digraph G { size="7.5,10" labeljust="l" fontname=Helvetica; node [fontname=Helvetica] edge [fontname=Helvetica,fontsize=10] subgraph cluster0 { label="Datastore layer: Syncer goroutine"; Syncer [shape=box] Syncer -> SyncerCallbacks [label="typed KVs"] SyncerCallbacks [label=<
Syncer callbacks API
Interface to frontend.

OnStatusUpdated(status SyncStatus)
OnUpdates(updates []KVPair)
>, shape=none, margin=0]; SyncerCallbacks -> SyncerCallbacksDecoupler [penwidth=5]; SyncerCallbacksDecoupler [label=<
SyncerCallbacksDecoupler
Decouples SyncerCallbacks via channel.
>, shape=none, margin=0]; } subgraph cluster1 { label="Calculation layer: Validation goroutine"; SyncerCallbacksDecoupler -> ValidationFilter [label="<>" penwidth=5]; ValidationFilter [label=<
ValidationFilter struct
Runs validation on values.
>, shape=none, margin=0] ValidationFilter -> AsyncCalcGraph [label="SyncerCallbacks", penwidth=5] } AsyncCalcGraph [label=<
AsyncCalcGraph struct
Puts updates on channel
>, shape=none, margin=0] AsyncCalcGraph -> AsyncCalcGraph2 [label="<>\nSyncStatus and []KVPair", penwidth=5] subgraph cluster2 { label="Calculation layer: graph processing goroutine"; AsyncCalcGraph2 [label=<
AsyncCalcGraph struct
Converts channel back to method calls.
Flushes event buffer after each dispatch.
>, shape=none, margin=0] AsyncCalcGraph2 -> Dispatcher [penwidth=5] AsyncCalcGraph2 -> EventBuffer [label="Rate-limited\nFlush()"] subgraph { /* Put some padding either side of the Dispatcher. */ rank=same; nodepadding1; Dispatcher; nodepadding2; nodepadding1 [style=invisible,fixedsize=true,width=4] nodepadding2 [style=invisible,fixedsize=true,width=4] nodepadding1 -> Dispatcher [style=invis]; Dispatcher -> nodepadding2 [style=invis]; } Dispatcher [label=<
Dispatcher
Fans out updates by type
>, shape=none, margin=0] Dispatcher -> PolicyResolver [label="policy, tier\nKVs", penwidth=2] Dispatcher -> ActiveRulesCalc [label="policy, profile\nKVs", penwidth=2] Dispatcher -> LocalDispatcher [label="all\nendpoint KVs", penwidth=4]; Dispatcher -> MemberCalc [label="all\nendpoint KVs", penwidth=4]; Dispatcher -> ConfigBatcher [label="config KVs", penwidth=2]; LocalDispatcher [label=<
Local endpoint dispatcher
Filters out non-local endpoints.
>, shape=none, margin=0] LocalDispatcher -> ActiveRulesCalc [label="local\nendpoint KVs", penwidth=2]; LocalDispatcher -> PolicyResolver [label="local\nendpoint KVs", penwidth=2] ConfigBatcher [label=<
Config batcher
Combines individual config keys
into consistent snapshots.
>, shape=none, margin=0] ConfigBatcher -> PipelineCallbacks [label="OnConfigUpdate()"] ActiveRulesCalc [label=<
Active rules calculator
Calculates which policies/profiles are
active on this host.
>, shape=none, margin=0]; ActiveRulesCalc -> RuleScanner [label="active rule\nupdates"]; ActiveRulesCalc -> PolicyResolver [label="policy match\nupdates"]; "<>" [shape=none] RuleScanner [label=<
Rule scanner
Scans rules, extracts selectors/named ports.
Calculates IP set IDs.
>, shape=none, margin=0]; PolicyResolver [label=<
Policy resolver
Calculates the active policies
for each active endpoint.
>, shape=none, margin=0]; MemberCalc [label=<
IP set member index
Combines profile labels with endpoint labels;
indexes labels against selectors;
calculates the IP/port memberships of IP sets;
handles de-dupe of members.
>, shape=none, margin=0]; RuleScanner -> PipelineCallbacks [label="OnPolicy(In)Active()\nOnProfile(In)Active()"]; RuleScannerShim [label="<>", shape=none] RuleScanner -> RuleScannerShim [label="Selector/Named port\n(in)active"]; RuleScannerShim -> MemberCalc [label="Selector/Named port\nupdates"] RuleScannerShim -> PipelineCallbacks [label="OnIPSetAdded/Removed()"]; MemberCalc -> "<>" [label="OnIPSetMemberAdded/Removed()"]; "<>" -> PipelineCallbacks [label="OnIPSetMemberAdded/Removed()"]; PolicyResolver -> PipelineCallbacks [label="Endpoints+policies\nOnEndpointTierUpdate()"]; PipelineCallbacks [label=<
Pipeline callbacks API
Interface to frontend.

OnIPSetAdded(setID string, ipSetType proto.IPSetUpdate_IPSetType)
OnIPSetMemberAdded(setID string, ip labelindex.IPSetMember)
OnIPSetMemberRemoved(setID string, ip labelindex.IPSetMember)
OnIPSetRemoved(setID string)

OnPolicyActive(model.PolicyKey, *proto.Rules)
OnPolicyInactive(model.PolicyKey)
OnProfileActive(model.ProfileRulesKey, *proto.Rules)
OnProfileInactive(model.ProfileRulesKey)

OnEndpointTierUpdate(endpointKey model.Key,

OnConfigUpdate(globalConfig, hostConfig map[string]string) endpoint interface{},
filteredTiers []endpoint.TierInfo)
>, shape=none, margin=0]; PipelineCallbacks -> EventBuffer [label="<>"] EventBuffer [label=<
Event sequencer
Batches/coalesces IP set updates;
converts to protobuf structs;
does dependency sequencing.
>, shape=none, margin=0]; } subgraph cluster3 { label="Dataplane layer: writer goroutine"; DataplaneConnection [label=<
Dataplane connection
Marshals messages to/from Dataplane.
>, shape=none, margin=0]; } EventBuffer -> DataplaneConnection [label="<>\nproto.XYZUpdate protobuf structs", penwidth=2] DataplaneConnection -> Dataplane [label="protobuf"]; Dataplane [shape=box, label="Dataplane driver"]; }