22 juillet 2015

BizCommands

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:

Default Architecture

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:

Details

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:
    1. Via a queue subscription, to get notified when a new business command is posted.
    2. Synchronously, to manage remote commands.
    3. 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:

MigrationScenario1_1

Link the new app to the existing resources:

MigrationScenario1_2

Switch the entry point (namely, update the nginx configuration and restart nginx):

MigrationScenario1_3

Get rid of the old app:

MigrationScenario1_4

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:

MigrationScenario2_1

Link the new converter to the existing resources:

MigrationScenario2_2

Stop the existing workers. Incoming business commands will be held in the queue. Restart the workers, having them point to the new converter:

MigrationScenario2_3

Get rid of the old converter:

MigrationScenario2_4

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.

MigrationScenario3_1

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.

MigrationScenario3_2

At this point, we can fill the delta with some ad hoc batch programs:

MigrationScenario3_3

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!”)

MigrationScenario3_4

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.

MigrationScenario3_5

We get rid of old components.

Migration Scenario #4: business workers

Deploy the new workers:

MigrationScenario4_1

Make them point to the local resources, but not yet subscribe to the queue and/or call the remote b_converter:

MigrationScenario4_2

Stop the old workers. At this point, no business command is being performed at all.

MigrationScenario4_3

Make the new workers point to the remote b_converter and subscribe to the queue:

MigrationScenario4_4

Migration Scenario #5: b_converter + business workers

Deploy the new components:

MigrationScenario5_1

Link them to the resources:

MigrationScenario5_2

Stop the old workers:

MigrationScenario5_3

Start the new workers and have them point to the new converter:

MigrationScenario5_4

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.

MigrationScenario6_1

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.

MigrationScenario6_2

At this point, we can fill the delta with some ad hoc batch programs:

MigrationScenario6_3

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!”)

MigrationScenario6_4

Once the “9315506” state has been reached for our v1 data, we can shutdown the batch programs, and start the new workers.

MigrationScenario6_5

We get rid of old components.