File: client.xml

package info (click to toggle)
gap-scscp 2.2.3%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,696 kB
  • sloc: xml: 1,226; sh: 388; makefile: 19
file content (402 lines) | stat: -rw-r--r-- 14,206 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
<Chapter Label="ClientFunctionality">
<Heading>Client's functionality</Heading>    

Sending and getting requests to the &SCSCP; server(s),
the client operates with processes. Process is an abstraction 
which in other words may be also called a remote task. It encapsulates
an input/output TCP stream (see <Ref Filt="IsInputOutputTCPStream" />) 
from the 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).
<P/>
There are two ways to create processes. One of them is to specify
the hostname and port where the &SCSCP; server is running; in this 
case a new input/output TCP stream will be created. Another way is 
first to establish the connection with the &SCSCP; server using
<Ref Func="NewSCSCPconnection" /> and then keep it alive across
multiple remote procedure calls, thus saving time on the DNS lookup 
and connection initiation. This may give a good speedup in computations
with an intensive message exchange. Note that as long as such connection
is open, other &SCSCP; clients will not be able to get through, so
if several clients are interchanging with the &SCSCP; server at the 
same time, they should not block each other with long-lasting connections.


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="SCSCP Connections">
<Heading>&SCSCP; connections</Heading>

<#Include Label="IsSCSCPconnection"/>
<#Include Label="NewSCSCPconnection"/>
<#Include Label="CloseSCSCPconnection"/>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="Client">
<Heading>Processes</Heading>

<#Include Label="IsProcess"/>
<#Include Label="NewProcess"/>
<#Include Label="CompleteProcess"/>
<#Include Label="TerminateProcess"/>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="All-in-one">
<Heading>All-in-one tool: sending request and getting result</Heading>

<#Include Label="EvaluateBySCSCP"/>

Now we demonstrate the procedure <C>GroupIdentificationService</C>,
also given in the previous chapter:

<Example>
<![CDATA[
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 ); 
rec( attributes := [ [ "call_id", "localhost:26133:2442:xOilXtnw" ], 
      [ "info_runtime", 4 ], [ "info_memory", 2596114432 ], 
      [ "info_message", "Memory usage for the result is 48 bytes" ] ], 
  object := [ 24, 12 ] )
]]>
</Example>

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

<Example>
<![CDATA[
gap> 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;;
]]>
</Example>

which works exactly like <Ref BookName="ref" Func="IdGroup" />:

<Example>
<![CDATA[
gap> G:=DihedralGroup(64);
<pc group of size 64 with 6 generators>
gap> IdGroupWS(G);
[ 64, 52 ]
]]>
</Example>

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="BinaryVsXML">
<Heading>Switching between Binary and XML &OpenMath; Encodings</Heading>

<#Include Label="SwitchSCSCPmodeToBinary"/>

