Skip to main content
Pigweed's logo Pigweed
code_xml
  1. Home
  2. Reference
  3. C/C++
  4. Comms
  5. pw_rpc
  6. pw::rpc::Rpc2ServerAdapter Class Reference
pw::rpc::Rpc2ServerAdapter Class Reference

Overview

Adapts an existing pw::rpc::Server to serve pw_rpc services on a pw::rpc2::Server.

The adapter injects calls from pw_rpc2 clients into an existing pw::rpc::Server, so one service instance can serve pw_rpc and pw_rpc2 clients at the same time. (If you do not have an existing pw::rpc::Server, use Rpc2Adapter instead.) Wrap each service with an Rpc2ServiceAdapter (or construct and own it with Rpc2ServiceFor) and register the wrapper with a pw::rpc2::Server. pw_rpc2 clients generated from the same .proto file can call the service without changes.

Each pw_rpc2 connection appears to pw_rpc services as its own channel. The adapter opens channels on the server as connections need them, in any free channel slot, assigning IDs upward from Rpc2AdapterConfig::first_channel_id and skipping IDs already in use. A connection keeps its channel ID for its whole lifetime, across any number of calls. After a connection closes, its channel ID may be reused by a later connection. Do not close the adapter's channels on a shared server: doing so aborts their pw_rpc calls without ending the pw_rpc2 calls. The adapter opens a new channel for the connection's next packet. A shared server must not have a default channel output (SetDefaultChannelOutput()), which prevents opening channels.

Method handlers and stream callbacks for pw_rpc2 clients run on a worker thread started by the adapter, so they may block without stalling the pw_rpc2 dispatcher. Handlers for the server's other channels run wherever the project processes those packets, so a shared service may be invoked from both threads concurrently.

Differences from running on a pw::rpc::Server alone:

  • Status codes: pw_rpc2 does not have application status codes. By default, finishing a call with a non-OK status ends the pw_rpc2 call with kCancelled and discards any response payload. Pass DeliverNonOkResponses() to Rpc2ServiceFor or Rpc2ServiceAdapter for unary and client streaming methods that encode failure in the response message alongside a non-OK status.
  • Flow control: pw_rpc has no flow control. The adapter buffers up to max_queued_messages_per_call outgoing stream messages per call; writes beyond that limit or when the allocator is exhausted fail.
  • Client stream completion: Client and bidirectional streaming handlers that need to know when the client closes its stream must enable PW_RPC_COMPLETION_REQUEST_CALLBACK and call set_on_completion_requested.

The adapter requires PW_RPC_USE_GLOBAL_MUTEX.

Example
// Set up an existing pw_rpc server and service. Any channels already
// configured on the server keep working, and unassigned channels are used for
// pw_rpc2 connections.
std::array<pw::rpc::Channel, 4> channels{};
pw::rpc::Server rpc_server(channels);
SensorServiceImpl sensor_service;
rpc_server.RegisterService(sensor_service);
pw::rpc2::Server rpc2_server(allocator, dispatcher);
// Bridge the pw_rpc2 server and the existing pw_rpc server.
rpc_server, adapter_allocator, thread_options);
// Wrap the existing pw_rpc service for registration with the pw_rpc2 server.
pw::rpc::Rpc2ServiceAdapter adapted_sensor(adapter, sensor_service);
PW_CHECK_OK(rpc2_server.RegisterService(adapted_sensor));
Definition: server.h:76
Definition: rpc2_adapter.h:153
Definition: rpc2_adapter.h:411
Definition: server.h:36
#define PW_CHECK_OK(expression,...)
Definition: check_impl.h:308
Source: pw_rpc/examples/use_rpc_services_in_rpc2.cc
Inheritance diagram for pw::rpc::Rpc2ServerAdapter:
pw::rpc::Rpc2Adapter

Public Member Functions

 Rpc2ServerAdapter (Server &server, Allocator &allocator, const thread::Options &options, const Rpc2AdapterConfig &config=Rpc2AdapterConfig())
 
 ~Rpc2ServerAdapter ()
 
 Rpc2ServerAdapter (const Rpc2ServerAdapter &)=delete
 
Rpc2ServerAdapter & operator= (const Rpc2ServerAdapter &)=delete
 
template<int &... kExplicitGuard, bool kJoiningEnabled = PW_THREAD_JOINING_ENABLED>
void Stop ()
 

Friends

class internal::Rpc2LegacyCall
 
class Rpc2Adapter
 
template<typename >
class Rpc2ServiceFor
 

Constructor & Destructor Documentation

◆ Rpc2ServerAdapter()

pw::rpc::Rpc2ServerAdapter::Rpc2ServerAdapter ( Server &  server,
Allocator &  allocator,
const thread::Options &  options,
const Rpc2AdapterConfig &  config = Rpc2AdapterConfig() 
)
inline

Creates an adapter for server and starts the worker thread that runs pw_rpc handlers for pw_rpc2 clients.

Parameters
[in]serverThe server that adapted services are registered with. It needs a free channel slot (or PW_RPC_DYNAMIC_ALLOCATION) for each concurrent pw_rpc2 connection. Must outlive the adapter.
[in]allocatorBuffers in-flight packets and holds per-connection state. Accessed under the adapter's lock, so it need not be thread-safe unless shared outside the adapter.
[in]optionsOptions for the worker thread. Anything options references (such as a stack or thread context) must outlive the adapter.
[in]configChannel assignment and buffering limits.
Precondition
server must not use SetDefaultChannelOutput(), and config.first_channel_id and config.max_queued_messages_per_call must not be 0.

◆ ~Rpc2ServerAdapter()

pw::rpc::Rpc2ServerAdapter::~Rpc2ServerAdapter ( )

Calls Stop() and frees any remaining queued packets.

Without PW_THREAD_JOINING_ENABLED, the worker thread cannot be stopped, so destroying the adapter crashes. Adapters on such backends must live for the rest of the program.

Precondition
All Rpc2ServiceAdapters using this adapter must have been destroyed, and the pw::rpc2::Server closed.

Member Function Documentation

◆ Stop()

template<int &... kExplicitGuard, bool kJoiningEnabled = PW_THREAD_JOINING_ENABLED>
void pw::rpc::Rpc2ServerAdapter::Stop ( )
inline

Stops the worker thread after processing any packets already queued (such as cancellations from closing the pw::rpc2::Server), then closes the channels the adapter opened on the server. Idempotent.

Close the pw::rpc2::Server and call Stop() before destroying adapted services, since handlers may run until Stop() returns.

Fails to compile without PW_THREAD_JOINING_ENABLED.

Precondition
The pw::rpc2::Server must be closed. Must not be called from the adapter's worker thread.

The documentation for this class was generated from the following file: