How to use a state chart as the flow chart for an agent - agent

I have two processes I want to juxtapose. The first is a Manual workflow that is well represented by the Process library. The second is a software System that performs the same work, but is better modelled as a state transition system (e.g. s/w component level).
Now in AnyLogic, state models are for agents, that can run through processes with animations (counts), or move across space. What if I want to use a state chart to run an agent through? so I have a System state chart/agent and a Job state chart/agent?
I want Jobs from Population A to go through the Manual process flow chart and Jobs from Population B to go through the System state flow chart, so I can juxtapose the processing costs. I then calculate various delays and resource allocations for each of the Jobs going through and compare them.
Can anyone explain how to setup a state chart as the base process, another agent will go through? Is this even possible?
Please help
Thanks

This will not work as you would like it to, for these reasons:
You can't send an Agent into a flowchart. (Not sure how AnyLogic is handling it internally, maybe a generic token, or no flow at all, just changes to the state).
In AnyLogic there can only be one state active (simple or combined state) per state chart, so you can't represent a population with several members.
Agents can't be in more then one flow at a time, so even if it would be possible to insert an Agent into a statechart, this limitation would also apply.
The conclusion of this is: State charts are suitable for modeling individual behaviour (inside one Agent), whereas process flows can be both used for individual behaviour (inside one Agent, running a dummy Agent through) as well as for groups (multiple Agents running through process).
The normal use case would be to add the state chart to the Agent type running through your process flow (as you already noted in your question), applying the changes caused by the state chart to the individual agent.

Related

Multi-Aggregate Transaction in EventSourcing

I'm new to event sourcing, but for our current project I consider it as a very promising option, mostly because of the audit trail.
One thing I'm not 100% happy with is the lack of aggregate-spanning transcations. Please consider the following problem:
I have an order which is processed at various machines at different stations. And we have containers where workers put the order in and carry it from machine to machine.
The tracking must be done through containers (which have a unique barcode-id), the order itself is not identifiable. The problem is: the containers are reused and need to be locked, so no worker can put two orders in the same container at the same time (for simplicity just assume they can't see if there is already an order inside the container).
For clarity, a high level view:
Order A created
Order A put on Container 1
Container 1 moves to Machine A and gets scanned
Machine A generates some events for Order A
Move Order A from Container 1 to Container 2
Order B created
Order B put on Container 1
...
"Move Order A from Container 1 to Container 2" is what I'm struggling with.
This is what should happen in a transaction (which do not exist):
Container 2: LockAquiredEvent
Order A: PositionChangedEvent
Container 1: LockReleasedEvent
If the app crashes after position 1 or position 2, we have containers that are locked and can't be reused.
I have multiple possible solutions in mind, but I'm not sure if there is a more elegant one:
Assume that it won't fail more than once a week and provide a way the workers can manually fix it.
See the container tracking as a different domain and don't use event sourcing in that domain.
Implement a saga with compensation actions and stuff.
Is there anything else I can do?
I think the saga-thing is the way to go, but we will have a rest api where we get a command transfer order A from container 1 to 2 and this would mean that the API command handler would need to listen to the event stream and wait for some saga generated event to deliver a 200 to the requester. I don't think this is good design, is it?
Not using event sourcing for the tracking is also not perfect because the containers might have an influence on the quality for the order, so the order must track the used containers, too.
Thank you for any hints.
The consistency between aggregates is eventual, meaning it could easily be that AR1 changed its state, Ar2 failed to change its state, and now you should revert the state of AR1 back to bring system into a consistent state.
1) If such scenarios are happening very often and recovery is really painful, rething your AR boundaries.
2) Recover manually. Don't use saga's, they should not be used for such purpose. If your saga wants to compensate AR1 but other transaction already changed its state to another one compensation would fail.

what the UML way to describe a master/slave state machine interaction