For example, let us create a vector over <M>GF(3)</M>:
<Example>
<![CDATA[
gap> x := [ Z(3)^0, Z(3), 0*Z(3) ];
[ Z(3)^0, Z(3), 0*Z(3) ]
]]>
</Example>
The XML &OpenMath; encoding of such objects is quite bulky:
<Example>
<![CDATA[
gap> OMString( x );
"<OMOBJ xmlns=\"http://www.openmath.org/OpenMath\" version=\"2.0\"> <OMA> <OMS\
 cd=\"list1\" name=\"list\"/> <OMA> <OMS cd=\"arith1\" name=\"power\"/> <OMA> \
<OMS cd=\"finfield1\" name=\"primitive_element\"/> <OMI>3</OMI> </OMA> <OMI>0<\
/OMI> </OMA> <OMA> <OMS cd=\"arith1\" name=\"power\"/> <OMA> <OMS cd=\"finfiel\
d1\" name=\"primitive_element\"/> <OMI>3</OMI> </OMA> <OMI>1</OMI> </OMA> <OMA\
> <OMS cd=\"arith1\" name=\"times\"/> <OMA> <OMS cd=\"finfield1\" name=\"primi\
tive_element\"/> <OMI>3</OMI> </OMA> <OMI>0</OMI> </OMA> </OMA> </OMOBJ>"
gap> Length( OMString(x) );
507
]]>
</Example>
We call the &SCSCP; procedure <C>Identity</C> just to test how this object
may be sent back and forth. The total length of the procedure call message
is 969 symbols:
<Log>
<![CDATA[
gap> SetInfoLevel(InfoSCSCP,3);
gap> EvaluateBySCSCP("Identity",[x],"localhost",26133);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message
#I  <?scscp service_name="GAP" service_version="4.dev" service_id="localhost:2\
6133:42448" scscp_versions="1.0 1.1 1.2 1.3" ?>
#I  Requesting version 1.3 from the server ...
#I  Server confirmed version 1.3 to the client ...
#I  Composing procedure_call message: 
<?scscp start ?>
<OMOBJ xmlns="http://www.openmath.org/OpenMath" version="2.0">
  <OMATTR>
    <OMATP>
      <OMS cd="scscp1" name="call_id"/>
      <OMSTR>localhost:26133:42448:IOs9ZkBU</OMSTR>
      <OMS cd="scscp1" name="option_return_object"/>
      <OMSTR></OMSTR>
    </OMATP>
    <OMA>
      <OMS cd="scscp1" name="procedure_call"/>
      <OMA>
        <OMS cd="scscp_transient_1" name="Identity"/>
          <OMA>
            <OMS cd="list1" name="list"/>
            <OMA>
            <OMS cd="arith1" name="power"/>
            <OMA>
              <OMS cd="finfield1" name="primitive_element"/>
              <OMI>3</OMI>
            </OMA>
            <OMI>0</OMI>
          </OMA>
          <OMA>
            <OMS cd="arith1" name="power"/>
            <OMA>
              <OMS cd="finfield1" name="primitive_element"/>
              <OMI>3</OMI>
            </OMA>
            <OMI>1</OMI>
          </OMA>
          <OMA>
            <OMS cd="arith1" name="times"/>
            <OMA>
              <OMS cd="finfield1" name="primitive_element"/>
              <OMI>3</OMI>
            </OMA>
            <OMI>0</OMI>
          </OMA>
        </OMA>
      </OMA>
    </OMA>
  </OMATTR>
</OMOBJ>
<?scscp end ?>
#I  Total length 969 characters 
...
rec( attributes := [ [ "call_id", "localhost:26133:42448:IOs9ZkBU" ] ], 
  object := [ Z(3)^0, Z(3), 0*Z(3) ] )
  ]]>
</Log>
Now we switch to binary mode:
<Log>
<![CDATA[
gap> SwitchSCSCPmodeToBinary();
gap> EvaluateBySCSCP("Identity",[x],"localhost",26133);
#I  Creating a socket ...
#I  Connecting to a remote socket via TCP/IP ...
#I  Got connection initiation message
#I  <?scscp service_name="GAP" service_version="4.dev" service_id="localhost:2\
6133:42448" scscp_versions="1.0 1.1 1.2 1.3" ?>
#I  Requesting version 1.3 from the server ...
#I  Server confirmed version 1.3 to the client ...
#I  Composing procedure_call message: 
3C3F7363736370207374617274203F3E0A18121408060773637363703163616C6C5F6964061E6C\
6F63616C686F73743A32363133333A34323434383A3256675A5562755A0806147363736370316F\
7074696F6E5F72657475726E5F6F626A6563740600151008060E73637363703170726F63656475\
72655F63616C6C1008110873637363705F7472616E7369656E745F314964656E74697479100805\
046C697374316C69737410080605617269746831706F7765721008091166696E6669656C643170\
72696D69746976655F656C656D656E7401031101001110080605617269746831706F7765721008\
091166696E6669656C64317072696D69746976655F656C656D656E740103110101111008060561\
726974683174696D65731008091166696E6669656C64317072696D69746976655F656C656D656E\
7401031101001111111113193C3F736373637020656E64203F3E0A
#I  Total length 339 bytes 
#I  Request sent ...
#I  Waiting for reply ...
#I  <?scscp start ?>
#I  Got back: object [ Z(3)^0, Z(3), 0*Z(3) ] with attributes 
[ [ "call_id", "localhost:26133:42448:2VgZUbuZ" ] ]
rec( attributes := [ [ "call_id", "localhost:26133:42448:2VgZUbuZ" ] ], 
  object := [ Z(3)^0, Z(3), 0*Z(3) ] )
gap> SetInfoLevel(InfoSCSCP,3);
]]>
</Log>
As we can see, the size of the message is almost three times shorter, and
this is not the limit. Switching to binary &OpenMath; encoding in 
combination with pickling and unpickling from &IO; package (see in the last
Chapter) and special methods for pickling compressed vectors implemented
in the <Package>Cvec</Package> available in &GAP;&nbsp;4.5 allow to 
dramatically reduce the overhead for vectors and matrices over finite
fields, making a roundtrip up to a thousand times faster. 

