Basic TCP:
ITCPConnection implemented by AsyncTCPConnection_APM is the innermost class resposinsble for TCP sends and received. Its used 
on both client and server symmetrically. All the hard async send/receive logic is there.
AsyncTCPConnectionAcceptor_APM opens a port and listens and accepts to connections from the client. It creates the ITCPConnection
on the server.
AsyncTCPConnector_APM connects to the server (above) and creates an ITCPConnection on the client side.

IPubSubServerConnection:
All communication to PubSubServer happens using this. It has 3 main types of calls:
1. send: to asyncronoulsy end data
2. get data: either through a polling call or callback
3. get connection info: through callbacks

The only implementation of the above is PubSubServerManagedTCPConnection
(there used to be an MSMQ one and another wrapped around native code - but neither exists anymore)

PubSubMessages:
PubSubClientMessage is the only messages thats sent from client to pubsubserver. Its serialized on the
client and sent over to the pubsubserver, where uints received ad deserialized

SubscriberCore:ISubscriberCore (retired now)
|
V
SingleServerSubscriberCore:ISingleServerSubscriberCore

PublisherCore:IPublisherCore (transactions not supported for now), keeps AllPublishedTagState to cache state on the publisher
|
V
IPubSubServerConnection

PubSubServer:
PubSubMessageReactor (top level, called from main), contain PubSubState (which has all data and connection state)
ManagedTCPMessageHub : IPubsubMessageHub (this is what handles each ITCPConnection for each connection)

PubSubState keeps the total pubsub data in 2 classes
Dictionary<string, SingleTagData> and 
Dictionary<string, SingleTagConnectionData>
SingleTagData has the tag and IPubSubServerTagHandler (or byte[]) (IPubSubServerTagHandler holds the data state)
for streams the IPubSubServerTagHandler is the PubsubServerTagHandler, which is designed for multiple tags and has a IDictionary<string, TagStateBank>
TagStateBank containes the PubsubDeserial izationController, which knows how to deserialize the stream publishes and build state, ad simialirly produce the state on demand
PubsubTagHandlerFactory returns a IPubSubServerTagHandler for each tag, called by the server state handler, SingleTagData and publisher tag state, AllPublishedTagState

SingleTagConnectionData contains connection vs sub, and connection vs pub
PubSubState calls
SystemSubscriptionMapPublisher.init(this);
SystemStatsPublisher.init(this);
SystemHeartbeatPublisher.init();
---------------------------------------------------------------
How internal tags are published?
There are 3 internal publishers (ie compute somerthing an dpublish tit PubSubServer, such that clients can subscribe to it):
SystemStatsPublisher, SystemSubscriptionMapPublisher and SystemHeartbeatPublisher
These are somewhat tricky because they are both listeners to PubUsbState event and intrnally publish, but are also IPubSubServerTagHandler
SystemSubscriptionMapPublisher:
just one instance, a static init is called by PubSubState and it passes itself. SystemSubscriptionMapPublisher subscribes to the event
gets the affected tags, marks them dirty, in doWork creates the state and calls the internal_publish.
Now, as the result of an internal_publish (which is pretty much like a rmote publish as far as the PubsubServer is concerned), SingleTagData
ends up calling SystemSubscriptionMapPublisher (since it also serves as the tagHandler for the tag it publishes via internal_publish)



PubSubState has onPublishStats (tag, sz) that is fired on update_pub_data
onPublishStats is subscribed by SystemStatsPublisher
SystemStatsPublisher.onPublishStats updates the state and on the next doWork calls PubSubMessageReactor.internal_send
SystemStatsPublisher is also an IPubSubServerTagHandler so SingleTagData calls it getContent to get full state

Streams:
PubTableBroker allows publishing of streams through createTable, addRow, deleteRow, changeRow, makeBatchChanges ->
PubTablePublisher:IPubTablePublisher per tag (addRow, deleteRow, changeRow, createTable, batchRemoveAdd)
PubTablePublisher has BlueDataSerializationController:IBlueDataSerializer to serialize the rows to byte[]
BlueDataSerializationController uses a IBlueDataSerializer, which is specialized for the tag (using UniversalSerializer for now)

IBlueDataSerializer has just one function
void serialize (byte op, IBlueRowCollection[] rows, out byte[] serializedData);
the second arg is IBlueRowCollection[] because in case of op = StreamOpCode.multipleRemoveAdd, it has multiple IBlueRowCollection for rem and add
(BlueDataSerializer.serialize's comment has the serialization layout)

For each serializer we have 2 matching deserializers, IPubsubDeserializer (for PubSubservr) and IClientDeserializer (for clients subscribing to streams)
For UniversalSerializer, we have PubsubUniversalDeserializer and ClientUniversalDeserializer

-------------------------------------------------------------------
TCP publishing:
To run the base TCP layer run PubSubServer as an echo server, 
(set run_echo_tcp_server_only in spark\src\DataStreamSuite\PubSubServer\Program.cs)
to run a client that sends a tcp message tot he echo server, run 
SimpleTCPEchoStream


Pubsub publishing:
-----------------
PubSubTestingStream (bounces pubs across the pubsub server)
mutableAppend(pubSubTesting(100,10000000,100000,"test_1"),
pubSubTesting(250,10000000,100000,"test_2"))


Stream publishing:
------------------
PublisherStream (publishes any stream to the pubsubserver)
r=second(100)
r=project(r,"id")
r=math(r,"x = id*id")
publisher(r, "test_x")


tracking message into the pubsubserver
--------------------------------------
connection:
ServerToClientManagedTCPConnectionAcceptor._on_accept
 var log_msg = $"ServerToClientManagedTCPConnectionAcceptor._on_accept called port: {_port} state: {res.AsyncState}";
         Log.Gen.info(log_msg);

data:
ManagedTCPMessageHub.onData
bts.Log.Gen.info($"ManagedTCPMessgageHub.onData recv msg: {message}");
PubSubMessageReactor._polling_thread_func
bts.Log.Gen.info($"PubSubMessageReactor._polling_thread_func n_msgs: {n_msgs}");
PubSubMessageReactor._handle_client_msg
bts.Log.Gen.info($"PubSubMessageReator._handle_client_msg ps_client_msg: {ps_client_msg}");
