Client Changes

There is one more method that a service can provide that RPC Manager uses during synchronization - GetClientChanges(). In the same way that the server instance builds an RPC package for execution on a client instance, the client instance can provide an RPC package for execution on the server. The RPC package from the client is executed after GetServerChanges() has been called. This ensures that any changes that result from the client instance’s RPC package being executed are not reflected in the RPC package generated by the server instance. Any changes in the synchronizable state of the service that result from executing the client instance-provided RPC package will cause normal service RPCs to be made to update all client instances.

It is uncommon for this facility to be required, however there are some circumstances in which it is necessary. The usual reason is where the client instance can operate independently from the server instance, if it loses the ability to communicate with the server instance.

It is essential for SetSyncComplete() to be called by the server instance, in the process of executing the RPC call stream that the client instance generated, just as it was essential for the client instance to call SetSyncComplete() during execution of the server generated RPC package. Once again, SetSyncComplete() can be called either by the last RPC subroutine in the package or the SetSyncComplete() can be embedded within the package.

The latter technique enables the RPC subroutines to be used other than for purely synchronization, by not embedding the SetSyncComplete() in an RPC subroutine. The following code demonstrates this:

<
{============================== GetClientChanges ===========================}
{ This module returns the changes seen on the client since the server was   }
{ last connected.                                                         }
{===========================================================================}
GetClientChanges
(
  PtrPackStream               { Pointer to var to receive changes           };
)

[
  Stream                      { Stream of changes to go to client           };
]

Only [
  If 1;
  [
    Stream = \RPCManager\PackRPC(Stream, "SomeRPC" { module },
                                 SvcName { scope  },
                                 { Parameters: } 69);
    Stream = \RPCManager\PackRPC(Stream, "SetSyncComplete" { module },
                                 "RPCManager" { scope  },
                                 { Parameters: } SvcName, Invalid, 1);
    *PtrPackStream = Stream;
    Slay(Self, 0);
  ]
]

{ End of GetClientChanges }
>

RPC subroutines that have a need to know whether they are being called via RPC or directly can determine this by comparing the current thread name against the name of the RPC Manager thread, as follows:

  IfThen (ThreadName(Self()) == "RPC",
    { Running on the RPC Manager thread }
  );