A MwsipcSession allows for synchronisation using DeltaRW/ROD messages of any number of working sets using a single stream oriented connection.
The set of working sets which can be synchronised over the connection is dynamic - i.e. it can change over the life of the session (this rules out directly using the multiplexing capabilities of the MultiplexedMsgConnection to multiplex messages across different working sets).
Working sets can be added/removed dynamically over the life of the session.
These functions can be called with or without locks on the CSpace of the working set. These functions have an asynchronous nature. They do not need to be paired.
There is a tendency for the last call to dominate previous calls. E.g. calling AddWorkingSet then RemoveWorkingSet for a given working set probably means it ends up being removed, however exactly what happens depends on the peer (which can also have called AddWorkingSet).
These functions must not be called after the associated MultiplexedMsgConnection has been closed.
$adt+ MwsipcSession
{
void AddWorkingSet(const TWorkingSetId& wsid, WorkingSetMachine* wsm);
void RemoveWorkingSet(const TWorkingSetId& wsid);
};
void AddWorkingSet(const TWorkingSetId& wsid, WorkingSetMachine* wsm)
Subject to various assumptions a call to AddWorkingSet()
eventually causes a working set to be
synchronised with the peer. The peer doesn't need to also call AddWorkingSet()
. If it does
that is fine, alternatively it can work passively and add a WorkingSetMachine
when requested
in its implementation of OnReceiveUnmatchedWorkingSetId().
An attempt to add a working set that is already being synchronised is not an error, the attempt to do so is simply ignored.
Note that the MwsipcSession does not take on responsibility for closing the given
WorkingSetMachine
. The given WorkingSetMachine
must not be closed until after the
MultiplexedMsgConnection is closed.
void RemoveWorkingSet(const TWorkingSetId& wsid)
Subject to various assumptions a call to RemoveWorkingSet() eventually stops the sending of messages both locally and remotely to synchronise a working set, but this can take some time to eventuate.
It is not necessary for the peer to also call RemoveWorkingSet() - syncing of a working set is stopped when either or both sides call RemoveWorkingSet().
It must not be assumed that the
WorkingSetMachine
can be closed after calling this function.
Currently the only safe thing to do is to close all the WorkingSetMachines after the
MultiplexedMsgConnection is closed.
RemoveWorkingSet() can be called safely on a working set that was never added and it can safely be called more than once on a given working set. The implementation simply ignores redundant calls to RemoveWorkingSet().
It is not necessary to remove all working sets before the MultiplexedMsgConnection is closed.
MwsipcSession* CreateMwsipcSession(
ptr<IMwsipcSessionHandler> handler, // Can be null
MultiplexedMsgConnection* c,
const WsipcSessionProtocolId& protocolId)
Performs the following:
The created MwsipcSession is concerned with supporting interactive collaboration, by sending and
receiving working set deltas on each WorkingSetMachine
. The protocol begins with an exchange of
datasetids, siteids and vector times for each WorkingSetMachine
.
It is expected that the peer will call the same function in order to set up their side of the connection.
Assumes the given MultiplexedMsgConnection has been created but OpenConnection() hasn't been called yet. After calling OpenConnection() the client will need to make a single call to NotifyMoreMessagesToWrite() in order to kick-start the message sending.
The given MultiplexedMsgConnection takes ownership of the returned MwsipcSession - i.e. the MwsipcSession is automatically deleted when the MultiplexedMsgConnection is closed.
WorkingSetMachines are pushed to the MwsipcSession by calling AddWorkingSet()
and pulled by the
MwsipcSession when it calls OnReceiveUnmatchedWorkingSetId() on the handler. In either case
it is very important not to close a WorkingSetMachine
until after the MultiplexedMsgConnection
has been closed.
MServer* CreateSimpleWsipcServer(
Iocp* iocp,
WorkingSetMachine* wsm,
const WsipcSessionProtocolId& protocolId,
SOCKET_PORT port,
const TcpSettings& tcpSettings = TcpSettings())
Create a server that listens on the given port
Returns NULL if server could not be created. A more specific windows error can be obtained with a call to GetLastError().
MClient* CreateSimpleWsipcClient(
Iocp* iocp,
WorkingSetMachine* wsm,
const WsipcSessionProtocolId& protocolId,
ConstStringZ hostname, SOCKET_PORT port,
const TcpSettings& tcpSettings = TcpSettings())
Create a client that tries to connect to the given host that is listening on the given port