Creating UML State machine Diagram showing all states of an automated booth - uml

I have never created/understood completely how to create a state machine diagram based on detailed description so I wanted to start somewhere. The automated booth is for student to return books automatically.
Description:
To return a book, it must be placed on a small conveyor belt and then the user needs to press the check-in button on the touch screen.
The chip reader in the machine then detects which book is being returned.
If no book is detected, the conveyor belt returns the item to the user. If a book is detected, the screen displays all the loan information on the screen and the user can confirm the return or cancel it.
If cancelled, the book is returned to the user. If confirmed, the book is taken into the library and the booth prints a physical receipt for the user. Additionally, the machine has a maintenance mode; no books can be returned until the maintenance is completed.
The Diagram:
I am not sure if I am describing all the states that the machine has or if I am fundamentally missing the guide lines of state machine diagram rules. I would appreciate any feedback as I am still learning.

In most cases, a state is a situation in which nothing happens and the machine is waiting for an external event to happen. The event may then be a reason to go to another state. Along the transition arrow, you write event [ condition ] / action. In your case, event is something the user does and action is something the machine does in response to the event.
States in which the machine is waiting are in your case: "Idle", "Loan information displayed" and "Maintenance". Although "Out of service" and "Self test" seem logical states, the description does not mention them, so I would not include them.
In some cases, you may wish to use a state to reflect the situation that the machine is busy doing something. The event may then be the completion of the work or an external interruption. In your case, Scan for book may be such a state, but you could also regard scanning as an action, for example user presses button / scan for book.
Both options are valid, but let's choose for Scan for book as a state (although I think "Busy scanning" would be a more state-like name).
From the description, I assume the machine goes from Idle to Scan for book when the user presses the button. So instead of Request book [check-in button pressed], I would write user presses check-in button.
State Scan for book is left when the machine has finished scanning. Along the arrow towards the decision diamond, you could write finished scanning. If it is a valid book, the machine will show the loan information and enter the state Loan information displayed. This transition is [valid book] / display loan information. Alternatively, you could write display loan information as an entry action inside the Loan information displayed state.
If the item is not valid, the machine returns the item. The transition is [else] / return item and this transition goes from the diamond to the Idle state.
In the same way, you can model transitions between Idle and Maintenance and between Idle and Loan information displayed.

Related

What notation marks that an activity must be completed within two-day time in an activity diagram?

Customers can pay for an order instantly or later. When the order is pay-later, I want to draw a notation that signifies that the customer must pay within two-day time in an activity diagram. If the customer does not pay within two-day time, the system will mark the order as canceled.
In this attached image, the first swimlane is for the actor Customer, and the second swimlane is for the actor System. I created a time event notation that signifies that the customer must pay within 48 hours. Then, I placed the merge/branch node on the customer swimlane to signify that the customer is the actor that must make the payment.
The issue that I thought of about my current diagram is that someone might misunderstand the time event notation. Someone might understand the notation as a sign that the system will always wait 48 hours before marking the order as canceled or awaiting shipment. In reality, the system will mark the order as awaiting shipment as soon as the customer pays. However, if the customer doesn't pay after 48 hours, the system will mark the order as canceled.
How can I draw a better diagram to signify the above description?
An accept time event action (e.g. an AcceptEventAction with a single TimeEvent trigger) cannot have an input flow, so your diagram is invalid, and then does not show what you want.
The guards of the flow after a Decision must be written between brackets ([]).
I placed the merge/branch node on the customer swimlane to signify that the customer is the actor that must make the payment.
but this is check by the system independently of the customer, so this is wrong / unclear
The fact the two actions creating order are not in the customer swimlane is also wrong / unclear for me
After the action create an order with the awaiting payment status you can create a new timer dedicated to the current order of the customer. In case a customer pays before 2 days the corresponding timer is deleted.
But that can produce a lot of timers, you can also memorize the current order more timeout in a fifo and you have a unique timer. In case a customer pays before 2 days the corresponding order is removed from the fifo.
That unique timer can periodically check the memorized orders, but that pooling wake-up the system even when nothing must be done.
That unique timer can be started when a first order is memorized, then when the system wake-up it manages the too older orders, then if the fifo become empty the timer is stopped else it is updated depending on the delay of the first (older) order in the fifo
Per #qwerty_so's comment, I have decided to use an interruptible region. This interruption trigger of this region is the system accepting payment. Here's the new diagram.
EDIT
As per #bruno's comments and #Axel Scheithauer's comments, I have cropped the more complete image of my activity diagram. An Accept Time Event Action seems to be able to have incoming edges/flows, contrary to #bruno's comments. Furthermore, I believe that the incomplete screenshot was what caused confusion in my diagram.
I also revised my diagram so that the interruptible region's signal comes from the Accept Time Event Action instead of Accept Event Action.
Diagram 1:
Diagram 2:

Activity Diagram Timed Event

I'm trying to model the following: When filling out a submission form, the system automatically saves the users progress every 5 minutes.
This is what I tried, but I don't think it's correct.
In my case the condition is asked only after the "fill submission" activity is finished. Also I don't want to indicate, that the user is starting the "fill submission" activity again.
You would use an interruptible region represented by a dashed line box:
The timer interrupt appears independently and intrerrupts the current action. Auto save is executed and comes back with Fill form. Resuming Fill form need a bit of thought since usually you have some entry code which must not be executed in case of a continuation. That might be a bit more tricky as you would likely need a mutex for that.
UML 2.5 has a detailed description in chap. 15.6.3.2 Interruptible Activity Regions on pp. 405.
Just a word about your approach. The save is only executed when the form is closed. So if it takes longer than 5 minutes you end up in your form again which is likely not desired :-)

Loading events from inside event handlers?

We have an event sourced system using GetEventStore where the command-side and denormalisers are running in two separate processes.
I have an event handler which sends emails as the result of a user saving an application (an ApplicationSaved event), and I need to change this so that the email is sent only once for a given application.
I can see a few ways of doing this but I'm not really sure which is the right way to proceed.
1) I could look in the read store to see if theres a matching application however there's no guarantee that the data will be there when my email handler is processing the event.
2) I could attach something to my ApplicationSaved event, maybe Revision which gets incremented on each subsequent save. I then only send the email if Revision is 1.
3) In my event handler I could load in the events from my event store for the matching customer using a repository, and kind of build up an aggregate separate from the one in my domain. It could contain a list of applications with which I can use to make my decision.
My thoughts:
1) This seems a no-go as the data may or may not be in the read store
2) If the data can be derived from a stream of events then it doesn't need to be on the event itself.
3) I'm leaning towards this, but there's meant to be a clear separation between read and write sides which this feels like it violates. Is this permitted?
I can see a few ways of doing this but I'm not really sure which is the right way to proceed.
There's no perfect answer - in most cases, externally observable side effects are independent of your book of record; you're always likely to have some failure mode where an email is sent but the system doesn't know, or where the system records that an email was sent but there was actually a failure.
For a pretty good answer: you're normally going to start with a facility that sends and email and reports as an event that the email was sent successfully, or not. That's fundamentally an event stream - your model doesn't get to veto whether or not the email was sent.
With that piece in place, you effectively have a query to run, which asks "what emails do I need to send now?" You fold the ApplicationSaved events with the EmailSent events, compute from that what new work needs to be done.
Rinat Abdullin, writing Evolving Business Processes a la Lokad, suggested using a human operator to drive the process. Imagine building a screen, that shows what emails need to be sent, and then having buttons where the human says to actually do "it", and the work of sending an email happens when the human clicks the button.
What the human is looking at is a view, or projection, which is to say a read model of the state of the system computed from the recorded events. The button click sends a message to the "write model" (the button clicked event tells the system to try to send the email and write down the outcome).
When all of the information you need to act is included in the representation of the event you are reacting to, it is normal to think in terms of "pushing" data to the subscribers. But when the subscriber needs information about prior state, a "pull" based approach is often easier to reason about. The delivered event signals the project to wake up (reducing latency).
Greg Young covers push vs pull in some detail in his Polyglot Data talk.

Occasionally connected CQRS system

