Reactor pattern
   HOME

TheInfoList



OR:

The reactor
software design pattern In software engineering, a software design pattern or design pattern is a general, reusable solution to a commonly occurring problem in many contexts in software design. A design pattern is not a rigid structure to be transplanted directly into s ...
is an
event handling In computing, an event is a detectable occurrence or change in the system's state, such as user input, hardware interrupts, system notifications, or changes in data or conditions, that the system is designed to monitor. Events trigger responses or ...
strategy that can respond to many potential service requests concurrently. The pattern's key component is an event loop, running in a ''single'' thread or
process A process is a series or set of activities that interact to produce a result; it may occur once-only or be recurrent or periodic. Things called a process include: Business and management * Business process, activities that produce a specific s ...
, which demultiplexes incoming requests and dispatches them to the correct request handler. By relying on event-based mechanisms rather than blocking I/O or multi-threading, a reactor can handle many concurrent I/O bound requests with minimal delay. A reactor also allows for easily modifying or expanding specific request handler routines, though the pattern does have some drawbacks and limitations. With its balance of simplicity and
scalability Scalability is the property of a system to handle a growing amount of work. One definition for software systems specifies that this may be done by adding resources to the system. In an economic context, a scalable business model implies that ...
, the reactor has become a central architectural element in several server applications and software frameworks for networking. Derivations such as the multireactor and proactor also exist for special cases where even greater throughput, performance, or request complexity are necessary.


Overview

Practical considerations for the
client–server model The client–server model is a distributed application structure that partitions tasks or workloads between the providers of a resource or service, called servers, and service requesters, called clients. Often clients and servers communicate ov ...
in large networks, such as the C10k problem for
web server A web server is computer software and underlying Computer hardware, hardware that accepts requests via Hypertext Transfer Protocol, HTTP (the network protocol created to distribute web content) or its secure variant HTTPS. A user agent, co ...
s, were the original motivation for the reactor pattern. A naive approach to handle service requests from many potential endpoints, such as network sockets or file descriptors, is to listen for new requests from within an event loop, then immediately read the earliest request. Once the entire request has been read, it can be processed and forwarded on by directly calling the appropriate handler. An entirely "iterative" server like this, which handles one request from start-to-finish per iteration of the event loop, is logically valid. However, it will fall behind once it receives multiple requests in quick succession. The iterative approach cannot scale because reading the request blocks the server's only thread until the full request is received, and I/O operations are typically much slower than other computations. One strategy to overcome this limitation is multi-threading: by immediately splitting off each new request into its own worker thread, the first request will no longer block the event loop, which can immediately iterate and handle another request. This "thread per connection" design scales better than a purely iterative one, but it still contains multiple inefficiencies and will struggle past a point. From a standpoint of underlying system resources, each new thread or process imposes overhead costs in
memory Memory is the faculty of the mind by which data or information is encoded, stored, and retrieved when needed. It is the retention of information over time for the purpose of influencing future action. If past events could not be remembe ...
and processing time (due to context switching). The fundamental inefficiency of each thread waiting for I/O to finish isn't resolved either. From a design standpoint, both approaches tightly couple the general demultiplexer with specific request handlers too, making the server code brittle and tedious to modify. These considerations suggest a few major design decisions: # Retain a single-threaded event handler; multi-threading introduces overhead and complexity without resolving the real issue of blocking I/O # Use an event notification mechanism to demultiplex requests only ''after'' I/O is complete (so I/O is effectively non-blocking) # Register request handlers as callbacks with the event handler for better separation of concerns Combining these insights leads to the reactor pattern, which balances the advantages of single-threading with high throughput and scalability.


Usage