My system has two state machines, one master, one slave. And the states between the master and the slave are not one to one. The possible interactions are as follows.
If the master transits to certain master state, it will notify the slave to transit to certain slave state
The slave may request the master to enter certain master state; if master succeeds, the master will notify the slave to enter certain slave state.
The slave may request certain data from master
What is the proper UML diagram to describe those interactions? Statechart diagram is limited to state transition only and can't describe the request from the slave(either state transition or data); Interaction diagram is limited to class/object and can't applied on state.
You can describe those interactions using two UML state machine diagrams, one for the master and one for the slave. For example, to specify that a transition from state Idle to state Busy of the slave takes place upon receipt of signal Req from master, you draw a transition from Idle to Busy with transition label Req in the slave's state machine diagram. To specify that master sends signal Req when it enters state X, you write entry/Req inside the state symbol of X in the master's state machine diagram.
Alternatively, you may draw elements for sending and receiving signals (see sections 14.2.4.8.2 to 14.2.4.8.5 of UML 2.5.1 specification):
For example, to go from Idle to Busy upon receipt of signal Req with parameter id:
You also described the situation where the slave requests certain data from the master. For this, you need a third diagram (or a textual specification) of the interface provided by the master and required by the slave, for example:
In the slave's state machine diagram, you can call an operation defined in the interface. For example, to call the read operation of master when the slave enters state Busy and store it in local variable x, write entry/x:=master.read() inside the state symbol X.
For an introduction to the UML state machine diagram, please refer to wikipedia
What you describe is the interaction between the master and the slave.
There is no single solution to that and it is really difficult to have at the same picture both all possible states and the logic of the transaction (actually I don't think it is possible at all).
The main diagrams to be considered here would be:
Sequence diagram depicting the process of requesting/changing states (you may have few showing various triggers for the change and use alt/opt to show further behaviour)
Activity diagram depicting how the process of state changing is handled
Interaction overview diagram with state changes being shown at the "activity" level and negotiation between the master and the slave in the "sequence" parts.
Especially the last one is an interesting option here as it combines possibilities of activity and sequence diagrams. Usually it's an overkill but might be the best idea for your specific case.
In addition to those you may also use the state machine diagram (two, one for master and one for slave) but they will not be able to show the interaction between the two entities. It might be useful though to explain what are the available states.
If it is not clear feel free to comment this answer asking for more details. I will try building example of each of those diagrams then (activity diagram example you already have in the answer by www.admiraalit.nl).

Activity Diagram - confusion regarding fork/join and decision/merge in this scenario

I am creating an activity diagram
Admin log in to the web
If validated, it reaches the dashboard
Through dashboard it can manage account, manage product and manages issues
after performing one of above options, it can go back to dashboard or logout from system.
I have used fork/join, is it correct or I should be using decision/merge instead
2ndly, is the procedure of logging out or performing another option available in dashboard correctly defined?
Your activity is having several issues.
First and most severe, it will not do anything because actions (and mostly those - not all model elements in activities) having an "implicit and sematics" for incomming control flows. This means that an action is only executed when an token is offered on ALL incomming control flow actions, otherwise it waits. So as your control flow from validate can not offer an token before Login has been executed and finished, you are having a lock. And nothing is executed. The same applies to Dashboard. To solve this you need to model merge nodes.
The second point is that you only want to execute (according to your description) one of the manage actions. (Btw. names with generic verbs like "manage", "maintain", "do", "perform", etc. are quite bad names for actions, use more specific ones instead). Your model executes, irregardless of the selection in the dashboard action, all manage actions concurrently. Concurrently means in an arbitrary order and does not demand a parallel execution. Thus you should replace the fork with a decision node, where the conditions on the outgoing flows are based on the selection from the dashboard. An decision node can have an arbitrary (but finite) number of outgoing control flows. All the outgoing control flows from the manage actions are merged using a merge node instead of a join node. As the join node would wait for an incommingtoken per incomming control flow.
A minor point, that would be solved when using an UML/SysML tool is that the fork and join nodes are bars and not rectangular frames.
Your AD has 2 flaws. First a fork/join is a solid thick line, but not a hollow rectangle. Second, it's used wrongly. This way you run all Manage actions in parallel and continue when they are all finished. According to your description use a diamond to decide for one of the actions Also use the diamond afterwards to merge the flows and continue to Logout.

DDD - How to modify several AR (from different bounded contexts) throughout single request?

I would want expose a little scenario which is still at paper state, and which, regarding DDD principle seem a bit tedious to accomplish.
Let's say, I've an application for hosting accounts management. Basically, the application compose several bounded contexts such as Web accounts management, Ftp accounts management, Mail accounts management... each of them represented by their own AR (they can live standalone).
Now, let's imagine I want to provide a UI with an HTML form that compose one fieldset for each bounded context, for instance to update limits and or features. How should I process exactly to update all AR without breaking single transaction per request principle? Can I create a kind of "outer" AR, let's say a ClientHostingProperties AR which would holds references to other AR and update them as part of single transaction, using own repository? Or should I better create an AR that emit messages to let's listeners provided by the bounded contexts react on, in which case, I should probably think about ES?
Thanks.
How should I process exactly to update all AR without breaking single transaction per request principle?
You are probably looking for a process manager.
Basic sketch: persisting the details from the submitted form is a transaction unto itself (you are offered an opportunity to accrue business value; step 1 is to capture that opportunity).
That gives you a way to keep track of whether or not this task is "done": you compare the changes in the task to the state of the system, and fire off commands (to run in isolated transactions) to make changes.
Processes, in my mind, end up looking a lot like state machines. These tasks are commands are done, these commands are not done, these commands have failed: now what? and eventually reach a state where there are no additional changes to be made, and this instance of the process is "done".
Short answer: You don't.
An aggregate is a transactional boundary, which means that if you would update multiple aggregates in one "action", you'd have to use multiple transactions. The reason for an aggregate to be equivalent to one transaction is that this allows you to guarantee consistency.
This means that you have two options:
You can make your aggregate larger. Then you can actually guarantee consistency, but your ability to handle concurrent requests gets worse. So this is usually what you want to avoid.
You can live with the fact that it's two transactions, which means you are eventually consistent. If so, you usually use something such as a process manager or a flow to handle updating multiple aggregates. In its simplest form, a flow is nothing but a simple if this event happens, run that command rule. In its more complex form, it has its own state.
Hope this helps 😊

Managing dynamic conditional dependencies with generated state machines?

Greetings SO denizens!
I'm trying to architect an overhaul of an existing NodeJS application that has outgrown its original design. The solutions I'm working towards are well beyond my experience.
The system has ~50 unique async tasks defined as various finite state machines which it knows how to perform. Each task has a required set of parameters to begin execution which may be supplied by interactive prompts, a database or from the results of a previously completed async task.
I have a UI where the user may define a directed graph ("the flow"), specifying which tasks they want to run and the order they want to execute them in with additional properties associated with both the vertices and edges such as extra conditionals to evaluate before calling a child task(s). This information is stored in a third normal form PostgreSQL database as a "parent + child + property value" configuration which seems to work fairly well.
Because of the sheer number of permutations, conditionals and absurd number of possible points of failure I'm leaning towards expressing "the flow" as a state machine. I merely have just enough knowledge of graph theory and state machines to implement them but practically zero background.
I think what I'm trying to accomplish is at the flow run time after user input for the root services have been received, is somehow compile the database representation of the graph + properties into a state machine of some variety.
To further complicate the matter in the near future I would like to be able to "pause" a flow, save its state to memory, load it on another worker some time in the future and resume execution.
I think I'm close to a viable solution but if one of you kind souls would take mercy on a blind fool and point me in the right direction I'd be forever in your debt.
I solved similar problem few years ago as my bachelor and diploma thesis. I designed a Cascade, an executable structure which forms growing acyclic oriented graph. You can read about it in my paper "Self-generating Programs – Cascade of the Blocks".
The basic idea is, that each block has inputs and outputs. Initially some blocks are inserted into the cascade and inputs are connected to outputs of other blocks to form an acyclic graph. When a block is executed, it reads its inputs (cascade will pass values from connected outputs) and then the block sets its outputs. It can also insert additional blocks into the cascade and connect its inputs to outputs of already present blocks. This should be equal to your task starting another task and passing some parameters to it. Alternative to setting output to an value is forwarding a value from another output (in your case waiting for a result of some other task, so it is possible to launch helper sub-tasks).

Resources