Problem:
Two employees (A & B) go off-line at the same time while editing customer #123, say version #20, and while off-line continue making changes...
Scenarios:
1 - The two employees edit customer #123 and make changes to one or more identical attributes.
2 - The two employees edit customer #123 but DO NOT make the same changes (they cross each other without touching).
... they then both come back on-line, first employee A appends, thereby changing the customer to version #21, then employee B, still on version #20
Questions:
Who's changes do we keep in scenario 1?
Can we do a merge in scenario 2, how?
Context:
1 - CQRS + Event Sourcing style system
2 - Use Event Sourcing Db as a Queue
3 - Eventual Consistency on Read Model
4 - RESTful APIs
EDIT-1: Clarifications based on the answers so far:
In order to perform fined grained merging, I'll need to have one command for each of field in a form for example?
Above, finely grained commands for ChangeName, ChangeSupplier, ChangeDescription, etc., each with their own timestamp would allow for auto-merging in the event A & B both updated ChangedName?
Edit-2: Follow up based on the the use of a particular event store:
It seems as though I'll make use of #GetEventStore for the persistence of my event streams.
They make use of Optimistic Concurrency as follows:
Each event in a stream increments stream version by 1
Writes can specify an expected version, making use of the ES-ExpectedVersion header on writers
-1 specifies stream should not already exist
0 and above specifies a stream version
Writes will fail if the stream is not at the version, you either retry with a new expected version number or you reprocessed the behavior and decided it's OK if you so choose.
If no ES-Expected Version specified, optimistic concurrency control is disabled
In this context, the Optimistic Concurrency is not only based on the Message ID, but also on the Event #
If I understand your design picture correctly, then the occasionally connected users enqueue commands, i.e., change requests, and when the user reconnects the queued commands are sent together; there is only one database authority (that the command handlers query to load the most recent versions of their aggretates); only the view model is synced to the clients.
In this setup, Scenario 2 is trivially auto-merged by your design, if you choose your commands wisely, read: make them fine-grained: For every possible change, choose one command. Then, on re-connection of the client, the commands are processed in any order, but since they only affect disjunct fields, there is no problem:
Customer is at v20.
A is offline, edits changes against stale model of v20.
B is offline, edits changes against stale model of v20.
A comes online, batch sends an queued ChangeName command, the Customer of v20 is loaded and persisted as v21.
B comes online, batch sends an queued ChangeAddress command, the Customer of v21 is loaded and persisted as v22.
The database contains the user with their correct name and address, as expected.
In Scenario 1, with this setup, both employees will overwrite the other employees' changes:
Customer is at v20.
A is offline, edits changes against stale model of v20.
B is offline, edits changes against stale model of v20.
A comes online, batch sends an queued ChangeName command to "John Doe", the Customer of v20 is loaded and persisted as v21 with name "John Doe"
B comes online, batch sends an queued ChangeName command to "Joan d'Arc", the Customer of v21 (named "John Doe") is loaded and persisted as v22 (with name "Joan d'Arc').
Database contains a user with name "Joan d'Arc".
If B comes online before A, then it's vice versa:
Customer is at v20.
A is offline, edits changes against stale model of v20.
B is offline, edits changes against stale model of v20.
B comes online, batch sends an queued ChangeName command to "Joan d'Arc", the Customer of v20 is loaded and persisted as v21 (with name "Joan d'Arc').
A comes online, batch sends an queued ChangeName command to "John Doe", the Customer of v21 is loaded and persisted as v22 with name "John Doe".
Database contains a user with name "John Doe".
There are two ways to enable conflict detection:
Check whether the command's creation date (i.e., the time of the employees modification) is after the last modification date of the Customer. This will disable the auto-merge feature of Scenario 2, but will give you full conflict detection against concurrent edits.
Check whether the command's creation date (i.e., the time of the employees modification) is after the last modification date of the individual field of the Customer it is going to change. This will leave the auto-merge of Scenario 2 intact, but will give you auto-conflict-detection in Scenario 1.
Both are easy to implement with event sourcing (since the timestamps of the individual events in the event stream are probably known).
As for your question "Who's changes do we keep in scenario 1?" -- this depends on your business domain and its requirements.
EDIT-1: To answer on the clarification question:
Yes, you'll need one command for each field (or group of fields, respectively) that can be changed individually.
Regarding your mockup: What you are showing is a typical "CRUD" UI, i.e., multiple form fields and, e.g., one "Save" button. CQRS is usually and naturally combined with a "task based" UI, where there would be, say, the Status field be displayed (read-only), and if a user wants to change the status, one clicks, say, a "Change Status" button, which opens a dialog/new window or other UI element, where one can change the status (in web based systems, in-place-editing is also common). If you are doing a "task based" UI, where each task only affects a small subset of all fields, then finely grained commands for ChangeName, ChangeSupplier etc are a natural fit.
Here's a generic overview of some solutions:
Scenario 1
Someone has to decide, preferably a human. You should ask the user or show that there is a conflict.
Dropbox solves this by picking the later file and keeping a file.conflict file in the same directory for the user to delete or use.
Scenario 2
Keep the original data around and see which fields actually changed. Then you can apply employee 1's changes and then employee 2's changes without stepping on any toes.
Scenario 3 (Only when the changes come online at different times)
Let the second user know that there were changes while they were offline. Attempt Scenario 2 and show the second user the new result (because this might change his inputs). Then ask him if he wants to save his changes, modify them first, or throw them out.
Aaron, where the events do actually conflict, i.e. in scenario 1 then I would expect a concurrency exception of some sort to be thrown.
The second scenario is much more interesting. Assuming your commands and events are reasonably well defined, i.e. not a wrapper for CRUD then you would be able to test if the events committed since your command was issued actually conflict. I use a concurrency conflict registry for this purpose. Essentially when I detect a potential conflict I grab the events that have been committed since the version I currently have and ask the registry to check if any of them actually conflict.
If you want to see a code example and and a bit more detail on this I put together a post outlining my approach. Take a look at it here: handling concurrency issues in cqrs es systems
Hope this helps!
In this case, maybe you can use the "aggregate root" concept, for the Item which powered by CEP Engine (Complex Event Process Engine) to perform these complex operations.

state machine for a cd writer

As a newbie am trying to develop a state machine using Visio for a cd writer. below are the device operations/transactions and attached, is a diagram of what I've done so far, am unsure if its accurately represented.
Device operation
Load button- causes the drawer to open and to shut if open(load an empty cdr)
Burn button- starts recording document on the cdr, green light comes on in the burning process
and goes off when completed. Once cdr is burned writer stops.
Verify button- verifies the document previously recorded on the cdr, green light comes on in the
process and goes off when completed, then device stops
Cancel button- stops process anytime during recording or verifying
Cancel button- no effect if cd writer is empty or not busy verifying or recording When powered up- CD Writer will ensure the drawer is closed
Burn button – has no effect when cd writer is empty and during recording or verifying process.
Verifying can only be started when the CD Writer is not busy recording.
Visually your diagram looks like a state machine and states have good-sounding names - it's a good start. :)
The first issue I see there is the transition specification. It is definitelly not correct. State transitions in UML are specify in the folowing format:
event [guard] /action
where:
event (or trigger) is an external on internal "signal" that starts the transition. It can be a button activated by a user, an elapsed timer, a detected error, etc. It can even be omitted.
guard is a logical condition that should be fulfilled in order to start the transition. It is usually an expression returning a boolean value of tru or false. It can also be omitted.
action is a kind of side-effect, something that is executed when the transition is triggered. Ic can also be omitted.
Getting back to your diagram I would say that...
most of the labels on your transitions should not carrry "/" as it indicates an action. There are mostly manual triggers, like "load" (pressing the button to open the drawer), "Cancel", "butn", etc.
Consider some events that are triggered internally, like "burning done", or "CD loaded"
You can add some guard conditions in the situations where possible
I would remove all the triggers with no effect (like cancel with no CD in). It makes the diagram simplier with no loss of information
States LOADED and IDLE in your case are kind of strange, weak. It is not clear what makes them different (see the example below)
Here is a diagram that I find a bit more acurate (see notes for additional comments):
You need to specify explicit events as triggers of the transitions.
In the current state machine, each transition (except the one leaving the initial vertex) has an effect, but not a trigger. More accurately, they are triggered by the default completion event, and are therefore automatic.
Moreover, since all transitions react to the same event, your state machine is non-deterministic. For instance, in the state loaded, the transitions to Recording, empty, and loaded all react to the completion event. When the completion event is dispatched, these transitions are said to be conflicting, and one of them is selected non-deterministically. I am sure this is no what you want.
Read the UML Specification, and define triggers for your transitions.
You don't need to depict the transitions from "empty" to "empty" as transitions without any actions or state transitions would not need to be drawn in the Statemachine diagrams. (State Transition tables are often used for the checks of any missing transitions for such cases.)
"loaded" and "Idle" can be represented in one as a same state
To represent the "green light", I would write "turn on the green light" as entry action in Recording and "turn off the green light" as exit
Here's the diagram I drew. The status of tray (whether its opened or closed) should be considered in the actual model, but its not on my sample diagram below.

Resources