This document describes implementation issues and how to use persistence and units of work in EntireX Broker. It assumes you are familiar with EntireX Broker from both an administrative and an application perspective, and with the ACI programming in particular. See also EntireX Broker and EntireX Broker ACI Programming. This document covers the following topics:
A persistent store driver is an executable, or a load module that implements access to the physical persistent store. There is one persistent store driver for each persistent store type. The following table shows the persistent store options:
Persistent Store Type | Description | Operating System | Notes |
---|---|---|---|
Adabas | Uses Adabas database. | UNIX, Windows, z/OS, z/VSE | Adabas, Software AG's ADAptable dataBASe, is a high-performance, multithreaded, database management system. |
DIV | Uses IBM Data In Virtual facility on z/OS. | z/OS | This persistent store option is implemented as a VSAM linear data set. |
CTREE | c-tree© is an embedded local database that can be used as your persistent store. | UNIX and Windows | c-tree© is the fast and reliable embedded database of FairCom Corporation®. |
It is important to note that some level of both application and system changes are necessary to utilize UOWs. Existing message-based Broker applications will continue to operate as before.
The following table represents the keyword parameters that can be used in the Broker attribute file for UOWs. A short form of the keyword is given if applicable. Default values are underlined.
Keyword | Value | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
STORE |
OFF | BROKER |
Broker: sets default STORE
attribute for all units of work.
Service: sets default |
||||||||
MAX-UOWS or MUOW |
0 | n |
Broker: maximum number of active UOWs. If 0 is specified, then
the Broker will not support any UOW operations.
Service: maximum number of active UOWs for a service. |
||||||||
MAX-MESSAGES-IN-UOW or
UMSG
|
16 | n |
Broker: maximum number of messages in a UOW.
Service: maximum number of messages in a UOW for the service. |
||||||||
PSTORE |
NO | HOT | COLD | WARM |
Broker only. Startup value for persistent store.
|
||||||||
UWSTATP |
0 - 254 |
Broker: persistent status is maintained either for persistent or
non-persistent UOWs.
Service: persistent status is maintained either for persistent or non-persistent UOWs for a service. |
||||||||
UWTIME |
1D | nS | nM | nH |
nD |
Broker: defines the lifetime of a UOW in seconds, minutes, hours
or days. This value is the time that it can remain in the system without being
completed. If the UOW is not completed within this time, it is deleted with a
status of TIMEOUT
Service: defines the lifetime of a UOW for a service. |
||||||||
MAX-UOW-MESSAGE-LENGTH |
n | 31647
|
Broker: defines the default maximum message size that can be
sent.
Service: defines the maximum message size that can be sent to a service. |
||||||||
DEFERRED |
NO | YES |
Broker: sets the default DEFERRED
attribute for all services. UOWs can be sent to a deferred service even if the
service is not registered.
Service: sets the |
The following fields have been added to the broker ACI control block. Note that the actual field names may differ slightly depending on the programming language being used.
Keyword | Description | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
STORE |
Indicates whether the specified UOW is persistent
or not:
Also returned with |
||||||||||||||||||||||||||
UWTIME |
The amount of time that the UOW can remain incomplete without being timed out. This is also referred to as the UOW lifetime. | ||||||||||||||||||||||||||
STATUS |
The current status of a UOW. The status is returned on
SEND , RECEIVE , and
SYNCPOINT operations. Applicable values are as
follows:
* The status values marked with an asterisk are persistent, and will only exist for UOWs with persistent status. In addition, the following status values are returned on a
All |
||||||||||||||||||||||||||
USTATUS |
A user-defined status associated with a UOW. It can be specified
as part of a SEND ,
RECEIVE , or SYNCPOINT
operation and will be returned whenever the status of a UOW is queried. See
Using User Status below for more information.
|
||||||||||||||||||||||||||
UOWID |
A unique identifier for a unit of work. This value is returned
on SEND and RECEIVE
operations and may be provided on SYNCPOINT
operations that are querying status of UOWs.
|
||||||||||||||||||||||||||
UWSTATP |
A numeric value indicating the lifetime value for persistent
status. This value is a multiplier against the
UWTIME value. Applicable values are:
|
The SYNCPOINT
function deals exclusively with
UOWs. The following table lists the OPTION
values that can be used with the SYNCPOINT
function,
and the associated behavior and restrictions of each one.
Note:
In many cases, the behavior will be different depending on whether
the issuer is the sender or the receiver of the UOW.
Option | Caller | Behavior and Restrictions |
---|---|---|
BACKOUT |
Sender | If the specified UOW is in RECEIVED
status, it will be put into BACKEDOUT status. If
persistent status is not specified, no trace of the UOW will remain.
|
Receiver | If the specified UOW is in DELIVERED
status, it will be put back into ACCEPTED status and its
attempted delivery count will be incremented.
|
|
CANCEL |
Sender | If the specified UOW is in ACCEPTED
status, it will be put into CANCELLED status. If
persistent status is not specified, no trace of the UOW will remain.
|
Receiver | If the specified UOW is in DELIVERED
status, it will be put into CANCELLED status. If
persistent status is not specified, no trace of the UOW will remain.
|
|
COMMIT |
Sender | If the specified UOW is in RECEIVED
status, it will be put into ACCEPTED status. It is now
available to be received by the other partner.
|
Receiver | If the specified UOW is in DELIVERED
status, it will be put into PROCESSED status. If
persistent status is not specified, no trace of the UOW will remain.
|
|
Both | This is a special case of the
COMMIT option, where the caller specifies
UOWID=BOTH in the request. This allows the caller to commit two UOWs, one being
received and one being sent, in a single atomic operation.
|
|
DELETE |
Sender | Deletes the persistent status of the specified UOW. The UOW must be complete and must have been created by the caller. After this request, no trace of the UOW will remain. |
EOC |
Sender | Commits the UOW and sets an EOC indication on the associated
conversation. See COMMIT for additional
information and restrictions.
|
EOCCANCEL |
Sender | Commits the UOW and sets an
EOC-CANCEL indication on the associated
conversation. See COMMIT for additional
information and restrictions.
|
LAST |
Sender | Returns the status of the last UOW sent by the caller. In
addition,
CLASS /SERVER /SERVICE
details of the associated server are also returned. The
CONV-ID can be included to qualify the request.
|
QUERY |
Sender | With UOWID=n, returns the status of the specified UOW. In
addition,
CLASS /SERVER /SERVICE
details of the associated server are also returned.
|
SETUSTATUS |
Both | Updates the user status field of the specified UOW. The UOW must
be in RECEIVED , ACCEPTED , or
DELIVERED status.
|
This table lists option values used to support UOW operations:
Option | Function | Behavior and Restrictions |
---|---|---|
SYNC |
SEND |
This option indicates that the data being sent is part of a UOW. The UOW is created on the first send, and subsequent sends will add messages to the UOW. |
SYNC |
RECEIVE |
This option indicates that the
RECEIVE can be satisfied only with a message in a
UOW.
|
MSG |
RECEIVE |
This option indicates that the
RECEIVE can be satisfied only with non-UOW
messages.
|
ANY |
RECEIVE |
This option indicates that the
RECEIVE can be satisfied by either a non-UOW or a
UOW message. It is up to the receiver to determine which, based on the
UOWSTATUS field that is returned.
|
COMMIT |
SEND |
This option combines a SEND and a
SYNCPOINT ,
OPTION =COMMIT into a
single operation. It allows the sender to create and commit a UOW in a single
operation.
|
In order to support unique conversation identifiers at Broker restart, there is an implementation of the CID which is alphanumeric and an internal identifier.
Note:
The CID is a Broker-generated identifier for the conversation, and
the application should not make any assumptions about either the content or
format of all or any part of the CID field, or about any relationship between
CIDs.
If any of the following three conditions exist, the all-numeric implementation of the CID field will be used in order to ensure compatibility:
the Broker does not support any UOW processing;
the application program is using API_VERSION
1 or 2 in its
request;
or
the target service does not support UOWs.
Note:
This level of compatibility may be removed at some point in the
future.
A Broker conversation will support either UOWs or messages, but not both. At the time the conversation is created, the Broker will determine which is to be supported.
The order of delivery of new conversations to receivers is determined
by the COMMIT
time of the first UOW within its
conversation. The conversation delivered to the receiver first is the one
containing the first UOW for which the sender issues a
SEND
,OPTION
=COMMIT
or
SYNCPOINT
,OPTION
=COMMIT
.
If there is more than one UOW in a conversation, the
COMMIT
time of the first UOW determines the age of that
conversation. Also, multiple UOWs within a conversation are picked up by the
receiver, in the same sequence as they were committed by the sender.
Scenario: A server starts to receive UOWs
(CONVID
=NEW
) and receives UOW T1
first, since this UOW is committed first. If the server issues another receive
(CONVID
=NEW
), it receives UOW T3.
If, however, the UOWs are not combined in conversations (i.e., every UOW is in
a separate conversation), the server receives
(CONVID
=NEW
) UOW T1 first, then
UOW T2, UOW T3, etc.
The COMMITTIME
field in the Broker control block shows COMMITTIME
of
the first UOW in a conversation.
An explicit LOGON
function must be used
before a program can use any of the UOW functions. In order to enable client
and server programs to recover the status of their UOWs in the event of a
failure (Broker, system, or application), these programs must specify a
TOKEN
value at the time of logon.
EntireX Broker identifies participants by ACI fields
USER-ID
and TOKEN
if
TOKEN
is supplied or by USER-ID
and internal ID (so-called physical user ID) if TOKEN
is
not supplied. However, the implementation of persistent units of work is based
on the user identification USER-ID
and
TOKEN
.
Warning: In order to avoid unpredictable inconsistencies, all applications using persistent units of work must use this user identification to run correctly. The ACI verification routines do not restrict usage of UOWs to USER-ID and TOKEN yet.
Modify your application accordingly. |
Applications that should consider using UOWs fit into a couple of different categories.
Applications that currently use multiple messages to communicate a single request are good candidates for UOWs. Grouping these messages within a UOW can give the application additional control over how its data is processed.
Applications that intend to utilize deferred services, persistence, or persistent status must use UOWs, since these facilities are not available to message-based applications.
In order to use UOWs effectively, you need to understand
the meaning of the various UOW status values;
how they change based on events within the system;
and
how these changes are influenced by both persistence and persistent status.
The diagram below represents the normal status values as a UOW progresses through the system. These statuses and the transitions between them are not affected by either persistence or persistent status. The status values are indicated in ovals.
Normal Status Values as a UOW progresses through System
Note:
The UOW is available to be received when it is first committed. The
status values BACKEDOUT
,
CANCELLED
and PROCESSED
are valid
only if there is persistent status.
When a RECEIVE
is issued for a message within
a UOW, you might expect that the UOW status returned would be
DELIVERED
, since this is the actual status of the UOW.
This is not the case, however. On a RECEIVE
, the
Broker returns a special UOW status that reflects additional information about
the message and the UOW. These statuses are:
RECV_FIRST=
the message is the first message in a UOW.
RECV_MIDDLE=
the message is not the first or last message in a
UOW.
RECV_LAST=
the message is the last message in a UOW.
RECV_ONLY=
the message is the only message in a UOW.
RECV_NONE=
the message is not part of a UOW. This status is
particularly useful if the application is receiving both messages and UOWs.
If you receive a status of either RECV_LAST
or RECV_ONLY
and then issue
another RECEIVE
for the same UOW, you will get an
error 00740301 Conversation found: end of unit of work
indicating
the end of the UOW.
The user status field of the UOW allows additional, application-specific information to be carried with the UOW. It can be used to maintain status or indicate error information. It can also provide a form of "out-of-band" data communication between the sender and the receiver of a UOW.
For example, if a server is processing a long-running UOW, it can
periodically update the user status of the UOW (using SYNCPOINT,
OPTION=SETUSTATUS
) to indicate its progress. The client can periodically get
the user status (using SYNCPOINT, OPTION=QUERY
) and report the progress back to
the end-user.
As another example, the sender of a long-running UOW can update the user status to indicate that processing of the UOW should be abandoned by the server. The server can periodically get the user status while processing and react accordingly.
Each active UOW consumes memory resources (approximately 140 bytes per UOW) in a preallocated pool, not including the size of the message itself.
Also, additional memory resources such as the conversation and participant control blocks for the UOW, together with messages associated with them, will remain in memory for a deferred service when persistence is used. This can become significant when UOWs are being sent to a deferred service. However, the message itself does not remain in memory if sent to a service which is not currently registered - the whole purpose of deferred services. If the service is currently registered, the message remains in memory.
Messages that are sent to any (registered or unregistered) service can be "paged out" by Broker if storage is required. This feature considerably eases memory consumption when using persistence.
A UOW should be made persistent if the sender wants the Broker to assure that the UOW will be deliverable, even if there is a system or Broker failure. Assured delivery assumes that the intended receiver of the UOW is active, or becomes active within the specified lifetime of the UOW.
Since most existing Broker applications are interactive, they are probably not good candidates for persistent UOWs. New application models can now be implemented, using persistent UOWs. For example, a service that collects information from other services, such as accounting, inventory, logging, etc., would be a good fit for persistent UOWs. Another example could be a client sending a long-running request to a service (one that may be inactive or busy), disconnecting, and coming back some time later to retrieve the results. The reliability of assured delivery makes this model practical.
Persistent UOWs do not require persistent status.
A UOW can be made persistent:
by specifying STORE=BROKER
in the ACI request that creates the
UOW;
by specifying STORE=BROKER
in service definition or service defaults
portion of the Broker attribute file, making all UOWs for that service
persistent; or
by specifying STORE=BROKER
in the Broker defaults section of the
Broker attribute files, making all UOWs in the system persistent.
In addition, specifying STORE=NO
in the ACI request that creates the UOW
will explicitly make the UOW non-persistent, overriding any Broker or service
default.
A persistent UOW consumes resources in two areas.
When the UOW is committed by the sender, all of the messages are written to the persistent store. This will generate multiple I/O operations, depending on the number and size of the messages.
Space used to store the UOW and its messages will be allocated in the persistent store and will remain until the UOW is completed.
Performance of certain specific functions (e.g.
SYNCPOINT
OPTION
=COMMIT
by the
sender of a UOW) will be affected by the additional time required to perform
the I/O operations associated with writing the UOW and message(s) to the
persistent store. These operations are performed synchronously because the
Broker must ensure that the UOW, once committed, can be recovered in the event
of a system or Broker failure.
When the UOW is initially created in the persistent store, the following information is written:
Unit-of-work ID
Conversation ID
UOW Sender information, including:
User ID
Token
Server/service/class *
UOW receiver information, including:
User ID **
Token **
Server/service/class *
Creation timestamp
UOW lifetime value
Persistence and persistent status values
The following pieces of information will be included when the UOW is initially written to the persistent store and will be updated, as needed, during the life of the UOW:
UOW status
UOW user status
Attempted delivery count
Number of messages in UOW
Total message size in UOW
Persistent status lifetime value
Conversation state and EOC reason code
* Server/service/class information is only saved if the sender or receiver is a registered service.
** The receiver's user ID and token are only saved if the receiver is a service that has already acquired the conversation associated with this UOW. When there are multiple instances of a service, this means that a new conversation can be restarted by any instance of the service, but an existing conversation is bound to a specific instance of the service.
Note:
"Restored" is an active UOW which has been returned to
ACCEPTED
status; "Discarded" is a UOW which has not been returned
to ACCEPTED
status. "Discarded" does not imply the status of
DISCARDED
.
Warning: The persistent store must be available before you attempt to restart your Broker; otherwise your Broker will not restart. |
Restart Table 1
The behavior during restart of the following states depends on the
previous settings of the options Persistent UOW and Persistent Status.
UOW Status before Restart |
Persistent UOW: YES | NO |
Persistent Status: YES | NO |
Behavior of UOW and Status |
UOW Status after Restart * |
---|---|---|---|---|
RECEIVED |
YES |
YES |
UOW not restored; Status is restored |
BACKEDOUT
|
RECEIVED |
YES |
NO |
UOW not restored; Status not restored |
--- |
RECEIVED |
NO |
YES |
UOW not restored; Status is restored |
DISCARDED |
RECEIVED |
NO |
NO |
UOW not restored; Status not restored |
--- |
ACCEPTED |
YES |
YES |
UOW is restored; Status is restored |
ACCEPTED |
ACCEPTED |
YES |
NO |
UOW is restored; Status is restored |
ACCEPTED |
ACCEPTED |
NO |
YES |
UOW not restored; Status is restored |
DISCARDED |
ACCEPTED |
NO |
NO |
UOW not restored; Status not restored |
--- |
DELIVERED |
YES |
YES |
UOW is restored; Status is restored |
ACCEPTED |
DELIVERED |
YES |
NO |
UOW is restored; Status is restored |
ACCEPTED |
DELIVERED |
NO |
YES |
UOW not restored; Status is restored |
DISCARDED |
DELIVERED |
NO |
NO |
UOW not restored; Status not restored |
--- |
PROCESSED ** |
YES |
YES |
Status is restored | PROCESSED |
PROCESSED ** |
YES |
NO |
Status is not restored | --- |
PROCESSED ** |
NO |
YES |
Status is restored | PROCESSED |
PROCESSED ** |
NO |
NO |
Status not restored | --- |
* If either UOW or its status is restored.
** In this state, the UOW information has already been deleted upon
reaching PROCESSED
status.
Restart Table 2
The behavior during restart of the following states does not depend
on the settings of Persistent UOW; in these cases only the Persistent Status
exists and does not change after a restart. There is no UOW to be restored.
UOW Status before Restart | Behavior of Status | UOW Status after Restart |
---|---|---|
CANCELLED |
Status is restored | CANCELLED |
DISCARDED |
Status is restored | DISCARDED |
BACKEDOUT |
Status is restored | BACKEDOUT |
TIMEDOUT |
Status is restored | TIMEDOUT |
To restore a UOW, the Broker re-creates all internal control blocks necessary to represent the UOW when it was accepted. The table displays the targets of each control block type:
Control Block Type | Association: Sender | Receiver | Notes |
---|---|---|
PCB |
Sender; Receiver (optional) | PCB = Participant CB
|
SCB |
Sender; Receiver | SCB = Service CB
|
CCB |
Sender; Receiver | CCB = Conversation CB
Two |
UOW |
Receiver | UOW = unit of work CB
|
Note:
The messages associated with the UOW are not re-created in memory
until a RECEIVE
is actually issued for the
UOW.
Broker sets any units of work (UOWs) that are in DELIVERED
status to
ACCEPTED
status during restart processing. If this is the first unit of work
within a conversation sent by a client to a server, the assignment of the
conversation to a particular server is dropped and the conversation is again
available for all servers offering the same service.
If there is more than one unit of work in a single conversation and the
first UOW is already received and committed by the server, the link to the
server will kept even after this (non-first) UOW has reverted from DELIVERED
to
ACCEPTED
status during restart processing. The server can retrieve units of
work after restart with function RECEIVE OPTION=SYNC,CONVID=ANY
and will get all old conversations containing UOWs first and then new conversations
containing UOWs.
Servers performing a RECEIVE OPTION=SYNC, CONVID=NEW
will retrieve
only conversations not already assigned to this server. We strongly recommend
that you implement RECEIVE OPTION=SYNC,CONVID=ANY
or
CONVID=OLD
to retrieve
already assigned conversations.
Special consideration must be given when restarts occur, and there are
persistent UOWs that are being sent to replicated servers, e.g. when more than
one copy of a server is active. This is because a UOW is not associated with a
server instance until the UOW's conversation is actually received by a server.
From an application perspective, this means that a conversation that has not
yet been received by its target server will be restored so that any instance of
the server can process it. However, once the conversation has been received,
any subsequent UOWs sent on the conversation will be restored so that only the
specific instance, based on USER-ID
and
TOKEN
, can receive them. The reasoning behind this is
that a broker restart can occur without the servers being restarted, and the
servers could be maintaining context information based on the conversation.
It is important to note that this can cause problems if the server instances are started as a result of load and the same load conditions are not present after the restart. For example, a UOW could be bound to the fifth instance of a server, but after a restart there is only enough load to start three instances. For this reason, we recommend that replicated servers using persistent UOWs not maintain any conversations with multiple UOWs.
Persistent status should be considered for applications in which the sender needs to know if UOWs were actually processed successfully. In cases where the data associated with a UOW can be easily re-created in the event of a failure, persistent status may be a more desirable and lower-overhead alternative to a persistent UOW.
Persistent status does not require a persistent UOW.
A UOW's status can be made persistent:
by specifying a UWSTATP
value between 1 and 254 in the ACI request
that creates the UOW;
by specifying a UWSTATP
value between 1 and 254 in service definition
or service defaults portion of the Broker attribute file, making the status of
all UOWs for that service persistent; or
by specifying a UWSTATP
value between 1 and 254 in the Broker defaults
section of the Broker attribute files, making the status of all UOWs in the
system persistent.
Specifying UWSTATP=255
in the ACI request that creates the UOW will
explicitly make the UOW status non-persistent, overriding any broker or service
default.
Using persistent status consumes resources in two areas.
The persistent store is updated each time the UOW is modified, by
either the sender or the receiver. These modifications occur whenever a SEND
or
RECEIVE
function is issued for the UOW, or whenever its status is changed, such
as by SYNCPOINT OPTION=COMMIT
. Depending
on the implementation, this will generate one or more I/O operations.
The space used for the UOW (but not its messages) in the persistent store remains allocated for some period of time after the UOW has been completed.
The performance of individual requests will generally be affected by the additional time required to perform the I/O operations associated with maintaining persistent status. At this time, all operations are performed synchronously, although that may change in future releases.
UOWs and persistence provide functionality for the application program (either client or server) to recover from failures: i.e., system, broker or application. In addition, this functionality allow new types of applications to be built, including ones not requiring concurrent execution of the client and server.
There are no standard rules for recovery, because each application model will use this functionality differently and will have different requirements for recovery. But the considerations in the following section should be kept in mind.
The most useful function for recovery is the
SYNCPOINT
,
OPTION
=LAST
. This
function will return the UOWID, CID, and status of the last UOW created by the
caller, based on the USER-ID
and
TOKEN
. This function can be used when an application
starts or when it detects a failure to determine how much processing has been
completed on a UOW. This information can then be used to decide how to recover
from the failure.
Chess-by-mail is a sample of an application that takes advantage of UOWs, persistence, and persistent status. In generic terms, this application involves a client and a server exchanging messages on a single conversation. The conversation is long-running, and there is no requirement that the client and the server be active at the same time.
Although chess-by-mail was conceived as a single application, it is perhaps easier to describe its operation separately for the client and the server side. By convention, the white player is the client and the black player is the server. For simplicity, any user interaction has been left out of the description. Also for simplicity, only one chess-by-mail game is assumed to be running at any one time.
The behavior of the chess-by-mail client is as follows:
Logon, specifying a USER-ID
and
TOKEN
, which allow recovery of prior UOWs.
Issue SYNCPOINT
,
OPTION
=LAST
to determine
the status of the last UOW created.
If the return code is 00780305 - UOW not found
, then
there is no game in progress. So send the first white move to the server with:
SEND OPTION=COMMIT,CID=NEW
. If the send is
successful, logoff and exit.
If the return code from SYNCPOINT
is 0,
then there is a last UOW and therefore a game is in progress. The UOW status
value is examined to decide how to proceed.
If the status is ACCEPTED
, then the server has not yet received the
last move, so logoff and exit.
If the status is DELIVERED
, then the server is currently processing
the last move, so logoff and exit.
If the status is TIMEOUT
, then the server did not receive the last
move before its lifetime expired, so logoff and exit.
If the status is PROCESSED
, then the server has received the last
move and committed the UOW. Our application model has the client sending a move
in response and committing both UOWs at the same time. So we need to receive
the new move and send a reply to it.
Get the server's move with RECEIVE,OPTION=SYNC,CID=n
, where
n is the CID returned from SYNCPOINT OPTION=LAST
.
Send the response move back using SEND OPTION=SYNC,CID=n
.
Commit both the received and sent UOWs with a single call SYNCPOINT OPTION=COMMIT,UOWID=BOTH
.
Logoff and exit.
The behavior of the chess-by-mail server is as follows:
Logon, specifying a Userid and Token, which allow recovery of prior UOWs.
Register as the chess-by-mail server.
Issue SYNCPOINT OPTION=LAST
to determine
the status of the last UOW created.
If the return code is 00780305 - UOW not found
, then
there is no game in progress. So we receive first white move from the client
with: RECEIVE OPTION=SYNC,CID=NEW
. When the
RECEIVE
has been completed, continue at step 11.
If the return code from SYNCPOINT
is 0,
then there is a last UOW and therefore a game is in progress. The UOW status
value is examined to decide how to proceed.
If the status is ACCEPTED
, then the client has not yet received the
last move, so deregister, logoff and exit.
If the status is DELIVERED
, then the client is currently processing
the last move, so deregister, logoff and exit.
If the status is TIMEOUT
, then the client did not receive the last
move before its lifetime expired, so deregister, logoff and exit.
If the status is PROCESSED
, then the client has received the last
move and committed the UOW. Our application model has the server sending a move
in response and committing both UOWs at the same time. So we need to receive
the new move and send a reply to it.
Get the client's move with RECEIVE,OPTION=SYNC,CID=n
, where
n is the CID returned from
SYNCPOINT,OPTION=LAST
.
Send the response move back using SEND,OPTION=SYNC,CID=n
.
Commit both the received and sent UOWs with a single call:
SYNCPOINT,OPTION=COMMIT,UOWID=BOTH
.
Deregister, logoff and exit.