Goto Chapter: Top 1 2 3 4 5 6 7 8 9 Bib Ind
 Top of Book   Previous Chapter   Next Chapter 

6 Client's functionality
 6.1 Sending request and getting result
  6.1-1 IsProcess

  6.1-2 NewProcess

  6.1-3 CompleteProcess

  6.1-4 EvaluateBySCSCP

  6.1-5 TerminateProcess
 6.2 Remote objects
  6.2-1 StoreAsRemoteObjectPersistently

  6.2-2 IsRemoteObject

  6.2-3 RemoteObjectsFamily

  6.2-4 RetrieveRemoteObject

  6.2-5 UnbindRemoteObject

6 Client's functionality

Sending and getting requests to the SCSCP server(s), the client operates with processes. Process is an abstraction which encapsulates an InputOutputTCPStream (see IsInputOutputTCPStream (3.1-1)) from a client to the server and the process ID of the CAS running as a server (deduced from the connection initiation message; may be unassigned, if the server CAS did not communicate it).

6.1 Sending request and getting result

6.1-1 IsProcess
> IsProcess( filter )

This is the category of processes. Processes in this category are created using the function NewProcess (6.1-2).

6.1-2 NewProcess
> NewProcess( command, listargs, server, port )( function )

Returns: object in the category IsProcess

command and server are strings, listargs is a list of GAP objects and port is an integer. Calls the SCSCP procedure with the name command and the list of arguments listargs at the server and port given by server and port. Returns an object in the category IsProcess for the subsequent waiting the result from its underlying stream.

It accepts the following options:

See CompleteProcess (6.1-3) and EvaluateBySCSCP (6.1-4) for examples.

6.1-3 CompleteProcess
> CompleteProcess( process )( function )

Returns: record with components object and attributes

The function waits, if necessary, until the underlying stream of the process will contain some data, then reads the appropriate OpenMath object from this stream and closes it.

It has the option output which may have two values:

In the following example we demonstrate combination of the two previous functions to send request and get result, calling the procedure WS_Factorial, installed in the previous chapter:


gap> s := NewProcess( "WS_Factorial", [10], "localhost", 26133 );                  
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
< process at localhost:26133 pid=6543 >
gap> x := CompleteProcess(s);
rec( object := "3628800", attributes := [ [ "call_id", "localhost:26133:6543" ] ] )

See more examples in the description of the function EvaluateBySCSCP (6.1-4), which combines the two previous functions by sending request and getting result in one call.

6.1-4 EvaluateBySCSCP
> EvaluateBySCSCP( command, listargs, server, port )( function )

Returns: record with components object and attributes

command and server are strings, listargs is a list of GAP objects and port is an integer. Calls the SCSCP procedure with the name command and the list of arguments listargs at the server and port given by server and port.

Since EvaluateBySCSCP combines NewProcess (6.1-2) and CompleteProcess (6.1-3), it accepts all options which may be used by that functions ( output, cd and debuglevel ) with the same meanings.


gap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message
#I  Requesting version 1.3 from the server ...
#I  Server confirmed version 1.3 to the client ...
#I  Request sent ...
#I  Waiting for reply ...
rec( attributes := [ [ "call_id", "localhost:26133:2442:6hMEN40d" ] ], 
     object := 3628800 )
gap> SetInfoLevel(InfoSCSCP,0);
gap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133 : output:="cookie" ); 
rec( attributes := [ [ "call_id", "localhost:26133:2442:jNQG6rml" ] ], 
  object := < remote object TEMPVarSCSCP@localhost:26133 > )
gap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133 : output:="nothing" );
rec( attributes := [ [ "call_id", "localhost:26133:2442:9QHQrCjv" ] ], 
  object := "procedure completed" )

Now we demonstrate the procedure GroupIdentificationService, also given in the previous chapter:


gap> G:=SymmetricGroup(4);
Sym( [ 1 .. 4 ] )
gap> gens:=GeneratorsOfGroup(G);
[ (1,2,3,4), (1,2) ]
gap> EvaluateBySCSCP( "GroupIdentificationService", [ gens ],
>                     "localhost", 26133 : debuglevel:=3 ); 
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message
#I  Requesting version 1.3 from the server ...
#I  Server confirmed version 1.3 to the client ...
#I  Request sent ...
#I  Waiting for reply ...
rec( attributes := [ [ "call_id", "localhost:26133:2442:xOilXtnw" ], 
      [ "info_runtime", 6 ], [ "info_memory", 670175232 ], 
      [ "info_message", "Memory usage for the result is 24 bytes" ] ], 
  object := [ 24, 12 ] )

Service provider may suggest to the client to use a counterpart function


IdGroupWS:=function( G )
local H, result;
if not IsPermGroup(G) then
  H:= Image( IsomorphismPermGroup( G ) );
else
  H := G;
fi;  
result := EvaluateBySCSCP ( "GroupIdentificationService", 
            [ GeneratorsOfGroup(H) ], "localhost", 26133 );
return result.object;
end;

which works exactly like IdGroup (Reference: IdGroup):


gap> G:=DihedralGroup(64);
<pc group of size 64 with 6 generators>
gap> IdGroupWS(G);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
[ 64, 52 ]

6.1-5 TerminateProcess
> TerminateProcess( process )( function )

The function is supposed to send an "out-of-band" interrupt signal to the server. Current implementation works only when the server is running as "localhost" by sending a SIGINT to the server using its PID contained in the process. It will do nothing if the server is running remotely, as the SCSCP specification allows the server to ignore interrupt messages. Remote interrupts will be introduced in one of the next versions of the package.

6.2 Remote objects

The SCSCP package introduces new kind of objects - remote objects. They provide an opportunity to manipulate with objects on remote services without their actual transmitting over the network. Remote objects store the information that allows to access the original object: the server name and the port number through which the object can be accessed, and the variable name under which it is stored in the remote system. Two remote objects are equal if and only if all these three parameters coincide.

There are two types of remote object which differ by their lifetime:

First we show the example of the temporary remote object in a session. The procedure PointImages returns the set of images of a point i under the generators of the group G. First we create the symmetric group S_3 on the client and store it remotely on the server (call 1), then we compute set of images for i=1,2 (calls 2,3) and finally demonstrate that we may retrieve the group from the server (call 4):


gap> stream:=InputOutputTCPStream( "localhost", 26133 );
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
< input/output TCP stream to localhost:26133 >
gap> StartSCSCPsession(stream);
#I  Got connection initiation message
#I  Requesting version 1.3 from the server ...
#I  Server confirmed version 1.3 to the client ...
"localhost:26133:6184"
gap> OMPutProcedureCall( stream, "store_session", 
>       rec( object := [ SymmetricGroup(3) ], 
>        attributes := [ [ "call_id", "1" ], 
>                        ["option_return_cookie"] ] ) );
true
gap> SCSCPwait( stream );
gap> G:=OMGetObjectWithAttributes( stream ).object;
< remote object TEMPVarSCSCPoS5nhta3@localhost:26133 >
gap> OMPutProcedureCall( stream, "PointImages", 
>       rec( object := [ G, 1 ], 
>        attributes := [ [ "call_id", "2" ] ] ) );
true
gap> SCSCPwait( stream );
gap> OMGetObjectWithAttributes( stream );
rec( attributes := [ [ "call_id", "2" ] ], object := [ 2 ] )
gap> OMPutProcedureCall( stream, "PointImages", 
>       rec( object := [ G, 2 ], 
>        attributes := [ [ "call_id", "3" ] ] ) );
true
gap> SCSCPwait( stream );
gap> OMGetObjectWithAttributes( stream );
rec( attributes := [ [ "call_id", "3" ] ], object := [ 1, 3 ] )
gap> OMPutProcedureCall( stream, "retrieve", 
>       rec( object := [ G ], 
>        attributes := [ [ "call_id", "4" ] ] ) );
true
gap> SCSCPwait( stream );
gap> OMGetObjectWithAttributes( stream );
rec( attributes := [ [ "call_id", "4" ] ], 
  object := Group([ (1,2,3), (1,2) ]) )
