GRPC C++  1.66.0
Data Structures | Public Types | Public Member Functions
grpc_event_engine::experimental::EventEngine Class Referenceabstract

The EventEngine Interface. More...

#include <event_engine.h>

Data Structures

class  Closure
 A custom closure type for EventEngine task execution. More...
 
struct  ConnectionHandle
 A handle to a cancellable connection attempt. More...
 
class  DNSResolver
 Provides asynchronous resolution. More...
 
class  Endpoint
 One end of a connection between a gRPC client and server. More...
 
class  Listener
 Listens for incoming connection requests from gRPC clients and initiates request processing once connections are established. More...
 
class  ResolvedAddress
 Thin wrapper around a platform-specific sockaddr type. More...
 
struct  TaskHandle
 Represents a scheduled task. More...
 

Public Types

using Duration = std::chrono::duration< int64_t, std::nano >
 A duration between two events. More...
 
using OnConnectCallback = absl::AnyInvocable< void(absl::StatusOr< std::unique_ptr< Endpoint > >)>
 Called when a new connection is established. More...
 

Public Member Functions

virtual absl::StatusOr< std::unique_ptr< Listener > > CreateListener (Listener::AcceptCallback on_accept, absl::AnyInvocable< void(absl::Status)> on_shutdown, const EndpointConfig &config, std::unique_ptr< MemoryAllocatorFactory > memory_allocator_factory)=0
 Factory method to create a network listener / server. More...
 
virtual ConnectionHandle Connect (OnConnectCallback on_connect, const ResolvedAddress &addr, const EndpointConfig &args, MemoryAllocator memory_allocator, Duration timeout)=0
 Creates a client network connection to a remote network listener. More...
 
virtual bool CancelConnect (ConnectionHandle handle)=0
 Request cancellation of a connection attempt. More...
 
virtual ~EventEngine ()=default
 At time of destruction, the EventEngine must have no active responsibilities. More...
 
virtual bool IsWorkerThread ()=0
 
virtual absl::StatusOr< std::unique_ptr< DNSResolver > > GetDNSResolver (const DNSResolver::ResolverOptions &options)=0
 Creates and returns an instance of a DNSResolver, optionally configured by the options struct. More...
 
virtual void Run (Closure *closure)=0
 Asynchronously executes a task as soon as possible. More...
 
virtual void Run (absl::AnyInvocable< void()> closure)=0
 Asynchronously executes a task as soon as possible. More...
 
virtual TaskHandle RunAfter (Duration when, Closure *closure)=0
 Synonymous with scheduling an alarm to run after duration when. More...
 
virtual TaskHandle RunAfter (Duration when, absl::AnyInvocable< void()> closure)=0
 Synonymous with scheduling an alarm to run after duration when. More...
 
virtual bool Cancel (TaskHandle handle)=0
 Request cancellation of a task. More...
 
- Public Member Functions inherited from grpc_event_engine::experimental::Extensible
virtual void * QueryExtension (absl::string_view)
 A method which allows users to query whether an implementation supports a specified extension. More...
 

Additional Inherited Members

- Protected Member Functions inherited from grpc_event_engine::experimental::Extensible
 ~Extensible ()=default
 

Detailed Description

The EventEngine Interface.

Overview

The EventEngine encapsulates all platform-specific behaviors related to low level network I/O, timers, asynchronous execution, and DNS resolution.

This interface allows developers to provide their own event management and network stacks. Motivating uses cases for supporting custom EventEngines include the ability to hook into external event loops, and using different EventEngine instances for each channel to better insulate network I/O and callback processing from other channels.

A default cross-platform EventEngine instance is provided by gRPC.

Lifespan and Ownership

gRPC takes shared ownership of EventEngines via std::shared_ptrs to ensure that the engines remain available until they are no longer needed. Depending on the use case, engines may live until gRPC is shut down.

EXAMPLE USAGE (Not yet implemented)