</Section>


<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->

<Section Label="Remote">
<Heading>Remote objects</Heading>

The &SCSCP; package introduces new kind of objects - <E>remote objects</E>.
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.
<P/>

There are two types of remote object which differ by their lifetime: 
<List>
<Item>temporary remote objects which exist only within a single session;</Item>
<Item>persistent remote objects which stay alive across multiple sessions.</Item>
</List>

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

<Example>
<![CDATA[
gap> stream:=InputOutputTCPStream( "localhost", 26133 );
< input/output TCP stream to localhost:26133 >
gap> StartSCSCPsession(stream);
"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 scscp://localhost:26133/TEMPVarSCSCPo3Bc8J75 >
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);
]]>
</Example>

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

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.
<P/>

Now we show remote objects which remain alive after the session is
closed. Such remote objects may be accessed later, for example, by:
<List>
<Item>subsequent procedure calls from the same instance of &GAP; or another system;</Item>
<Item>other instances of &GAP; or another systems (if the identifier of an object is known)</Item>
<Item>another &SCSCP; servers which obtained a reference to such object as an argument of a procedure call.</Item>
</List>

<#Include Label="StoreAsRemoteObject"/>

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

<Example>
<![CDATA[
gap> s![1]; 
"TEMPVarSCSCPLvIUUtL3"
gap> s![2];
"localhost"
gap> s![3];
26133
]]>
</Example>

When the remote object is printed in the &OpenMath; format, we
use symbols <C>@</C> and <C>:</C> to combine these parameters
in the &OpenMath; reference:

<Example>
<![CDATA[
gap> OMPrint(s);
<OMOBJ>
      <OMR href="scscp://localhost:26133/TEMPVarSCSCPLvIUUtL3" />
</OMOBJ>
]]>
</Example>

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

<Example>
<![CDATA[
gap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133);  
rec( attributes := [ [ "call_id", "localhost:26133:52918:Viq6EWBP" ] ],
Line 183 : 
  object := [ 6, 1 ] )
]]>
</Example>

<#Include Label="IsRemoteObject"/>
<#Include Label="RemoteObjectsFamily"/>
<#Include Label="RetrieveRemoteObject"/>
<#Include Label="UnbindRemoteObject"/>

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:
<Example>
<![CDATA[
gap> s:=StoreAsRemoteObject( SymmetricGroup(3), "localhost", 26133 );
< remote object scscp://localhost:26133/TEMPVarSCSCPNqc8Bkan >
gap> EvaluateBySCSCP( "WS_IdGroup", [ s ], "localhost", 26134 );
rec( object := [ 6, 1 ], attributes := [ [ "call_id", "localhost:26134:7414" ] ] )
]]>
</Example>
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:
<Example>
<![CDATA[
gap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133 : output:="cookie" );
rec( attributes := [ [ "call_id", "localhost:26133:52918:mRU6w471" ] ], 
  object := < remote object scscp://localhost:26133/TEMPVarSCSCPS9SVe9PZ > )
]]>
</Example>

</Section>

</Chapter>