gap> CloseStream(stream);

After the stream is closed, it is no longer possible to retrieve the group G again or use it as an argument.

Thus, the usage of remote objects existing during a session reduces the network traffic, since we pass only references instead of actual OpenMath representation of an object. Also, the remote object on the server may accumulate certain information in its properties and attributes, which may not be included in it default OpenMath representation.

Now we show remote objects which remain alive after the session is closed. Such remote objects may be accessed later, for example, by:

6.2-1 StoreAsRemoteObjectPersistently
> StoreAsRemoteObjectPersistently( obj, server, port )( function )
> StoreAsRemoteObject( obj, server, port )( function )

Returns: remote object

Returns the remote object corresponding to the object created at server:port from the OpenMath representation of the first argument obj. The second form is just a synonym.


gap> s:=StoreAsRemoteObject( SymmetricGroup(3), "localhost", 26133 );
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
< remote object TEMPVarSCSCP@localhost:26133 >

Internally, the remote object carries all the information which is required to get access to the original object: its identifier, server and port:


gap> s![1]; 
"TEMPVarSCSCP"
gap> s![2];
"localhost"
gap> s![3];
26133

When the remote object is printed in the OpenMath format, we use symbols @ and : to combine these parameters in the OpenMath reference:


gap> OMPrint(s);
<OMOBJ>
	<OMR xref="TEMPVarSCSCP@localhost:26133" />
</OMOBJ>

This allows substitution of remote object as arguments into procedure calls in the same manner like we do this with usual objects:


gap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133);  
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
rec( object := [ 6, 1 ], attributes := [ [ "call_id", "localhost:26133:6726" ] ] )

6.2-2 IsRemoteObject
> IsRemoteObject( filter )

This is the category of remote objects.

6.2-3 RemoteObjectsFamily
> RemoteObjectsFamily( family )

This is the familty of remote objects.

6.2-4 RetrieveRemoteObject
> RetrieveRemoteObject( remoteobject )( function )

Returns: object

This function retrieves the remote object from the remote service in the OpenMath format and constructs it locally. Note, however, that for a complex mathematical object its default OpenMath representation may not contain all information about it which was accumulated during its lifetime on the SCSCP server.


gap> RetrieveRemoteObject(s);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
Group([ (1,2,3), (1,2) ])

6.2-5 UnbindRemoteObject
> UnbindRemoteObject( remoteobject )( function )

Returns: true or false

Removes any value currently bound to the global variable determined by remoteobject at the SCSCP server, and returns true or false dependently on whether this action was successful or not.


gap> UnbindRemoteObject(s);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
true

Finally, we show an example when first we create a group on the service running on port 26133, and then identify it on the service running on port 26134. Instead of transmitting the group to the client and then sending it as an argument to the second service, the latter service directly retrieves the group from the first service.


gap> s:=StoreAsRemoteObject( SymmetricGroup(3), "localhost", 26133 );
< remote object TEMPVarSCSCP@localhost:26133 >
gap> EvaluateBySCSCP( "WS_IdGroup", [ s ], "localhost", 26134 );
rec( object := [ 6, 1 ], attributes := [ [ "call_id", "localhost:26134:7414" ] ] )


gap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133 : output:="cookie" );
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message 
#I  Request sent ...
#I  Waiting for reply ...
rec( object := < remote object TEMPVarSCSCP2@localhost:26133 >, 
  attributes := [ [ "call_id", "localhost:26133:7328" ] ] )

 Top of Book   Previous Chapter   Next Chapter 
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 Bib Ind

generated by GAPDoc2HTML