Business command objects, or “BizCommands”, are at the core of our architecture.
There are several applications, or “AppCenters”, and one business core, or “BizMaster”.
States
- Each application may have its own data storage.
- The real data is the data managed at the business level.
- The application data may be seen as a view of the business state.
- States (that is, data storages) can be seen as caches.
Commands
- Each business command is a transition from a business state “n” to another state “n+1”.
- Ideally, the business data could be reconstructed from a savepoint, by performing all business commands again.
- Business commands hold the real information.
Default Architecture
The applications post business commands, and the business core is responsible for handling them. Then the business core calls the application level back, which, notified of a business change, performs the corresponding changes in the application data. This may be seen as caching.
This can be done synchronously or asynchronously. The default mode is asynchronous.
The default architecture follows the following pattern:
The two data models “app data1” and “app data2” may be completely different.
The “b_converter” parts make sure the BizMaster doesn’t access the application data directly.
The main idea is that it’s the BizMaster that answers business commands sent by the AppCenters, and not the AppCenters that call the BizMaster synchronously.
Let’s look in detail at the communication mechanism between an AppCenter and the BizMaster:
We can see that:
- The AppCenter never connects to the BizMaster.
- Note: This can be nice even from a security perspective.
- The BizMaster connects to the AppCenter:
- Via a queue subscription, to get notified when a new business command is posted.
- Synchronously, to manage remote commands.
- Synchronously, to inject changes into the app data.
Generally, business commands are also stored within the “business data” resource on the BizMaster’s side (generally a database), but semantically, business commands and business data may be separated.
Workers are not event-driven: They are really asynchronous. Think of an infinite loop performing business tasks. Using a queue for notifications is a default implementation.
On the contrary, the business converter (“b_converter”) and the command manager (“cmd_mgr”) are event-driven.
Benefits
- All business command is logged, even when it didn’t succeed: Very easy to audit the app from a business perspective.
- Data migrations and app migrations can be run smoothly. If a delta exists between business states before and after a migration, it means that some new business commands have been performed in the old system prior to switching to the new one: This can be resorbed by running those same business commands on the new system (this should be idempotent with respect to the corresponding app data, though).
- Data replication (even at the business level) is non-blocking.
Following are a list of migration scenarios, taking benefits of the loose coupling between the AppCenter and the BizMaster.
- Migration Scenario #1: webapp
- Migration Scenario #2: b_converter
- Migration Scenario #3: webapp + app data + b_converter
- Migration Scenario #4: business workers
- Migration Scenario #5: b_converter + business workers
- Migration Scenario #6: business data + business workers
Migration Scenario #1: webapp
We switch from a v0 app to a v1 app, but no changes are required in the app data.
Deploy the new app:
Link the new app to the existing resources:
Switch the entry point (namely, update the nginx configuration and restart nginx):
Get rid of the old app:
Migration Scenario #2: b_converter
We switch from a v0 converter to a v1 converter, but no changes are required in the app data or in the web app.
Deploy the new converter:
Link the new converter to the existing resources:
Stop the existing workers. Incoming business commands will be held in the queue. Restart the workers, having them point to the new converter:
Get rid of the old converter:
Migration Scenario #3: webapp + app data + b_converter
Here we have a data migration.
The old data can take a while to copy and translate into the new schema, so it’s likely the system will receive some new business commands from the moment the copy starts and the moment it ends.
Say we start the copy+translation while the v0 app data is in state “1205001”. We capture the current pending business commands.
When we finish the copy+translation, we have a v1 app data in state “1205001”, and a v0 app data in state “1205489”.
The delta results from the business commands that have been performed (and added to app data v0) during the copy.
At this point, we can fill the delta with some ad hoc batch programs:
Once the batch programs are done reaching the “1205489” state in our v1 data, some more new business commands have been added to our v0 data state, which is now “1205506”.
We shutdown the workers, so the v0 data will not be updated any more, and keep running the batch programs.
See that the web app is still running as v0, recording business commands and holding them in the queue, but no business command is actually performed.
From a user perspective, we can also freeze the web app (message: “Sorry, we are in maintenance mode!”)
Once the “1205506” state has been reached for our v1 data, we can shutdown the batch programs, restart the workers and have them point to the new v1 converter. It is safe to switch the app to v1.
We get rid of old components.
Migration Scenario #4: business workers
Deploy the new workers:
Make them point to the local resources, but not yet subscribe to the queue and/or call the remote b_converter:
Stop the old workers. At this point, no business command is being performed at all.
Make the new workers point to the remote b_converter and subscribe to the queue:
Migration Scenario #5: b_converter + business workers
Deploy the new components:
Link them to the resources:
Stop the old workers:
Start the new workers and have them point to the new converter:
Migration Scenario #6: business data + business workers
Just as in Scenario #3, we have a data migration.
Say we start the copy+translation while the v0 business data is in state “9315001”. We capture the current pending business commands.
When we finish the copy+translation, we have a v1 business data in state “9315001”, and a v0 business data in state “9315489”.
The delta results from the business commands that have been performed during the copy.
At this point, we can fill the delta with some ad hoc batch programs:
Once the batch programs are done reaching the “9315489” state in our v1 data, some more new business commands have been added to our v0 data state, which is now “9315506”.
We shutdown the old workers, so the v0 data will not be updated any more, and keep running the batch programs.
See that the web app is still recording business commands and holding them in the queue, but no business command is actually performed.
From a user perspective, we can also freeze the web app (message: “Sorry, we are in maintenance mode!”)
Once the “9315506” state has been reached for our v1 data, we can shutdown the batch programs, and start the new workers.
We get rid of old components.
Aucun commentaire:
Enregistrer un commentaire