MDrivenServer periodic server-side actions
No edit summary
 
(20 intermediate revisions by 5 users not shown)
Line 1: Line 1:
A re-occurring pattern when building multi user software systems is the need to execute periodic actions. With MDrivenServer you can use it to execute re-occurring actions, or periodic actions.
=== 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 and it needs 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.
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.
The periodic action logic will load the viewmodel for your object and loop through all actions that 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.
Periodic actions can be used to “automatically” step your information from one state to the next – given that the circumstances are correct.
 
This ability might 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:
Define the periodic actions in the ViewModelEditor:
Line 13: Line 11:
[[File:ServerSide Actions 01.png|frameless|246x246px]] ☛  [[File:ServerSide Actions 02.png|frameless|464x464px]]
[[File:ServerSide Actions 01.png|frameless|246x246px]] ☛  [[File:ServerSide Actions 02.png|frameless|464x464px]]


With this technique you can change any and all state of objects in your database in an efficient manner with very little code.
With this technique, you can change any state of the objects in your database efficiently with very little code.


As a common case is the need to assign a unique number I will show this. The client cannot alone 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. We need to make sure we 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.
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:
Consider having this State machine:


[[File:ServerSide Actions 03.png|frameless|388x388px]]
[[File:ServerSide Actions 03.png|frameless|388x388px]]


The ViewModel associated with the periodic action on the server can now assign my number.
The ViewModel associated with the periodic action on the server can now assign your number.


[[File:ServerSide Actions 04.png|frameless|550x550px]]
[[File:ServerSide Actions 04.png|frameless|550x550px]]
Line 27: Line 25:
The client will set the AssignNumber state. The Server side action will look for
The client will set the AssignNumber state. The Server side action will look for
  Order.allinstances- >select(o|o.State=’AssignNumber’)
  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 on the client as soon as state is changed to NumberAssigned.
When objects are found, they will be assigned a new number by the actions in the ServerSide ViewModel and saved.  
 
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 pushing a button to get a new number, 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 abut 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 of any number of users of your system.
 
=== Other uses of Server side Actions ===
 
==== Emailing from the server ====
We have also implemented several additional common actions that you can have the MDrivenServer perform for you.
 
If you have an action in your viewmodel named “email” then MDrivenServer will try to find the following properties in your viewmodel:
 
'''to''' : will be used as to email address. You can also send in multiple emails in a comma separated string to send to multiple. Use this syntax  PopularName<email> to get a common name to show instead of the email
 
'''<s>topresentation</s>:''' <s>the name of the owner of the email</s>  this is replaced by sending in PopularName<email> in the "to" column [[Send email with attachments|as described here]]
 
'''from:''' the sender email
 
'''frompresentation''': the name to use as sender
 
'''body:''' the message
 
'''subject''': the subject line
 
''The properties found will be used to send an email – you need to [[fill in the email settings in the admin UI]] for this to work''
 
Emailing from the server has been updated to allow for attachments as described here; [[send email with attachments]]
 
==== Importing data from other SQL sources ====
MDriven Server has functionality to import data from other sqlbased systems. The ability to read from an external SQL server and import that data – strictly by using MDriven techniques and zero need for external programs.
 
´Suppose I have this model and I really want class1 to be reference data from an external database:
 
[[File:ServerSide Actions Importing Data 01.png|frameless|257x257px]]
 
So I declare a viewModel that looks like this:
 
[[File:ServerSide Actions Importing Data 02.png|frameless|469x469px]]
 
It defines 4 columns with data and 2 actions:
 
1=<u>'''ViewModel'''</u> – the name of yet another viewmodel that will act as a importer of the sql result set
 
2='''<u>Connectionstring</u>'''- the external database
 
3=<u>'''Query'''</u> – the sql query – remember that you can build it with data from the rest of your model
 
4=<u>'''Key'''</u> – if we want the import to be able to update Class1 we need to explain what the key is in the class
 
And the actions:
 
'''SQLImport''' – using this name will trigger the import function in MDriven Server
 
Finished – this is a generic action – that just execute the expression – in this case setting Class2.Attribute1 to ‘Done’
 
So the SQL data returned looks like this:


[[File:ServerSide Actions Importing Data 03.png|frameless|323x323px]]
Combined with a periodic client action that calls selfVM.Refresh, we will see the client as soon as the state is changed to NumberAssigned.


And the ViewModel that is going to act as the import template – called “TheImporter” in the example above looks like this:
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’.


[[File:ServerSide Actions Importing Data 04.png|frameless]]
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.


I now declare the ServerSide job in MDriven server:
====== New Recommendation on Number Assignment Pattern ======
Do as shown above but mark the state attribute and the number attribute with tagged value [[SignalR and Realtime|Realtime]]. This removes the need for periodic action with Refresh on the client.


[[File:ServerSide Actions Importing Data 05.png|frameless|422x422px]]
Combine this with triggering via [[AsyncTicket|SysAsyncTicket]] and lower/remove the frequency of the ServerSide-job execution.


Now the MDriven Server will check every 20:seconds if the expression
=== Other Uses of Server-side Actions ===
Class2.allinstances- >select(attribute1=’todo’)
We have also implemented several additional common actions you can have the MDrivenServer perform for you.
returns any rows. If it does – it fetches at most 2 of these and executes all the actions found in TheServerSideJob.


In MDriven Designer I can create a Class2 with the debugger and save it:
==== Emailing from the Server ====
This topic is described here: [[Emailing from an app using MDrivenServer]]


[[File:ServerSide Actions Importing Data 06.png|frameless|324x324px]]
==== Importing Data From Other SQL Sources ====
This topic is described here: [[Training:Import data from other SQL servers|Import_data_from_other_SQL_servers]]


And then I check the MDriven Server log: [[File:ServerSide Actions Importing Data 07.png|frameless|493x493px]]
==== Exporting Files From MDriven Server ====
This topic is described here: [[Training:Exporting files from MDriven Server|More about exporting]]


I then check my Class2:                             [[File:ServerSide Actions Importing Data 08.png|frameless|448x448px]]
==== Catching Errors and Debug Info For Server-side Actions ====
Debugging serverside is covered here: [[Debugging MDrivenServer Serverside actions]]


Attribute1 is now ‘Done’ – so the serverside job relaxes and will not find anything more to do just now…
==== Environment Specific Execution ====
Read on Server-wide variables here: [[Server_Wide_Variables]]


[[Exporting files from MDriven Server|More about exporting]]
The MDriven Book - See: [[Training:SQLExport from MDriven Server|SQLExport from MDriven Server]]
[[Category:MDriven Server]]
[[Category:Advanced]]
[[Category:The MDriven Book]]

Latest revision as of 05:25, 3 April 2024

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:

ServerSide Actions 01.pngServerSide Actions 02.png

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:

ServerSide Actions 03.png

The ViewModel associated with the periodic action on the server can now assign your number.

ServerSide Actions 04.png

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 - See: SQLExport from MDriven Server

This page was edited 43 days ago on 04/03/2024. What links here