Reactor pattern
The reactor software design pattern is an event handling pattern for concurrently handling service requests without limiting throughput. The pattern's key component is an event loop, running in a single thread or process. This loop demultiplexes incoming requests and dispatches them to corresponding handlers running outside the event loop's thread / process.
This permits handling many concurrent requests without blocking while retaining a simple, reliable mechanism for dispatching the requests. It also allows for adding or removing distinct request handlers in a modular way, though the resulting callbacks can have some disadvantages.[1]
Because of its balance between simplicity and scalabity, the reactor pattern has become a central architectural element of several server applications and software frameworks for networking. Derivations such as the multireactor and proactor also exist for special cases where even greater throughput or additional isolation between threads is necessary.[1][2][3]
Overview
![]() | This section needs expansion. You can help by adding to it. (September 2023) |
Usage
![]() | This section needs expansion. You can help by adding to it. (September 2023) |
Applications
Structure
![]() | This section needs expansion. You can help by adding to it. (September 2023) |
- Resources
- Any resource that can provide input to or consume output from the system.
- Synchronous Event Demultiplexer
- Uses an event loop to block on all resources. The demultiplexer sends the resource to the dispatcher 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. The demultiplexer usesselect()
on the resource, which blocks until the resource is available for reading. In this case, a synchronous call toread()
won't block, and the demultiplexer can send the resource to the dispatcher.) - Dispatcher
- Handles registering and unregistering of request handlers. Dispatches resources from the demultiplexer to the associated request handler.
- Request Handler
- An application defined request handler and its associated resource.
UML diagram
Variants
Properties
All reactor systems are single-threaded by definition, but can exist in a multithreaded environment.
Benefits
The reactor pattern completely separates application-specific code from the reactor implementation, which means that application components can be divided into modular, reusable parts.
Limitations
The reactor pattern can be more difficult to debug than a procedural pattern due to the inverted flow of control.[1] Also, by only calling request handlers synchronously, the reactor pattern limits maximum concurrency, especially on symmetric multiprocessing hardware.[citation needed]
See also
- Proactor pattern, which allows mixing synchronous & asynchronous dispatching
- C10k problem
- Input/output
- Application server
- Web server
References
- ^ a b c . ISBN 9781118725177.
{{cite book}}
: Missing or empty|title=
(help) - ^ . ISBN 9781492091721.
{{cite book}}
: Missing or empty|title=
(help) - ^ Garrett, Owen (10 June 2015). "Inside NGINX: How We Designed for Performance & Scale". NGINX. F5, Inc. Archived from the original on 20 August 2023. Retrieved 10 September 2023.
External links
- An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events by Douglas C. Schmidt
Sample implementations: