Skip to content

Rework on public service discovery + ObserverDemo - #434

Open
KonradBreitsprecherBkd wants to merge 1 commit into
dev_public_service_discovery_capifrom
dev_public_service_discovery_observer
Open

KonradBreitsprecherBkd wants to merge 1 commit into
dev_public_service_discovery_capifrom
dev_public_service_discovery_observer

Conversation

@KonradBreitsprecherBkd

@KonradBreitsprecherBkd KonradBreitsprecherBkd commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Experimental Service Discovery: Extensions to the PoC

This branch extends the proof of concept of the public, experimental service discovery
(SilKit_Experimental_ServiceDiscovery_* in silkit/capi/Experimental.h, plus the C++ hourglass
SilKit::Experimental::ServiceDiscovery). It adds two things:

  1. A reworked service descriptor.
  2. Network-simulator links and pub/sub and RPC matches have their own kinds
    and are reported as removed.
  3. Each participant's operation mode and time synchronization are reported.
    Services carry stable ids, a typed bus type, and a flag for the initial snapshot.
  4. An observer demo (SilKitDemoObserver): a live terminal dashboard built only on that API.

1 - Service descriptor

What changed compared to the first PoC:

  • The catch-all SilKit_Experimental_ServiceKind_Link is replaced by the three link and match kinds.
  • Stable ids. serviceId / connectedServiceId identify services independently of their names. A match
    points directly at both of its endpoints.
  • Typed values. The bus type, operation mode and time synchronization are enums and booleans instead of
    strings in serviceName / primaryIdentifier.
  • Snapshot flag. On registration, the handler first receives every already known service as
    ServiceCreated with isSnapshot set, synchronously inside SetServiceDiscoveryHandler. Later events have
    it cleared. A consumer can thus show the existing simulation without treating it as a burst of changes.
  • Removed: simulationName, which was always empty, because services never carry the simulation name;
    only the VAsio peers do.

SilKit_Experimental_ServiceDescriptor (C) and SilKit::Experimental::ServiceDiscovery::ServiceDescriptor (C++):

Field Meaning
participantName owning participant; for a match the receiving side, for a netsim link the simulator
serviceName controller / publisher / subscriber / client / server name
serviceId id of the service within its participant (the wire EndpointId); with participantName a stable key
serviceKind see the table below
primaryIdentifier network name, topic or function name; empty for lifecycle and time sync services
networkType bus type (SilKit_Experimental_SimulatedNetworkType: CAN, LIN, Ethernet, FlexRay) of bus controllers and netsim links; Undefined otherwise
mediaType, labelList pub/sub and RPC only
operationMode LifecycleService only (SilKit_OperationMode); Invalid otherwise
timeSyncActive TimeSyncService only
connectedParticipantName, connectedServiceName, connectedServiceId matches only: the publisher / client
isSnapshot the service already existed when the handler was registered

Fields that don't apply to a kind are empty, zero, Undefined or Invalid.

Value Kind Receiving / owning side Connected side primaryIdentifier Kind-specific field
1-4 CanController, EthernetController, FlexrayController, LinController controller network name networkType
5, 6 DataPublisher, DataSubscriber publisher / subscriber topic
7, 8 RpcClient, RpcServer client / server function name
9 NetworkSimulatorLink simulating participant simulated network name networkType
10 PubSubMatch DataSubscriber DataPublisher topic
11 RpcMatch RpcServer RpcClient function name
12 LifecycleService participant operationMode
13 TimeSyncService participant timeSyncActive

2 - Links and matches

What changed

Previously, network-simulator links and pub/sub/RPC matches were all reported as Link. Consumers had to
work out the rest by convention:

  • An empty connectedParticipantName meant a network-simulator link.
  • Pub/sub vs. RPC was only known by looking up the kind of the receiving service from an earlier event.
  • A match was never reported as removed. Its removal had to be inferred from the ServiceRemoved of one of
    its endpoints.
  • The bus type of a simulated network was not available at all; it is now in networkType.

Now the kind alone says what a link or match is, and each is reported on both ServiceCreated and
ServiceRemoved. Pub/sub and RPC pairings are called matches, as in SIL Kit's matching of
publishers/subscribers and clients/servers. Link is kept for network simulators, which are internally
ServiceType::Link.

Guarantees

  • A PubSubMatch / RpcMatch exists only while both of its endpoints are known. It is reported as created
    after both endpoints were reported, and as removed before the first endpoint's ServiceRemoved.
  • A match is removed when its internal match endpoint goes away, or when either endpoint goes away,
    whichever comes first. It is reported as removed exactly once.
  • A match that was never reported (one endpoint was never known) produces no events.
  • A repeated internal announcement of the same match does not report the match twice.
  • NetworkSimulatorLink is reported on creation and removal of the simulated network. A simulated network is
    identified by its bus type and its name, just like the bus controllers on it.

Implementation (SilKit/source/capi/ServiceObserver.{hpp,cpp})

VSilKit::ServiceObserver turns the internal service-discovery events into the public ones:

  • Pending matches. Pub/sub and RPC matches are announced internally as DataSubscriberInternal /
    RpcServerInternal endpoints. Such an endpoint becomes a PubSubMatch / RpcMatch once the parent
    (subscriber/server) and the peer (publisher/client, identified by its UUID) are both known. Until then it
    waits in _pending.

  • Emitted matches. _emitted holds every match that was reported as created, keyed by
    (parent, peer UUID). Removals are taken from there:

    • by the internal endpoint's removal (HandleInternalMatch),
    • by the peer's removal (HandlePeer),
    • by the parent's removal (HandleParent).

    The match removals are emitted before the endpoint's own ServiceRemoved.

  • Network-simulator links. These are the internal ServiceType::Link descriptors. ClassifyAndFill
    maps them to NetworkSimulatorLink, and maps the internal network type to networkType
    (ToSimulatedNetworkType).

  • Snapshot flag. SilKit_Experimental_ServiceDiscovery_SetServiceDiscoveryHandler (CapiExperimental.cpp)
    remembers the registering thread while it calls RegisterServiceDiscoveryHandler. The internal service
    discovery replays the known services synchronously on that thread, under its lock. An invocation on that
    thread during the registration is therefore exactly a snapshot entry. The flag is applied to everything
    emitted for that event, including matches it resolves.

  • Handler calls. The handler is always invoked outside the observer's mutex.

3 - Operation mode and time synchronization

Each participant announces its lifecycle and time sync services internally when it calls StartLifecycle,
with the supplemental data keys LifecycleIsCoordinated (the operation mode) and TimeSyncActive. The
observer used to suppress them as infrastructure. Now it reports them as LifecycleService (with
operationMode) and TimeSyncService (with timeSyncActive).

Before StartLifecycle, neither is known. SIL Kit never announces that a participant has no lifecycle,
so consumers should treat a missing announcement as "unknown", not as "none".

4 - Observer demo (Demos/tools/Introspection)

SilKitDemoObserver joins a simulation and draws a live dashboard. It is also the reference consumer of
the API above:

  • It keys services, matches and links by participant and service id.
  • It groups networks by networkType and name.
  • It relies on the link and match kinds and their removal events only, with no inference.
  • It shows the initial snapshot without logging or highlighting it.
image

@KonradBreitsprecherBkd
KonradBreitsprecherBkd added this pull request to stack #435 October 5, 2026 13:44
@KonradBreitsprecherBkd
KonradBreitsprecherBkd force-pushed the dev_public_service_discovery_observer branch from d6d0ac0 to 315bfd0 Compare October 6, 2026 07:51
@MariusBgm
MariusBgm force-pushed the dev_public_service_discovery_observer branch from 315bfd0 to 1e1dcb6 Compare October 6, 2026 13:03
…s, observer demo

- Replace the catch-all Link kind with NetworkSimulatorLink, PubSubMatch and
  RpcMatch. Matches are now reported as removed: after both endpoints are
  known, and before the first endpoint's ServiceRemoved.
- Report each participant's LifecycleService and TimeSyncService.
- Rework SilKit_Experimental_ServiceDescriptor (unreleased, so not backward
  compatible): serviceId / connectedServiceId as stable keys, typed
  networkType, operationMode and timeSyncActive, an isSnapshot flag for the
  services replayed on handler registration; drop the always empty
  simulationName.
- Adapt the C++ hourglass, and extend the unit, integration and hourglass
  tests.
- Add SilKitDemoObserver, a live terminal dashboard that joins a simulation
  and shows, based only on the experimental service discovery and the
  system monitor:
  - the system state, and all participants with their state, operation
    mode, time synchronization and services;
  - the topology: bus networks with their controllers and network
    simulators, and pub/sub topics and RPC functions with their matches;
  - a concise log of every change, with new and removed elements
    highlighted.
  With --sim-time it also takes part in the virtual time synchronization to
  show the global simulation time, without ever advancing alone.

Signed-off-by: Konrad Breitsprecher <Konrad.Breitsprecher@vector.com>
@MariusBgm
MariusBgm force-pushed the dev_public_service_discovery_observer branch from 1e1dcb6 to 8f61cd3 Compare October 6, 2026 14:32

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant