RPC-style applications
RPC-style applications directly interact with the messaging infrastructure. In SST the main component of interest is the invocation handler (see SstInvocationHandler). Applications can create and manage invocation handlers exclusively for their own use or share them. Loosely-coupled applications probably should not share handlers to enable their independent creation and destruction.
Invocation handlers are configured objects. Their configurations specify the kind of object space used, the way requests are sent and processed (the dispatcher used), the marshaler to use, and other lesser details. The default configuration has reasonable settings for most of these options but you must set up the marshaler and object space as a minimum. The invocation configuration for the SstPingPongByValue example is defined in the class method registerInvocationConfiguration shown below. This method runs when the application loads and it installs a configuration in the global scheme registry. In this case, whenever a URL with the scheme pingPongValue is used, it maps onto this configuration. Note that this code is largely the same for all examples.
registerInvocationConfiguration
SstInvocationHandler
register: (
SstInvocationConfiguration byValueConfiguration
marshaler: SstSwapperMarshaler byValueConfiguration)
asScheme: self invocationScheme
setupPong: pong ponging: ping
LocalHandler :=
SstInvocationHandler on: (SstLocalEndpoint fromUrl: (self urlFor: pong)).
LocalHandler startUp.
RemoteHandler := SstRemoteInvocationHandler
to: (SstRemoteEndpoint fromUrl: (self urlFor: ping)) using: LocalHandler.
RemoteHandler startUp.
LocalHandler space export: self as: self name
Given a URL string (from urlFor: and the user-supplied @pong) a local invocation handler is built. The act of building a handler automatically finds and uses the invocation and transport configurations registered with the system. The handler is then started. Starting the handler opens listening sockets (in the case of TCP), sets up internal data structures, and starts the server process which fetches and dispatches requests.
Next a remote handler is created. This is a local representation of an invocation handler on a remote machine. It is used as a convenience mechanism to link the local handler with a particular destination, specified in this case by @ping.
Once the local system is up and running, the setup code explicitly exports the class SstPingPongByValue under its own name. Exporting the class makes it available as the receiver of messages from other machines.
After running similar code on Ping, you can bootstrap the application by establishing cross-machine links. The code below first creates an example object and then exports it as pingPong. It then does an RPC-style message send to Pong asking it to create an example object and link it to the local one. The local object is identified by its export key (pingPong). Pong returns the export key of the example object it created and explicitly exported.
createPingAndPong
| ping pong |
ping := self new.
LocalHandler space export: ping as: #pingPong.
pong := RemoteHandler invoke: (
DirectedMessage
receiver: self name selector: #createFor: arguments: #(pingPong)).
ping remote: pong.
^ping
With the application bootstrapped, you can run it by executing:
<pingObject> start: 3 with: #(1 2)
where <pingObject> is the result of createPingAndPong. This code eventually runs the method shown below which does another explicit invoke using the export key of the remote object determined during bootstrapping as the message receiver.
sendPing: count with: value
^RemoteHandler invoke: (
DirectedMessage
receiver: remote
selector: #ping:with:
arguments: (Array with: count with: value))
When the application finishes running, the SST resources should be freed. This is done by sending either shutDown or clear to the invocation handlers in use. Clearing resources must be done on each machine in the system.
Last modified date: 01/29/2015