CICS® business transaction services support client/server processing. A server process is one that is typically waiting for work. When work arrives, BTS restarts the process, which retrieves any state data that it has previously saved.
Typically, the client invokes the server with a named input event, and sends it some input data in a data-container. From these inputs, the server determines what actions it needs to take. It returns any output for the client in a data-container.
When the client has dealt with any output returned by the server, it releases the server process. Releasing the server means that its in-memory instance is freed. At this point, the server process is maintained only by BTS.
The client/server example in this section shows:
Figure 19 shows, in COBOL pseudocode, the example client program, PRG001.
Identification Division.
Program-id. PRG001.
Environment Division.
Data Division.
Working-Storage Section.
01 RC pic s9(8) comp.
01 Unique-Reference pic x(36) value low-values.
.
01 Process-Type pic x(8) value 'Servers'.
.
01 Event-Name pic x(16) value low-values.
.
01 Work-Buffer.
.
01 Work-request Pic x.
88 Work-New value 'N'.
88 Work-Continue value 'C'.
88 Work-End value 'E'.
Linkage Section.
01 DFHEIBLK.
.
01 DFHCOMMAREA.
.
.
Procedure Division using DFHEIBLK DFHCOMMAREA.
In-The-Beginning.
.
EXEC CICS SEND ...
RESP(data-area) END-EXEC
.
EXEC CICS RECEIVE ...
RESP(data-area) END-EXEC
.
Move ..unique.. TO Unique-Reference
Move ..request.. TO Work-Request
.
Evaluate True
When Work-New
Perform New-Process
When Work-Continue
Move 'SRV-WORK' TO Event-Name
Perform Existing-Process
When Work-End
Move 'SRV-SHUTDOWN' TO Event-Name
Perform Existing-Process
When Other
.
End Evaluate.
.
EXEC CICS GET CONTAINER('Server-Out')
ACQPROCESS INTO(Work-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS SEND ...
RESP(data-area) END-EXEC
.
EXEC CICS RETURN END-EXEC
.
New-Process.
.
EXEC CICS DEFINE PROCESS(Unique-Reference) PROCESSTYPE(Process-Type)
TRANSID('SERV')
PROGRAM('SRV001')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Server-In')
ACQPROCESS FROM(Work-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACQPROCESS
SYNCHRONOUS
RESP(RC) RESP2(data-area) END-EXEC
.
Existing-Process.
.
EXEC CICS ACQUIRE PROCESS(Unique-Reference) PROCESSTYPE(Process-Type)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Server-In')
ACQPROCESS FROM(Work-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACQPROCESS
SYNCHRONOUS
INPUTEVENT(Event-Name)
RESP(RC) RESP2(data-area) END-EXEC
.
End Program.
First, PRG001 determines if this is the first time the server is to be called. If it is, it establishes a unique name for this instance of the server process. Then it creates the server process by issuing an DEFINE PROCESS command with that unique name. PRG001 provides some input data for the server in a data-container named Server-In:
EXEC CICS PUT CONTAINER('Server-In')
ACQPROCESS FROM(Work-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
The ACQPROCESS option associates the Server-In container with the process that PRG001 has "acquired". A program "acquires" access to a process in one of two ways: either, as here, by defining it; or, if the process has already been defined, by issuing an ACQUIRE PROCESS command.
Having created the server process, PRG001 issues a request to run it synchronously. The RUN ACQPROCESS command causes the currently-acquired process to be activated. Because RUN ACQPROCESS rather than LINK ACQPROCESS is used, the server process is run in a separate unit of work from that of the client. PRG001 waits for the server to run, and then retrieves any data returned from a data-container named Server-Out.
PRG001 has now temporarily finished using the server process; the implicit syncpoint at RETURN causes it to be released.
To use this instance of the server again, PRG001 must first acquire access to the correct process. It does this by issuing an ACQUIRE PROCESS command which specifies the unique combination of the process’s name and process-type:
EXEC CICS ACQUIRE PROCESS(Unique-Reference) PROCESSTYPE(Process-Type)
RESP(data-area) RESP2(data-area) END-EXEC
Once again, PRG001 provides input data for the server in a data-container named Server-In, and requests the process to be run:
EXEC CICS RUN ACQPROCESS
SYNCHRONOUS
INPUTEVENT(Event-Name)
RESP(RC) RESP2(data-area) END-EXEC
PRG001 uses the INPUTEVENT option of the RUN command to tell the server why it has been invoked--in this case, it is for SRV-WORK. (The server must have defined an input event of that name.)
Again, PRG001 waits for the process to complete, retrieves any returned data, and releases the process.
Eventually, PRG001 tells the server to shut down by invoking it with an event of SRV-SHUTDOWN.
Figure 20 shows, in COBOL pseudocode, the example server program, SRV001.
Identification Division.
Program-id. SRV001.
Environment Division.
Data Division.
Working-Storage Section.
01 Event-Name pic x(16).
88 DFH-Initial value 'DFHINITIAL'.
88 SRV-Request value 'SRV-REQUEST'.
01 Sub-Event-Name pic x(16).
88 SRV-Work value 'SRV-WORK'.
88 SRV-Shutdown value 'SRV-SHUTDOWN'.
01 Input-Buffer.
.
01 Output-Buffer.
.
01 State-Buffer.
.
Linkage Section.
01 DFHEIBLK.
.
Procedure Division.
Begin-Process.
.
EXEC CICS RETRIEVE REATTACH EVENT(Event-Name)
RESP(data-area) RESP2(data-area) END-EXEC
.
Evaluate True
When DFH-Initial
Perform Initial-Request
Perform Server-work
When SRV-Request
Perform Server-Event
When Other
.
End Evaluate.
.
EXEC CICS RETURN END-EXEC
.
Server-Event.
.
EXEC CICS RETRIEVE SUBEVENT(Sub-Event-Name) EVENT(Event-Name)
RESP(data-area) RESP2(data-area) END-EXEC
.
Evaluate True
When SRV-Work
Perform Server-Work
When SRV-Shutdown
Perform Server-Shutdown
When Other
.
End Evaluate.
.
Initial-Request.
.
EXEC CICS DEFINE INPUT EVENT('SRV-WORK')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE INPUT EVENT('SRV-SHUTDOWN')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE COMPOSITE EVENT('SRV-REQUEST') OR
SUBEVENT1('SRV-WORK')
SUBEVENT2('SRV-SHUTDOWN')
RESP(data-area) RESP2(data-area) END-EXEC
.
Server-Work.
.
EXEC CICS GET CONTAINER('Server-In') INTO(Input-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
If DFH-Initial
EXEC CICS DEFINE ACTIVITY('Work')
TRANSID('SWRK')
PROGRAM('PRG002')
RESP(data-area) RESP2(data-area) END-EXEC
.
Else
EXEC CICS GET CONTAINER('Previous-State') INTO(State-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
End-If.
.
EXEC CICS PUT CONTAINER('Work-Input')
ACTIVITY('Work') FROM(Input-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RUN ACTIVITY('Work')
SYNCHRONOUS
RESP(data-area) RESP2(data-area) END-EXEC
EXEC CICS CHECK ACTIVITY('Work') COMPSTATUS(status)
RESP(RC) RESP2(data-area) END-EXEC
.
If RC NOT = DFHRESP(NORMAL)
.
End-If.
.
If status NOT = DFHVALUE(NORMAL)
.
End-If.
.
EXEC CICS GET CONTAINER('Work-Output')
ACTIVITY('Work') INTO(Output-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Previous-State') FROM(State-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS PUT CONTAINER('Server-Output') FROM(Output-Buffer)
RESP(data-area) RESP2(data-area) END-EXEC
.
Server-Shutdown.
EXEC CICS DELETE EVENT('SRV-WORK')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DELETE EVENT('SRV-SHUTDOWN')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DELETE EVENT('SRV-REQUEST')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS RETURN ENDACTIVITY
RESP(data-area) RESP2(data-area) END-EXEC
End Program.
The server program, SRV001, first issues a RETRIEVE REATTACH EVENT command to determine the reason for its invocation. On its first invocation, the event returned is DFHINITIAL, which tells SRV001 to perform any initial housekeeping. SRV001’s housekeeping includes defining two input events for which it could subsequently be reinvoked:
EXEC CICS DEFINE INPUT EVENT('SRV-WORK')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE INPUT EVENT('SRV-SHUTDOWN')
RESP(data-area) RESP2(data-area) END-EXEC
.
EXEC CICS DEFINE COMPOSITE EVENT('SRV-REQUEST') OR
SUBEVENT1('SRV-WORK')
SUBEVENT2('SRV-SHUTDOWN')
RESP(data-area) RESP2(data-area) END-EXEC
.
The DEFINE COMPOSITE EVENT command defines a third, composite, event (SRV-REQUEST), and adds the two input events to it. Because the composite event uses the OR Boolean operator, it will fire when either of the two input events fires; SRV001 will be reattached.
SRV001 obtains its input data from a data-container named Server-In. It then performs the work activity Work.
When the work activity has completed, SRV001 saves some state data for the next time it is run, and returns the output data produced by the work activity to the client program in a data-container named Server-Output.
On subsequent invocations, SRV001 determines that it has been invoked to perform work. (The RETRIEVE REATTACH EVENT command returns the composite event SRV-REQUEST, and a RETRIEVE SUBEVENT command with an event-name of SRV-REQUEST returns the sub-event SRV-WORK.)
Eventually, the RETRIEVE SUBEVENT command returns the sub-event SRV-SHUTDOWN, and SRV001 responds by ending the server process. First it deletes the user events that it has defined, then issues an EXEC CICS RETURN ENDACTIVITY command to indicate that it has completed all its processing.