Running Background Jobs on the Server
A recurring pattern when building multi-user software systems is the need to execute periodic actions. With MDrivenServer, you can execute recurring actions or periodic actions.
A Periodic action is defined by a selection expression that selects what objects to act on. For each object selected for a periodic action, we want to do the “action” and that probably needs a cluster of objects to do different stuff to evolve some object state. To enable efficient load for such an object cluster, you must define and associate a ViewModel with each periodic action.
- The periodic action logic will load the ViewModel for your object and loop through all actions it finds in its root ViewModel class. When all actions are executed, the periodic action logic will save any changed state that was the result of your actions.
- Periodic actions can be used to “automatically” step your information from one state to the next – given that the circumstances are correct.
This ability may take some getting used to, but it can be used for things like assigning a unique number to an order or an article in your domain model – or for actions that need to be done serverside for some particular reason.
Define the periodic actions in the ViewModelEditor:
With this technique, you can change any state of the objects in your database efficiently with very little code.
A common case is the need to assign a unique number. I will demonstrate this. The client alone cannot be used to guarantee that the next number in a sequence is taken, since there may be multiple users trying to do this at the same time. You need to ensure you serialize all user requests for a new number. This is commonly done with a database lock. There is, however, a nice alternative to a harsh DB-locking technique and that is to serialize via a server-side action.
Consider having this State machine:
The ViewModel associated with the periodic action on the server can now assign your number.
The client will set the AssignNumber state. The Server side action will look for
Order.allinstances- >select(o|o.State=’AssignNumber’)
When objects are found, they will be assigned a new number by the actions in the ServerSide ViewModel and saved.
Combined with a periodic client action that calls selfVM.Refresh, we will see the client as soon as the state is changed to NumberAssigned.
Since we do not want the client to poll selfVM.Refresh all the time, we set the EnableExpression in this action to self.State=’AssignNumber’.
Following this pattern, we get the user to push a button to get a new number and we can show some info about working. The client starts refreshing, the server does its job – the client gets the new info by its refresh – the info about progress can be hidden as a consequence. This way, we have serialized an action in our system with model-driven techniques that will scale well and work for any number of users of your system.
New Recommendation on Number Assignment Pattern
Do as shown above but mark the state attribute and the number attribute with tagged value Realtime. This removes the need for periodic action with Refresh on the client.
Combine this with triggering via SysAsyncTicket and lower/remove the frequency of the ServerSide-job execution.
Other Uses of Server-side Actions
We have also implemented several additional common actions you can have the MDrivenServer perform for you.
Emailing from the Server
This topic is described here: Emailing from an app using MDrivenServer
Importing Data From Other SQL Sources
This topic is described here: Import_data_from_other_SQL_servers
Exporting Files From MDriven Server
This topic is described here: More about exporting
Catching Errors and Debug Info For Server-side Actions
Debugging serverside is covered here: Debugging MDrivenServer Serverside actions
Environment Specific Execution
Read on Server-wide variables here: Server_Wide_Variables
The MDriven Book - Next Chapter: SQLExport from MDriven Server