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.
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.
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: