Horizon conversation interface
This topic is intended for programmers who use the Horizon conversation interface, the statements a SOUL request uses to converse with a partner program. The SOUL conversation statements that comprise the conversation interface are discussed in detail individually and shown in sample programs in this topic.
Horizon partners have a peer to peer relationship. One partner controls the direction of data flow on the path at any given time, but either partner may assume control at different points in the conversation. Which partner is in control at a given point is decided by the application designer and is based on Horizon's implementation of the LU 6.2 conversation protocols. The rules that govern Horizon conversations are described and their use is illustrated in this topic.
Conversation rules and states
Imagine a debate in which there are no rules of discourse: each side talks out of turn, arguing its point at the same time as the other. It would be difficult, if not impossible, to follow each train of thought and make sense of it. A formal set of rules prevents this, however, by requiring each side to talk and listen in turn.
Two communicating programs also need to obey rules. An orderly conversation implies, for example, that a program that sends data can expect the other to receive it:
Partner A Partner B
SEND → RECEIVE
SEND → RECEIVE
An orderly conversation also implies that both programs do not wait to receive data at the same time, each expecting the other to send it:
Partner A Partner B
SEND → RECEIVE
Rules impose order on a conversation by specifying what actions either partner may take at any given point. Rules also allow the LU that is host to a conversation program to detect errors and to report them in an understandable way to the programmer. Without these rules, programmers would be forced to detect errors on their own by observing lost data or deadlock conditions.
LU 6.2 conversation rules rely on the concept of a conversation state. At the completion of each SOUL communication statement, the conversation is said to be in one of a number of states. Each state is associated with a set of verbs (communication statements) the application program is allowed to issue when in that state, and a set of verbs that are prohibited when in that state. A set of rules also dictates how a conversation partner may change from one state to another upon the completion of a verb (in Horizon, a SOUL statement).
Violations of these state rules are detected by the LU at which a program is running. When a violation occurs, the LU returns a state check indicator to the program, through the $STATUS and $STATUSD functions. State checks are described in more detail in Enforcing direction of data flow.
Horizon conversation states
A Horizon conversation partner can be in one of five states:
|Reset||Exists between conversations. No Horizon resources have been acquired; the process is not open.|
|Send||The state in which a partner is allowed to send data.|
|Receive||The state in which a partner must be to receive information.|
|Confirm||An intermediate state in which the receiving side of the conversation is expected to send a confirmation or an error response to its partner.|
|Close||The state in which the conversation is over (the partner has closed its process), but local resources are still allocated.|
Horizon state rules
The transition rules that specify how a partner changes from one state to another are described in the examples in this section. The descriptions of the individual SOUL conversation statements in Horizon conversation interface contain tables that list the state changes possible for each statement. Conversation statement/state dependencies lists the Horizon statements that can be issued in each state.
Horizon state rules also help to address the following issues, each of which is discussed in detail in this section:
- Enforcing the direction in which data may be sent at a given point in the conversation.
- Providing ways for the receiving partner to interrupt the sender and request the right to send data.
- Providing a way for the sending partner to request acknowledgment that sent data has been received and accepted, and for the receiving partner to supply that acknowledgment.
Horizon Conversation Data Flow
Data flow rules
The following rules govern Horizon conversation data flow:
- When a conversation begins, the client side is in Send state and the server side is in Receive state.
At any given time during a conversation, one and only one partner is allowed to send data.
The other partner must receive it.
The direction of data transfer remains the same until the side that is sending indicates that it is finished. A program indicates that it is finished sending data by issuing one of the following statements:
- RECEIVE, which allows its partner to send data.
- CONFIRM, to which its partner must respond positively or negatively.
- CLOSE PROCESS, which terminates the conversation.
Each conversation partner runs under the supervision of a host LU. (For more information about LUs, see SNA concepts and terminology.) The LUs coordinate and enforce these data flow rules by monitoring the Send or Receive state at each end of the conversation.
The following figure, "Conversation data flow illustration," shows the effect of these data flow rules on the basic format of a Horizon conversation. The numbers in parentheses indicate the sequence of the data flow between the client and server programs.
Most of the figures in this topic are arranged to show the logical correlation of the conversation statements issued by each partner program. Arrows show the type of information passed between the partners and often unrealistically suggest that a physical transmission of data accompanies each statement. For more information about how the physical transmission of data is determined, see Buffering and shipping conversation information.
This table describes the steps in parentheses in the previous figure.
|(1)||The client program allocates a conversation with a server program. After the OPEN PROCESS completes, the client is in Send state and the server is in Receive state.|
|(2)-(3)||The client program sends two messages to the server program. The client program then issues a RECEIVE statement.|
|(4)||The RECEIVE statement puts the client program in Receive state.|
|(5)-(8)||The server program receives (issues RECEIVE statements) and the host LU returns data to it. When the LU encounters the "change-direction" indicator, it places the server program in Send state, and it notifies the server program by setting its RESULT %variable to "SEND."|
|(9)-(10)||The server program sends one message and closes (with CLOSE PROCESS) its side of the conversation.|
|(11)-(12)||The client program receives until it has received all the messages the server sent. When the LU encounters the "close" indicator, it notifies the client program by setting $STATUS to 4.|
|(13)||The client program closes its side of the conversation.|
Enforcing direction of data flow
A program puts itself into another state by issuing the appropriate statement during a conversation. For example, a program in Send state changes to Receive state by issuing a RECEIVE statement. The program thereby surrenders the right to send information; it must receive until its partner gives up the right to send.
As shown in the figure "Conversation State Check," however, a program in Receive state cannot regain send rights by issuing a SEND statement. Issuing SEND is not allowed in Receive state (see Horizon conversation states and statements). If the program issues a SEND statement while in Receive state, it receives a state check from its LU in the form of non-zero $STATUS and $STATUSD codes. (These codes are set by the LU as completion codes following each SOUL statement issued.)
A state check means that a program is out of synchronization with its partner because of an application program error in one or both partners. A program is issuing a statement while it is in a state in which that statement is not allowed. By issuing state checks, the LUs enforce the conversation data flow rules.
After a state check indication, you can issue a QUERY PROCESS statement to determine the correct conversation state. Then you can terminate the conversation and fix one or both of the partner programs.
Following the RESULT %variable
The RESULT parameter of the RECEIVE statement indicates to a program in Receive state that its partner has surrendered the right to send. Upon completion of a RECEIVE, the RESULT %variable specified in the RECEIVE contains a character string indicating what was just received (see Steps 6-8 in "Conversation Data Flow Illustration").
If RESULT contains the string "DATA", the receiving side knows that it has received information from its partner and should process it accordingly. If RESULT contains the string "SEND", the receiving side knows that its partner is surrendering the right to send. The receiving program can begin to send data.
Unless it intends to interrupt the sender, the receiving side never acts on its own. It follows the directions in the RESULT %variable until it is told to go into Send state. Once in Send state, it controls the conversation.
Interrupting the Sender
During a conversation, a conversation partner in Receive state can use one of two statements to interrupt the sending side:
- SEND ERROR
- SIGNAL PROCESS
Using SEND ERROR to interrupt the sender
If the receiving side detects an error in the information received, such as the arrival of incorrect data, an "out of space" condition, or an application logic error, it may force a reversal in the direction of data flow by issuing a SEND ERROR statement.
SEND ERROR transmits a negative response to the partner and then discards all not-yet-received information sent by the partner. No further information is presented to the transaction program. Upon receipt of the negative response, the remote LU switches the direction of data flow. The program that issued the SEND ERROR changes into Send state and its partner changes into Receive state. See the following figure, "Using SEND ERROR in a File Transfer Application."
The following figure, "Using SEND ERROR in a File Transfer Application," shows SEND ERROR used in a conversation.
Using SIGNAL PROCESS to interrupt the sender
If the receiving side of a conversation wants to interrupt its partner without causing an error condition, it can use the SIGNAL PROCESS statement.
Issuing SIGNAL PROCESS does not put the issuing program into Send state or discard any data that is already in transit from the sending partner. SIGNAL PROCESS merely transmits a desire to send to the partner.
The partner program is notified about this desire to send at the completion of its next SEND statement: its host LU sets a value of 1 in the %variable specified in the REQSEND parameter of SEND. The partner does not have to pay attention to this signal. The issuing program must continue to receive until the partner surrenders the right to send by issuing the RECEIVE statement.
Typically, a sending program knows whether its partner is coded to issue a SIGNAL PROCESS, and only checks the REQSEND %variable if the conversation is designed to use this feature.
The following figure, "Using SIGNAL PROCESS," shows SIGNAL PROCESS used in a conversation.
Confirming Receipt of Data
Information is typically passed back and forth during a conversation without an indication of whether it has been received by the intended partner. Sometimes, however, before it can continue with the transaction, one side of a conversation needs confirmation that what it sent was received. The CONFIRM and CONFIRMED statements perform this function.
The sending side issues the CONFIRM statement. Any buffered data is shipped to the partner along with the indication that a confirmation is expected. The receiving side must then issue a CONFIRMED or a SEND ERROR statement before the sending side can continue.
The following figure, "Confirming Receipt of Data," is a conversation excerpt showing the use of CONFIRM and CONFIRMED.
Buffering and Shipping Conversation Information
This section describes how the LUs of conversation partner programs buffer and ship conversation information from partner to partner.
The Horizon buffering process is such that issuing a SEND statement doesn't necessarily cause data to be sent immediately. This introduces a potentially confusing interval between the first SEND statement issued and the eventual confirmation (or not) of the receipt of the data sent. Also, since a SEND may not cause data to be shipped immediately, the application programmer must know the statements that do cause immediate shipment.
How the LUs buffer and ship data
The following figure, "Buffering Data," shows the larger context for the conversation depicted in "Conversation Data Flow Illustration". The conversation between the partner programs, Program A and Program B, uses a session established between their respective LUs, M204A and M204B.
The LUs buffer data and handle statement processing for the application programs. While a statement issued by an application program is being executed by an LU, the application program's processing is suspended. Application program processing continues when the LU returns control to the application program.
When a program issues a SEND statement, the data sent is stored in the conversation buffer in that program's LU. The contents of the buffer are held until it is full or until the application program issues a statement that explicitly causes the LU to send, or flush, the buffer. The statements that can cause an immediate buffer flush are discussed later in this section.
The contents of the sending LU's conversation buffer is shipped over the session to the partner LU's conversation buffer, where it is stored until the partner program issues a statement that receives data.
Large blocks of data are broken into multiple network conversation buffers on the sending side and reassembled on the receiving side.
The "Buffering Data" figure shows how the LUs buffer and ship data. This depiction of the physical transmission of conversation information complements the preceding figures in this topic. The earlier figures emphasize the logical correlation of conversation statements.
In Buffering Data, the data from Program A's three SEND statements is stored in the conversation buffer in LU M204A. Program A's RECEIVE statement causes LU M204A to ship the conversation buffer over the session to LU M204B's conversation buffer. The buffer's data is staged in a "receive buffer" in LU M204B before being passed through to the conversation buffer.
The data is stored in LU M204B's conversation buffer until Program B receives it with RECEIVE statements. LU M204A appends a change-direction indicator to the buffered information when Program A issues a RECEIVE statement.
Four statements cause immediate buffer flushing
The following statements can cause an immediate buffer flush:
When issued in Send state, RECEIVE indicates to the host LU that the application program intends to change the conversation direction. The LU then sends all buffered data to the partner.
CONFIRM indicates that the application program expects a confirmation from its partner after all data that has been sent up to that point is physically shipped.
FLUSH PROCESS is used by an application program that needs to force a physical send. FLUSH PROCESS could be used, for example, if a program that sends data only intermittently to its partner needs to have that data physically sent immediately, rather than be buffered to conserve network utilization.
Issued in Send state, INVITE, like RECEIVE, indicates to the host LU that the application program intends to change the conversation direction. The LU then sends all buffered data to the partner. Unlike RECEIVE, the issuing program does not wait for a reply after the buffer is sent.
Buffering delays error and data-receipt notification
Because the LU buffers data, not always shipping it immediately, certain errors (especially OPEN PROCESS errors) do not reflect back to the client program until a buffer is actually shipped through the network. Depending on how the conversation is constructed, the client program can issue an OPEN PROCESS statement and many SEND statements before it receives an OPEN PROCESS error condition.
Note: A good completion code following a SEND statement is only an indication that the data to be transmitted has been accepted by Model 204. It does not tell the program whether that data has been received by the conversation partner. Before taking any action that depends on the successful arrival of sent data, you should issue a CONFIRM, which forces the data to be physically sent and which requires an acknowledgment from the other side.
Communicating with Multiple Partners Concurrently
Typically a partner program waits until information is received from the remote partner before proceeding to the next statement in the program. This serial processing is satisfactory for applications that depend on input from a specific partner before they can continue. However, serial processing restricts the ability to communicate efficiently with multiple concurrent partners: regardless of the number of concurrent conversations the program has, the program must request and wait for data from one partner at a time before soliciting data from another partner.
Horizon also supports applications in which a local program sends a request for data to multiple partners and processes their replies in any order. The local program invites its partners to send it data, then either waits for the partners to respond or continues executing other tasks until its partners respond.
The INVITE statement causes residual data in the send buffer to be flushed to the partner along with a Change Direction indicator. This places the sender in Receive state and the partner in Send state, like issuing the RECEIVE statement. Unlike RECEIVE, INVITE does not cause the program to wait for a reply. Instead, it continues to execute. Subsequent INVITE statements can therefore be issued to other partners before processing of replies begins.
To detect whether and from whom a reply has arrived, the application requires a WAIT FOR RECEIPT or a TEST RECEIPT statement following INVITE. Both WAIT FOR RECEIPT and TEST RECEIPT permit the application to detect a reply from a specific conversation ID or from any of the partner conversations or processes with outstanding invitations.
WAIT FOR RECEIPT suspends further running of the program until the specified reply is received. TEST RECEIPT detects the specified reply but does not stop the program from running. Situations for which WAIT FOR RECEIPT and TEST RECEIPT are suitable are described below.
Awaiting requests for data from multiple partners
If your application requires data from multiple partners to complete a task before the program can do further processing, use the WAIT FOR RECEIPT statement after INVITE. The WAIT FOR RECEIPT statement suspends execution of your program until a reply is received from the specified remote partner(s). Your program awakens when a specified reply has arrived. The RECEIVE statement then receives the data into program variables.
Confirming Receipt of Data is an example of a SOUL program in which the client program initiates tasks at both server program A and server program B. The client waits while the servers process the request. The $STATUS=0 code following the client's WAIT FOR ANY RECEIPT statement tells the client to RECEIVE the data from server program B. The $STATUS=0 code following the client's next WAIT FOR ANY RECEIPT statement tells the client to RECEIVE the data from server program A.
The shaded area in the following figure, "Waiting for receipt of data," indicates where the client program and the server programs are executing concurrently.
Initiating a background task
You can use the INVITE statement followed by TEST RECEIPT to have a partner process serve as a background task. Since the TEST RECEIPT statement does not suspend execution of your program, you can invite a partner program to perform a task and can continue to perform other tasks until a reply is received from the partner. When TEST RECEIPT $STATUS codes indicate that a reply has arrived, the RECEIVE statement puts the data into program variables.
The application subsystem performing the background task can execute both command level commands and SOUL procedures.
The following figure, "Testing for receipt of data," is an example of a SOUL program in which the client program initiates a task at server program A and continues to run while server program A is processing the task request. The client periodically (in this case, each time it is about to use READ SCREEN) issues a TEST FOR RECEIPT A statement. When the $STATUS code indicates that no reply has been received ($STATUS/D=1/2), the client program continues with other work. When the $STATUS code indicates that server program A has replied ($STATUS=0), the client program RECEIVEs the data.
The shaded area in the figure indicates where the client program and the server programs are executing concurrently.
With the method shown in "Testing for receipt of data," you can initiate multiple background tasks and can test for replies from invited partners.