The reactor pattern can be a good starting point for any concurrent, event-handling problem. The pattern is not restricted to network sockets either; hardware I/O, file system or
database In computing, a database is an organized collection of data or a type of data store based on the use of a database management system (DBMS), the software that interacts with end users, applications, and the database itself to capture and a ...
access,
inter-process communication In computer science, interprocess communication (IPC) is the sharing of data between running Process (computing), processes in a computer system. Mechanisms for IPC may be provided by an operating system. Applications which use IPC are often cat ...
, and even abstract
message passing In computer science, message passing is a technique for invoking behavior (i.e., running a program) on a computer. The invoking program sends a message to a process (which may be an actor or object) and relies on that process and its supporting ...
systems are all possible use-cases. However, the reactor pattern does have limitations, a major one being the use of callbacks, which make
program analysis In computer science, program analysis is the process of analyzing the behavior of computer programs regarding a property such as correctness, robustness, safety and liveness. Program analysis focuses on two major areas: program optimization an ...
and
debugging In engineering, debugging is the process of finding the Root cause analysis, root cause, workarounds, and possible fixes for bug (engineering), bugs. For software, debugging tactics can involve interactive debugging, control flow analysis, Logf ...
more difficult, a problem common to designs with inverted control. The simpler thread-per-connection and fully iterative approaches avoid this and can be valid solutions if scalability or high-throughput are not required. Single-threading can also become a drawback in use-cases that require maximum throughput, or when requests involve significant processing. Different multi-threaded designs can overcome these limitations, and in fact, some still use the reactor pattern as a sub-component for handling events and I/O.


Applications

The reactor pattern (or a variant of it) has found a place in many web servers, application servers, and networking frameworks: * Adaptive Communication Environment (ACE) * EventMachine * Netty * Nginx * Node.js * Perl Object Environment * POCO C++ Libraries * Spring Framework (version 5 and later) * Tokio * Twisted * Vert.x


Structure

Reactor Pattern - UML 2 Component Diagram.svg, alt=A reactor typically consists of 2 subsystems. Sockets (a.k.a. handles) and a demultiplexer (like select or epoll) are typically provided by the system. The reactive application will provide a dispatcher / event-loop that reacts to handle events by invoking handlers, which are registered as callbacks., UML 2 component diagram of a reactive application. ReactorPattern - UML 2 Sequence Diagram.svg, alt=Before starting the event loop, a reactive application will typically register handles & handlers for specific requests. The event loop will then respond to request-based events by invoking a handler, passing the handle for processing., UML 2 sequence diagram of a reactive server. A reactive application consists of several moving parts and will rely on some support mechanisms:


Variants

The standard reactor pattern is sufficient for many applications, but for particularly demanding ones, tweaks can provide even more power at the price of extra complexity. One basic modification is to invoke event handlers in their own threads for more concurrency. Running the handlers in a thread pool, rather than spinning up new threads as needed, will further simplify the multi-threading and minimize overhead. This makes the thread pool a natural complement to the reactor pattern in many use-cases. Another way to maximize throughput is to partly reintroduce the approach of the "thread per connection" server, with replicated dispatchers / event loops running concurrently. However, rather than the number of connections, one configures the dispatcher count to match the available CPU cores of the underlying hardware. Known as a multireactor, this variant ensures a dedicated server is fully using the hardware's processing power. Because the distinct threads are long-running event loops, the overhead of creating and destroying threads is limited to server startup and shutdown. With requests distributed across independent dispatchers, a multireactor also provides better availability and robustness; should an error occur and a single dispatcher fail, it will only interrupt requests allocated to that event loop. For particularly complex services, where synchronous and asynchronous demands must be combined, one other alternative is the proactor pattern. This pattern is more intricate than a reactor, with its own engineering details, but it still makes use of a reactor subcomponent to solve the problem of blocking IO.


See also

* C10k problem *
Event-driven programming In computer programming, event-driven programming is a programming paradigm in which the Control flow, flow of the program is determined by external Event (computing), events. User interface, UI events from computer mouse, mice, computer keyboard, ...
*
Input/output In computing, input/output (I/O, i/o, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, such as another computer system, peripherals, or a human operator. Inputs a ...
* libevent * Reactive programming Related patterns: * Active object * Observer pattern *
Proactor pattern Proactor is a software design pattern for event handling In computing, an event is a detectable occurrence or change in the system's state, such as user input, hardware interrupts, system notifications, or changes in data or conditions, that the ...
, which allows mixing synchronous & asynchronous event handling


Notes


References


External links

Specific applications: * Sample implementations:
APR Networking & the Reactor Pattern

Architecture of a Highly Scalable NIO-Based Server
{{Design Patterns patterns Concurrent computing Events (computing) Software design patterns