This section discusses the new APIs that have been added to support connection migration. For more information about using these new APIs, see “Instructing clients to migrate to a different server”.
The CS_REQ_MIGRATE request capability indicates if a client supports the migration protocol and if the client is capable of migrating to another server when requested. You can use srv_capability_info() to retrieve the CS_REQ_MIGRATE capability information. For example:
CS_RETCODE ret; CS_BOOL migratable; ret = srv_capability_info(sp, CS_GET, CS_CAP_REQUEST, CS_REQ_MIGRATE, &migratable);
SRV_CTL_MIGRATE has been added as a control type of the srv_send_ctlinfo() function. Using the SRV_CTL_MIGRATE control type, srv_send_ctlinfo() can now send a migration request to the client or cancel a previous migration request. SRV_CTL_MIGRATE can be used only if the client supports migration and has received a session ID when it first connected to the session.
Requesting a client migration
This sample code sends a request to the client to migrate to server “target”:
CS_RETCODE ret; SRV_CTLITEM *srvitems; CS_CHAR *target; /* ** request a migration to server 'target' */ srvitems = (SRV_CTLITEM *) srv_alloc(sizeof (SRV_CTLITEM)); srvitems[0].srv_ctlitemtype = SRV_CT_SERVERNAME; srvitems[0].srv_ctllength = strlen(target); srvitems[0].srv_ctlptr = target; ret = srv_send_ctlinfo(sp, SRV_CTL_MIGRATE, 1, srvitems); srv_free(srvitems);
Your application can still send the SRV_CTL_MIGRATE control type even if a migration has already been requested. Open Server cancels the earlier migration request and sends a new request to the client. The return values for a new migration request are:
Return value |
Description |
---|---|
CS_SUCCEED |
The migration request was sent successfully. |
CS_FAIL |
The migration request failed due to one of the following reasons:
|
Cancelling a migration
You can also use the SRV_CTL_MIGRATE control type to cancel a previous migration request. In this case, paramcnt must be 0 and param must be a NULL pointer. For example:
ret = srv_send_ctlinfo(sp, SRV_CTL_MIGRATE, 0, NULL); if (ret != CS_SUCCEED) { ... }
SRV_CTL_MIGRATE can be used by any thread in an Open Server application. However, a thread cancelling the migration of a client thread's connection has a different requirement than a client thread cancelling its own connection migration:
Any Open Server thread can cancel a migration, however, the cancellation must be requested before the SRV_MIGRATE_STATE event handler informs the client thread that the client is ready to migrate.
The client thread can cancel a migration even inside the SRV_MIGRATE_STATE event handler. However, the client cannot cancel a migration after it exits the SRV_MIGRATE_STATE event with a SRV_MIG_READY state.
The return values of a migration cancellation are:
Return value |
Description |
---|---|
CS_SUCCEED |
The migration request was cancelled successfully. |
CS_FAIL |
The migration cancellation failed due to one of these reasons:
|
Open Server does not trigger a new migrate state event
when a migration request is successfully cancelled.
When a client migrates to a new server while waiting for results, the new server invokes the SRV_MIGRATE_RESUME event after the client connection has successfully migrated. If the migration request failed or is cancelled, the event is invoked from the original server.
In the SRV_MIGRATE_RESUME event handler, your application does not have to send any actual result to the client, except for the SRV_DONE_FINAL result type that must always be sent. The only result that the default SRV_MIGRATE_RESUME sends to the client is SRV_DONE_FINAL.
This is an example of a SRV_MIGRATE_RESUME event handler:
/* ** Simple migrate_resume event handler. */ CS_RETCODE CS_PUBLIC migrate_resume_handler(SRV_PROC *sp) { CS_RETCODE ret; ret = srv_senddone(sp, SRV_DONE_FINAL, CS_TRAN_COMPLETED, 0); if (ret == CS_FAIL) { ... } return CS_SUCCEED; } ... /* ** Install the migrate-resume event handler */ srv_handle(server, SRV_MIGRATE_RESUME, migrate_resume_handler); ...
SRV_MIGRATE_STATE is an event that is triggered whenever the migration state has transitioned to SRV_MIG_READY or SRV_MIG_FAILED, the transition being a result of a migration message from a client. The SRV_MIGRATE_STATE event handler is invoked in these situations:
SRV_T_MIGRATE_ STATE |
Situation |
Possible application action |
---|---|---|
SRV_MIG_READY |
The client has sent a message to the server indicating that it has detected the request and is ready to migrate. The server determines whether to continue the migration or not. |
One of the following:
|
SRV_MIG_FAILED |
The client has sent a message to the server indicating that the migration failed. |
One of the following:
|
This is an example of a SRV_MIGRATE_STATE event handler:
/* ** Simple migrate-state event handler */ CS_RETCODE CS_PUBLIC migrate_state_handler(SRV_PROC *sp) { SRV_MIG_STATE migration_state; ret = srv_thread_props(sp, CS_GET, SRV_T_MIGRATE_STATE, &migration_state, sizeof (migration_state), NULL); ... switch(migration_state) { case SRV_MIG_READY: ... case SRV_MIG_FAILED: ... } } ... /* ** Install the migrate-state change event handler */ srv_handle(server, SRV_MIGRATE_STATE, migrate_state_handler); ...
When working with the SRV_MIGRATE_STATE event handler:
If the client thread cancels the migration from inside the SRV_MIGRATE_STATE event handler, your application must make sure that the context is consistent. For instance, you cannot expect a different server to use the context your application has created.
If a new migration request is sent from within the SRV_MIGRATE_STATE event handler, this handler is called again when the client is ready to start with the new requested migration.
SRV_T_MIGRATE_STATE indicates the migration state of the client. SRV_T_MIGRATE_STATE is a read-only property that any thread can access. The possible migration states are:
State |
Value |
Description |
---|---|---|
SRV_MIG_NONE |
0 |
There is no migration in progress. |
SRV_MIG_REQUESTED |
1 |
A migration has been requested by the server. |
SRV_MIG_READY |
2 |
The client has received the request and is ready to migrate. |
SRV_MIG_MIGRATING |
3 |
The client is now migrating to the specified server. |
SRV_MIG_CANCELLED |
4 |
The migration request has been cancelled. |
SRV_MIG_FAILED |
5 |
The client failed to migrate. |
SRV_MIG_STATE is an enumerated datatype that has been added to model the SRV_T_MIGRATE_STATE property. SRV_MIG_STATE is declared as:
typedef enum { SRV_MIG_NONE, SRV_MIG_REQUESTED, SRV_MIG_READY, SRV_MIG_MIGRATING, SRV_MIG_CANCELLED, SRV_MIG_FAILED } SRV_MIG_STATE;
This sample code shows how you can retrieve SRV_T_MIGRATE_STATE values; in case of a successful migration, the client exits and the SRV_DISCONNECT event handler is called with a SRV_MIG_MIGRATING status:
CS_RETCODE ret; SRV_MIG_STATE migration_state; ret = srv_thread_props(sp, CS_GET, SRV_T_MIGRATE_STATE, &migration_state, sizeof (migration_state), NULL); if (ret != CS_SUCCEED) { ... }
SRV_T_MIGRATED is a Boolean property that indicates whether a connection is a new connection or a migrated connection. This read-only property is set to true when the client is migrating or has migrated to the server. This sample code retrieves the value of SRV_T_MIGRATED:
CS_RETCODE ret; CS_BOOL migrated; status = srv_thread_props(sp, CS_GET, SRV_T_MIGRATED, &migrated, sizeof (migrated), NULL);