digraph SMPAgent { graph [fontname=arial] node [fontname=arial fontsize=11 shape=box] edge [fontname=arial fontsize=10 arrowhead=open arrowtail=open] main [shape=hexagon color=orange label="main\nthread"] aSock [label="user agent TCP socket" color=darkgreen] subgraph clusterPersistence { graph [fontsize=11 color=gray] label="persistence (sqlite)" connectionsStore [shape=cylinder label="duplex connections,\nSMP queues,\nrecent messages"] } subgraph clusterAgent { graph [color=gray] node [shape=hexagon color=orange] label="agent threads" connectClnt runClnt } main -> {runClnt connectClnt} [style=dashed label="race" color=orange fontcolor=orange] aSock -> connectClnt [color=darkgreen] subgraph clusterUserTCP { graph [color=gray] label="1 group per user TCP connection" uSock [label="user connection TCP socket" color=darkgreen] subgraph clusterUserTCPThreads { graph [fontsize=11 color=gray] label="user TCP threads" node [shape=hexagon, color=orange] uRcv [label="user\nreceive"] uSnd [label="user\nsend"] } uSock -> uRcv [color=darkgreen] uSnd -> uSock [color=darkgreen] } subgraph clusterUser { graph [color=gray] label="1 group per user TCP connection" subgraph clusterUserInterface { graph [fontsize=11] label="user queues" uInq [shape=rarrow label="user\nreceive\nTBQueue"] uOutq [shape=larrow label="user\nsend\nTBQueue"] } subgraph clusterUserThreads { graph [fontsize=11] label="user threads\nNote: `user agent` sends\nall commands to `commands TBQueue`s\n(invalid commands with attached responses),\nand only valid commands to `server TBQueue`.\nIt is used to respond in correct order." node [shape=hexagon, color=orange] uAgent [label="user\nagent"] uProcess [label="process\nresponses"] } uRcv -> uInq -> uAgent [color=darkgreen] uProcess -> uOutq -> uSnd [color=darkgreen] {uRcv uAgent} -> uOutq [color=green] uRespq [shape=rarrow label="user\nSMP\nTBQueue"] subgraph clusterClient { label="1 group per SMP client/server connection" runClient [shape=hexagon, color=orange] sOutq [shape=rarrow label="srv send\nTBQueue"] sSock [label="SMP client connection TCP socket" color=blue] subgraph clusterServerThreads { graph [fontsize=11] label="SMP client threads" node [shape=hexagon, color=orange] sAgent [label="server\nreceive"] sSnd [label="server\nsend"] } runClient -> {sAgent sSnd} [style=dashed label=race color=orange fontcolor=orange] {uAgent uProcess} -> sOutq -> sSnd -> sSock -> sAgent [color=blue] } userState [label="connected\nservers,\nsubscribed\nqueues,\nsent\ncommands\n(STM)" shape="folder"] {uAgent uProcess} -> userState [dir=both color="#FF8888"] {uAgent uProcess} -> connectionsStore [dir=both color="#880000"] connectClnt -> uSock [style=dashed label="connect" color=darkgreen fontcolor=darkgreen] connectClnt -> {uRcv uSnd} [style=dashed label="race" color=orange fontcolor=orange] runClnt -> {uAgent uProcess} [style=dashed label="race" color=orange fontcolor=orange] sAgent -> uRespq -> uProcess uAgent -> runClient [style=dashed label="fork" color=orange fontcolor=orange] } }