Custom EventEngines can be specified per channel, and allow configuration for both clients and servers. To set a custom EventEngine for a client channel, you can do something like the following:

ChannelArguments args; std::shared_ptr<EventEngine> engine = std::make_shared<MyEngine>(...); args.SetEventEngine(engine); MyAppClient client(grpc::CreateCustomChannel( "localhost:50051", grpc::InsecureChannelCredentials(), args));

A gRPC server can use a custom EventEngine by calling the ServerBuilder::SetEventEngine method:

ServerBuilder builder; std::shared_ptr<EventEngine> engine = std::make_shared<MyEngine>(...); builder.SetEventEngine(engine); std::unique_ptr<Server> server(builder.BuildAndStart()); server->Wait();

Blocking EventEngine Callbacks

Doing blocking work in EventEngine callbacks is generally not advisable. While gRPC's default EventEngine implementations have some capacity to scale their thread pools to avoid starvation, this is not an instantaneous process. Further, user-provided EventEngines may not be optimized to handle excessive blocking work at all.

Best Practice : Occasional blocking work may be fine, but we do not recommend running a mostly blocking workload in EventEngine threads.

Thread-safety guarantees

All EventEngine methods are guaranteed to be thread-safe, no external synchronization is required to call any EventEngine method. Please note that this does not apply to application callbacks, which may be run concurrently; application state synchronization must be managed by the application.

Member Typedef Documentation

◆ Duration

using grpc_event_engine::experimental::EventEngine::Duration = std::chrono::duration<int64_t, std::nano>

A duration between two events.

Throughout the EventEngine API durations are used to express how long until an action should be performed.

◆ OnConnectCallback

using grpc_event_engine::experimental::EventEngine::OnConnectCallback = absl::AnyInvocable<void(absl::StatusOr<std::unique_ptr<Endpoint> >)>

Called when a new connection is established.

If the connection attempt was not successful, implementations should pass the appropriate statuses to this callback. For example, callbacks might expect to receive DEADLINE_EXCEEDED statuses when appropriate, or CANCELLED statuses on EventEngine shutdown.

Constructor & Destructor Documentation

◆ ~EventEngine()

virtual grpc_event_engine::experimental::EventEngine::~EventEngine ( )
virtualdefault

At time of destruction, the EventEngine must have no active responsibilities.

EventEngine users (applications) are responsible for cancelling all tasks and DNS lookups, shutting down listeners and endpoints, prior to EventEngine destruction. If there are any outstanding tasks, any running listeners, etc. at time of EventEngine destruction, that is an invalid use of the API, and it will result in undefined behavior.

Member Function Documentation

◆ Cancel()

virtual bool grpc_event_engine::experimental::EventEngine::Cancel ( TaskHandle  handle)
pure virtual

Request cancellation of a task.

If the associated closure cannot be cancelled for any reason, this function will return false.

If the associated closure can be cancelled, the associated callback will never be run, and this method will return true. If the callback type was an absl::AnyInvocable, it will be destroyed before the method returns.

◆ CancelConnect()

virtual bool grpc_event_engine::experimental::EventEngine::CancelConnect ( ConnectionHandle  handle)
pure virtual

Request cancellation of a connection attempt.

If the associated connection has already been completed, it will not be cancelled, and this method will return false.

If the associated connection has not been completed, it will be cancelled, and this method will return true. The OnConnectCallback will not be called, and on_connect will be destroyed before this method returns.

◆ Connect()

virtual ConnectionHandle grpc_event_engine::experimental::EventEngine::Connect ( OnConnectCallback  on_connect,
const ResolvedAddress addr,
const EndpointConfig args,
MemoryAllocator  memory_allocator,
Duration  timeout 
)
pure virtual

Creates a client network connection to a remote network listener.

Even in the event of an error, it is expected that the on_connect callback will be asynchronously executed exactly once by the EventEngine. A connection attempt can be cancelled using the CancelConnect method.

