Skip to content

Transports

Oleksandr Geronime edited this page Jul 4, 2026 · 7 revisions

Transports

SERP services are transport-agnostic. The same C++ service implementation compiles unchanged for any backend — in-process function calls, DBus IPC, or gRPC. The deployment spec (SerpIDL composition definition) selects which transport is used for each service-to-service connection. No #ifdef or conditional code is required in your service implementation.


How It Works

The code generator produces transport adapter files under gen/adapters/. These files contain all the serialization, dispatch, and stub/proxy glue for the selected backend. When you switch transports, you switch which adapter is compiled — not which service code runs.

specs/serp.sidl (composition: select transport per connection)
         │
         ▼
     serpgen
         │
         ├──► gen/adapters/inprocess/   direct shared_ptr calls
         ├──► gen/adapters/dbus/        sdbus-c++ adapter + proxy
         ├──► gen/adapters/grpc/        proto stubs + gRPC channel
         └──► gen/adapters/posix/       POSIX UDS adapter + proxy

Transport Backends

inprocess (monolith)

All services run in a single process. Method calls are direct shared_ptr function calls — no serialization, no IPC, no marshaling.

Property Value
Latency Minimal (direct function call)
Serialization None
Process topology Single binary
Debugging Simplest — single-process debugger, no IPC traces
CMake target Part of generated wiring (no separate lib)
Platform macOS, Linux, embedded

Use for:

  • Development and iteration (fast build-run cycle)
  • Unit and component tests
  • Single-process production deployments
  • Systems where IPC overhead is unacceptable

DBus (Linux multiprocess)

Services run in separate processes and communicate over the DBus session or system bus. SERP uses the sdbus-c++ library to generate typed adapter and proxy classes.

Property Value
Latency IPC overhead (kernel round-trip)
Serialization DBus wire format
Process topology One or more processes, any layout
Debugging dbus-monitor, gdbus, d-feet
CMake target Serp::transport_dbus
CMake flag SERP_BUILD_TRANSPORT_DBUS=ON (default ON on Linux)
Platform Linux only
Requires libsdbus-c++, running dbus daemon

Use for:

  • Linux embedded targets (automotive, industrial)
  • Android Automotive OS (AAOS) — DBus is idiomatic on real AAOS devices; the generated VHAL registers as a native AIDL service connecting to CarService via the generated VehicleHardwareAdapter (see serp-vhal)
  • Production multiprocess deployments on Linux

POSIX (portable multiprocess, no deps)

Services run in separate processes and communicate over POSIX Unix Domain Sockets. No external libraries are required.

Property Value
Latency Low IPC overhead (local socket)
Serialization SERP binary framing
Process topology One or more processes, any layout
Debugging socat, strace
CMake target Serp::transport_posix
CMake flag SERP_BUILD_TRANSPORT_POSIX=ON
Platform macOS and Linux
Requires Nothing — POSIX sockets are available on any POSIX OS

Socket path: /tmp/serp-<ComponentName>.sock. Override via SERP_POSIX_<COMPONENT>_PATH or SERP_POSIX_SOCKET_DIR.

Use for:

  • macOS development — zero external dependencies (unlike gRPC)
  • CI and testing — no gRPC or DBus installation required
  • Lightweight embedded Linux deployments without gRPC overhead
  • Mixed deployments alongside gRPC (see Mixed Transport below)

gRPC (portable multiprocess)

Services run in separate processes and communicate over gRPC channels. SERP generates proto definitions and stub/channel wiring from the SerpIDL spec.

Property Value
Latency Network IPC overhead
Serialization Protocol Buffers
Process topology One or more processes, any layout
Debugging grpcurl, Wireshark, gRPC interceptors
CMake target Serp::transport_grpc
CMake flag SERP_BUILD_TRANSPORT_GRPC=ON
Platform macOS, Linux, embedded with gRPC support
Requires gRPC library, Protobuf

Use for:

  • macOS development with multiprocess topology (DBus not available on macOS)
  • Cross-platform multiprocess deployments
  • Systems that need gRPC's streaming or language interoperability features

Choosing a Transport

Scenario Transport
Single binary, all services co-located inprocess
Linux embedded / production multiprocess DBus
macOS development, zero external deps POSIX
macOS development with multiprocess topology gRPC or POSIX
Cross-platform portable deployment gRPC or POSIX
Development / testing (fastest iteration) inprocess or POSIX
Mixed: different IPC per connection in one deployment SUML arrow labels (see below)

Switching Transport Without Code Changes

Because transport selection is in the spec, switching from inprocess to DBus or gRPC requires only:

  1. Updating the composition spec in specs/serp.sidl to change the transport declaration.
  2. Running serpgen generate-workspace -w specs/serp.sidl.
  3. Rebuilding.

No changes to service implementation files in src/.


Mixed Transport

A single deployment can use different transports for different service-to-service connections. The transport for each connection is specified via arrow labels in the SUML deployment diagram:

@startuml multiprocess_mixed

package client_app {
  component ClientService <<generated_service>>
}

package platform_app {
  component HalService <<generated_service>>
}

package cloud_app {
  component CloudService <<generated_service>>
}

ClientService --> HalService : posix
ClientService --> CloudService : grpc

@enduml

The ipc: field in the .sidl deployment config acts as a fallback for any connection without an explicit arrow label. Arrow labels always take priority.

# multiprocess_mixed.sidl
deployment:
  mode: multiprocess
  ipc: posix          # fallback for unlabelled connections

What the generator produces:

  • client_app starts both a POSIX backend (to serve its own adapters) and creates a gRPC channel for CloudService — each connection uses its own transport independently.
  • Each process starts only the backends it needs as a server. A process that only consumes a service via gRPC does not start a gRPC server backend.

IPC priority: arrow label > ipc: fallback > error (SERP053)


CMake Configuration

Enable or disable transport backends at configure time:

cmake -S . -B build \
    -DSERP_BUILD_TRANSPORT_DBUS=ON \
    -DSERP_BUILD_TRANSPORT_GRPC=OFF \
    -DSERP_BUILD_TRANSPORT_POSIX=ON

Link the transport target in service CMakeLists where needed:

# DBus transport
target_link_libraries(my_service PRIVATE Serp::transport_dbus)

# gRPC transport
target_link_libraries(my_service PRIVATE Serp::transport_grpc)

# POSIX transport
target_link_libraries(my_service PRIVATE Serp::transport_posix)

The inprocess transport requires no additional link targets — it is part of the generated wiring compiled directly into the monolith.

For mixed transport deployments, the generated CMakeLists.txt automatically links the correct transport targets per process based on which backends that process needs.


Extensibility

The transport layer is modular. The three built-in backends (inprocess, DBus, gRPC) are implemented as plugins in the code generator's IPC plugin registry. This architecture makes it possible to add support for additional transports — such as custom IPC mechanisms, shared memory, or platform-specific buses — without changes to the framework core or to service code.


See Also

Clone this wiki locally