Invocation handlers
To better understand this section, examine the sample SstPingPongByValue.
For a request sender, invocation handlers coordinate the marshaling and transfer of the request as well as providing a mechanism for waiting for the result. For request receivers, invocation handlers provide a mechanism for waiting for messages and then coordinate their retrieval, reconstruction, execution and the subsequent replying of the return value as required. Application requirements in this area vary widely so SST partitions the behavior into two separate objects: invocation handlers and dispatchers.
Invocation handlers define the details of how messages are moved from one place to another. That is, they manage the dispatchers, marshalers, transports and collections of reply locations. They also manage optional server processes which automatically fetch and process requests and replies. The following protocol controls the autonomous behavior of invocation handlers.
makeActive
Sets the receiver in active mode where it actively seeks out new work. If you detect that the transport cannot receive messages then ensure that the receiver is not running a server process.
makePassive
Sets the receiver in passive mode where it does not actively seek out new work.
resume
Resumes processing of requests if possible. If the receiver is in passive mode then it does nothing. If its endpoint cannot receive messages then it puts the receiver in passive mode. If the receiver is already running then it does nothing.
suspend
Stops the active processing of incoming messages. Answers true if the receiver was running at the time. Otherwise, answers false.
Passive invocation handlers use user processes to fetch and handle requests and replies. Due to multithreading concerns, if you expect concurrent use of a handler, ensure that that handler is active.
Making a handler passive usually terminates any server processes associated with the handler. These may be in the middle of processing a user request. Thus, use the makePassive operation carefully.
Messages are invoked remotely using the invocation protocol shown below. The endpoint argument specifies the communications destination to which request should be sent. It is assumed that there will be a compatible invocation handler at or near endpoint to take care of processing the request. Note the receiver of request is not endpoint but rather is embedded in request itself (that is, it is a directed message). Replies are returned through a similar mechanism.
invoke: request at: endpoint
Sends @request to @endpoint for processing and returns the result if one is required. It is assumed that @endpoint represents some remote location. Returns an error if one should occur.
reply: value inResponseTo: request
Sends @value in reply to @message. If an error occurs, replies an error value to @message's sender and returns the error from this method. In the event that an error occurred while trying to send the error reply, simply returns an error from this method. If a reply of any sort is actually sent then @message is marked as having been answered.
earlyReply: value inResponseTo: request continuation: continuation
Sends @value as an early reply to @request. An early reply is defined as a reply done before the method invoked as a result of dispatching @request has returned. @continuation is a zero argument block containing the code which should be executed after @value is replied. If an error occurs, it replies an error value to the origin of @request (its sender) and returns the error from this method. In the event that an error occurs while trying to send the error reply, it simply returns an error from this method. If a reply of any sort is actually sent then @request is marked as having been answered.
deferReply
Marks the receiver as a deferred request. The value returned from the method processing a deferred request is ignored. The request (self) can be replied to at a later time using the lateReply: protocol.
lateReply: value
Sends @value in reply to the receiver which has been deferred. If an error occurs, replies an error value to the origin of the receiver (its sender) and returns the error from this method. If an error occurs while trying to send the error reply, returns an error from this method. If a reply of any sort is actually sent then the receiver is marked as having been answered.
Normally invocation handlers map incoming requests onto Smalltalk messages which are executed locally. By default the value returned from that Smalltalk message is the value returned to the original sender of remote request. There are three situations which vary from this.
The first is if the request was marked as asynchronous using the protocol markAsAsynchronous. Asynchronous messages do not require replies so the return value from the invoked method is simply ignored. Note that senders of asynchronous messages do not wait for replies as none will be coming.
The second case is if the handling of the request resulted in an early reply using the protocol described above. In this case, the explicitly mentioned value is returned as the result of the request and the request is marked as answered (using markAsAnswered). Again, the value actually returned from the invoked method is discarded. Note that the DGC does not collect distributed garbage cycles.
The third case is, if in the processing of the request, it is marked as deferred (using deferReply:). In this case, the value returned by this method is ignored. You are responsible for maintaining the request itself in some appropriate data structure so that a reply can eventually be sent (using lateReply:). This behavior is useful when a request cannot be answered immediately, but the client should not be resumed until the reply value is available. After deferring the processing of a request, the handling process is free to service other requests for the invocation handler.
While a handler's invoke:at: protocol can be used directly, it is often convenient to have a local representation of a remote invocation handler. SstRemoteInvocationHandlers manage the correspondence between local invocation handlers and remote endpoints. Using this, the protocol for remote method invocation is simplified to:
invoke: request
Sends @request to the receiver's % endpoint for processing and returns the result if one is required. It is assumed that @endpoint represents some remote location. Returns an error if one should occur.
Last modified date: 05/12/2020