Implementation Note: it is important that the memory_allocator be used for all read/write buffer allocations in the EventEngine implementation. This allows gRPC's ResourceQuota system to monitor and control memory usage with graceful degradation mechanisms. Please see the MemoryAllocator API for more information.

◆ CreateListener()

virtual absl::StatusOr<std::unique_ptr<Listener> > grpc_event_engine::experimental::EventEngine::CreateListener ( Listener::AcceptCallback  on_accept,
absl::AnyInvocable< void(absl::Status)>  on_shutdown,
const EndpointConfig config,
std::unique_ptr< MemoryAllocatorFactory memory_allocator_factory 
)
pure virtual

Factory method to create a network listener / server.

Once a Listener is created and started, the on_accept callback will be called once asynchronously for each established connection. This method may return a non-OK status immediately if an error was encountered in any synchronous steps required to create the Listener. In this case, on_shutdown will never be called.

If this method returns a Listener, then on_shutdown will be invoked exactly once when the Listener is shut down, and only after all on_accept callbacks have finished executing. The status passed to it will indicate if there was a problem during shutdown.

The provided MemoryAllocatorFactory is used to create MemoryAllocators for Endpoint construction.

◆ GetDNSResolver()

virtual absl::StatusOr<std::unique_ptr<DNSResolver> > grpc_event_engine::experimental::EventEngine::GetDNSResolver ( const DNSResolver::ResolverOptions options)
pure virtual

Creates and returns an instance of a DNSResolver, optionally configured by the options struct.

This method may return a non-OK status if an error occurred when creating the DNSResolver. If the caller requests a custom DNS server, and the EventEngine implementation does not support it, this must return an error.

◆ IsWorkerThread()

virtual bool grpc_event_engine::experimental::EventEngine::IsWorkerThread ( )
pure virtual

◆ Run() [1/2]

virtual void grpc_event_engine::experimental::EventEngine::Run ( absl::AnyInvocable< void()>  closure)
pure virtual

Asynchronously executes a task as soon as possible.

Closures passed to Run cannot be cancelled. Unlike the overloaded Closure alternative, the absl::AnyInvocable version's closure will be deleted by the EventEngine after the closure has been run.

This version of Run may be less performant than the Closure version in some scenarios. This overload is useful in situations where performance is not a critical concern.

Implementations must not execute the closure in the calling thread before Run returns.

◆ Run() [2/2]

virtual void grpc_event_engine::experimental::EventEngine::Run ( Closure closure)
pure virtual

Asynchronously executes a task as soon as possible.

Closures passed to Run cannot be cancelled. The closure will not be deleted after it has been run, ownership remains with the caller.

Implementations must not execute the closure in the calling thread before Run returns. For example, if the caller must release a lock before the closure can proceed, running the closure immediately would cause a deadlock.

◆ RunAfter() [1/2]

virtual TaskHandle grpc_event_engine::experimental::EventEngine::RunAfter ( Duration  when,
absl::AnyInvocable< void()>  closure 
)
pure virtual

Synonymous with scheduling an alarm to run after duration when.

The closure will execute when time when arrives unless it has been cancelled via the Cancel method. If cancelled, the closure will not be run. Unlike the overloaded Closure alternative, the absl::AnyInvocable version's closure will be deleted by the EventEngine after the closure has been run, or upon cancellation.

This version of RunAfter may be less performant than the Closure version in some scenarios. This overload is useful in situations where performance is not a critical concern.

Implementations must not execute the closure in the calling thread before RunAfter returns.

◆ RunAfter() [2/2]

virtual TaskHandle grpc_event_engine::experimental::EventEngine::RunAfter ( Duration  when,
Closure closure 
)
pure virtual

Synonymous with scheduling an alarm to run after duration when.

The closure will execute when time when arrives unless it has been cancelled via the Cancel method. If cancelled, the closure will not be run, nor will it be deleted. Ownership remains with the caller.

Implementations must not execute the closure in the calling thread before RunAfter returns.

Implementations may return a kInvalid handle if the callback can be immediately executed, and is therefore not cancellable.


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