Crate reactor

source ·
Expand description

Concurrent I/O without rust async problems

This repository provides a set of libraries for concurrent access to I/O resources (file, network, devices etc) which uses reactor pattern with pluggable poll syscall engines. This allows to handle situations like multiple network connections within the scope of a single thread (see C10k problem).

The crate can be used for building concurrent microservice architectures without polling all APIs with asyncs.

The reactor design pattern is an event handling pattern for handling service requests delivered concurrently to a service handler by one or more inputs. The service handler then demultiplexes the incoming requests and dispatches them synchronously to the associated request handlers1.

Core concepts:

  • Resource: any resource that can provide input to or consume output from the system.
  • Runtime: runs an event loop to block on all resources. Sends the resource service when it is possible to start a synchronous operation on a resource without blocking (Example: a synchronous call to read() will block if there is no data to read.
  • Service: custom business logic provided by the application for a given set of resources. Service exposes a Handler API for the reactor Runtime. It is also responsible for the creation and destruction of the resources.

Reactor exposes a high-level API and manages multiple resources of two main kinds listeners and sessions. It uses a dedicated thread blocked on I/O events from all of these resources and than calls the Resource::handle_io to process the I/O and generate resource-specific event.

Once a resource generates an event, reactor calls Handler API (in the context of the runtime thread) to process each of the events.

All resources under poll reactor must be representable as file descriptors.


  1. Schmidt, Douglas et al. Pattern-Oriented Software Architecture Volume 2: Patterns for Concurrent and Networked Objects. Volume 2. Wiley, 2000. 

Modules

OS and implementation-specific poll engines.

Structs

Control API to the service which is run inside a reactor.
High-level reactor API wrapping reactor Runtime into a thread and providing basic thread management for it.
Internal Reactor runtime which is run in a dedicated thread.
Manages timers and triggers timeouts.

Enums

Actions which can be provided to the reactor by the Handler.
Reactor errors
I/O events which can be subscribed for - or notified about by the crate::Reactor on a specific Resource.
Error during write operation for a reactor-managed Resource.

Traits

A service which handles I/O events generated in the Reactor.
A resource which can be managed by the reactor.
Marker traits for types which can be used as a reactor-managed Resource identifiers.
The trait guarantees that the data are either written in full - or, in case of an error, none of the data is written. Types implementing the trait must also guarantee that multiple attempts to do the write would not result in data to be written out of the initial ordering.