E 81 CSE 532 S Advanced MultiParadigm Software

  • Slides: 25
Download presentation
E 81 CSE 532 S: Advanced Multi-Paradigm Software Development Reactor Pattern Venkita Subramonian, Christopher

E 81 CSE 532 S: Advanced Multi-Paradigm Software Development Reactor Pattern Venkita Subramonian, Christopher Gill, Guandong Wang, Zhenning Hu, Zhenghui Xie Department of Computer Science and Engineering Washington University, St. Louis cdgill@cse. wustl. edu

Motivating Example: A Logging Server From http: //www. cs. wustl. edu/~schmidt/patterns-ace. html

Motivating Example: A Logging Server From http: //www. cs. wustl. edu/~schmidt/patterns-ace. html

Providing Responsive Event Handling Client 1 Port: 27098 Goal: process multiple service requests responsively

Providing Responsive Event Handling Client 1 Port: 27098 Goal: process multiple service requests responsively Logging Server CO NN E CT Port: 30000 listen Client 2 C CT E N ON Port: 24467 accept Port: 25667 accept Port: 26545

What about Thread-per-Connection? • Multi-threading may increase code complexity • Multi-threading/processing adds overhead –

What about Thread-per-Connection? • Multi-threading may increase code complexity • Multi-threading/processing adds overhead – Context switching (especially among processes) – Synchronization for shared data, other resources • What if we could make 1 thread responsive? – Using a top-half/bottom-half like approach – Better resource utilization by aligning threading strategy to # of available resources (like CPUs) – Also, multi-threading may not be available in all OS platforms (e. g. , small embedded ones)

Design Idea for Event Driven Server (reusable: e. g. , from ACE) Event Dispatching

Design Idea for Event Driven Server (reusable: e. g. , from ACE) Event Dispatching Logic _ le d n a h (pluggable: you write your own) Event Handling Logic Connection Acceptor st e u q re _ n o i ct e n n co Event Handlers hand le_d • Inversion of control • Hollywood principle – Don’t call us, we’ll call you (“there is no main”) ata_ read Data Reader

Reactor Pattern (Dispatching Logic) • An architectural pattern – Context: event-driven application – Concurrent

Reactor Pattern (Dispatching Logic) • An architectural pattern – Context: event-driven application – Concurrent reception of multiple service requests, but serial processing of each one • Dispatch service requests – Calls the appropriate event handler • Also known as – Dispatcher, Notifier, Selector (see Java NIO)

Design Forces • • Enhance scalability Maximize throughput Minimize latency Reduce effort that is

Design Forces • • Enhance scalability Maximize throughput Minimize latency Reduce effort that is needed to integrate new services into server

Solution Approach – Separates Concerns Application De-multiplexing & Dispatching Event sources Application logic Event

Solution Approach – Separates Concerns Application De-multiplexing & Dispatching Event sources Application logic Event Handlers Reactor Synchronous wait Serial Dispatching

Reactor Pattern Solution Structure a. k. a “the reactor” From http: //www. cs. wustl.

Reactor Pattern Solution Structure a. k. a “the reactor” From http: //www. cs. wustl. edu/~schmidt/patterns-ace. html

Synchronous vs. Reactive Read Clients Server read() data select() read() Handle. Set

Synchronous vs. Reactive Read Clients Server read() data select() read() Handle. Set

Serial Event Dispatching Reactor Application read() Clients select() Handle. Set read() handle_*() Event Handlers

Serial Event Dispatching Reactor Application read() Clients select() Handle. Set read() handle_*() Event Handlers

Interactions among Participants Main Program Concrete Event Handler Synchronous Event Demultiplexer Reactor register_handler(handler, event_types)

Interactions among Participants Main Program Concrete Event Handler Synchronous Event Demultiplexer Reactor register_handler(handler, event_types) get_handle() handle_events() select() event handle_event()

Implementation • De-multiplexer/dispatcher infrastructure – Anonymous de-multiplexing of events to handlers – Assumes specific

Implementation • De-multiplexer/dispatcher infrastructure – Anonymous de-multiplexing of events to handlers – Assumes specific event handler hook methods • Application – Defines concrete event handlers – Handlers perform service-specific processing (“Service Handlers”)

Event Handler Interface • Determine type of dispatching target – – Objects vs. functions

Event Handler Interface • Determine type of dispatching target – – Objects vs. functions Can have pointers to either Command pattern can unify these Note: singular, not plural E. g. , handle_event () • Event handling dispatch interface strategy – Single-method dispatch • handle_event (handle, event_type) – Multi-method dispatch • handle_input (handle) • handle_output (handle) • handle_timeout (handle)

Reactor Interface • Handler registration/deregistration – E. g. , register_handler() deregister_handler() • Consider visitor,

Reactor Interface • Handler registration/deregistration – E. g. , register_handler() deregister_handler() • Consider visitor, observer patterns • Event loop – E. g. , handle_events() Note: plural, not singular

Reactor Implementation • Reactor implementation hierarchy – Abstract base class or template concept –

Reactor Implementation • Reactor implementation hierarchy – Abstract base class or template concept – Concrete platform-specific implementations • Synchronous event de-multiplexing mechanism – E. g. , Wait. For. Multiple. Objects() on Win 32 – E. g. , select() or poll() on UNIX platforms • Implement a dispatch table • Complete concrete reactor implementation – Hook dispatch table into de-mux mechanism

Multiple Reactors • A single reactor instance will work in most cases – Sometimes

Multiple Reactors • A single reactor instance will work in most cases – Sometimes desirable, e. g. , for handler serialization – Can use Singleton (e. g. , ACE_Reactor: : instance()) • Limits on number of OS handles may restrict this – Total available (rarely an issue in a general-purpose OS) – Max a single thread can wait for • E. g. , 64 in some Win 32 platforms – May need multiple reactors, each with its own thread – Note that handlers are not serialized across Reactor instances – treat remote/concurrent reactors similarly

Concrete Event Handlers • Implement base interface / model concept • Determine policies for

Concrete Event Handlers • Implement base interface / model concept • Determine policies for handler state – Stateless, stateful, or a combination • ACTs (cookies) can help offload some of the state • I. e. , can keep state outside the handler objects, but index into a data structure, etc. using the ACT • Implement event handler functionality – I. e. , add application logic to handler methods

Logging Server++ Part 1 a. k. a. “the reactor” Steps performed when a client

Logging Server++ Part 1 a. k. a. “the reactor” Steps performed when a client connects to the logging server (we’ll cover Acceptor/Connector in a subsequent lecture) From http: //www. cs. wustl. edu/~schmidt/patterns-ace. html

Logging Server++ Part 2 a. k. a. “the reactor” Steps performed by reactive logging

Logging Server++ Part 2 a. k. a. “the reactor” Steps performed by reactive logging server for each record From http: //www. cs. wustl. edu/~schmidt/patterns-ace. html

Variant: Integrated De-multiplexing of Timer and I/O Events • Timer-based and I/O-based events in

Variant: Integrated De-multiplexing of Timer and I/O Events • Timer-based and I/O-based events in same reactor • Extend reactors and event handlers – Register concrete event handlers for some time trigger • Relative vs. absolute time triggers • Periodic vs. one time invocation – Reactor calls handler’s handle_timeout() method • Can use same handler for time and event dispatching • E. g. , an alert watchdog timer for some logging handler – Various timer strategies • • E. g. , select/WFMO timeout E. g. , hardware timer interrupt E. g. , polling Pentium tick counter Key trade-offs between portability, overhead and responsiveness

Variant: Re-entrant Reactors • Event handlers re-invoke reactor->handle_events() – Result: nested event handlers –

Variant: Re-entrant Reactors • Event handlers re-invoke reactor->handle_events() – Result: nested event handlers – E. g. , CORBA AMI nested work_pending() • Reactor implementation must be re-entrant – Copy the handle set state onto the run-time stack – Any changes to handle set are local to that nesting level of the reactor – Use thread stack frame to record reactor’s logical “stack frame”

Variant: Thread-Safe Reactor • Synchronized reactor – Lock to synchronize access to the reactor’s

Variant: Thread-Safe Reactor • Synchronized reactor – Lock to synchronize access to the reactor’s internal state • Multiple threads could register/remove event handlers – Preventing self-deadlock • An event handler could register/remove other event handlers or itself – Explicitly notifying a waiting event loop thread • Notify the reactor of a change so that the wait handleset could be updated

Variant: Concurrent Event Handlers • Event handlers with their own threads – In addition

Variant: Concurrent Event Handlers • Event handlers with their own threads – In addition to event loop thread(s) • Related concurrency patterns – the Active Object – the Leader/Followers – the Half-Sync/Half-Async

Variant: Concurrent Event De-multiplexer • Event de-multiplexer concurrent in multiple threads • E. g.

Variant: Concurrent Event De-multiplexer • Event de-multiplexer concurrent in multiple threads • E. g. , Windows Wait. For. Multiple. Objects() • Benefits – Can improve throughput significantly for some applications • Drawbacks – Need a thread-safe event de-multiplexer wrapper façade – Less portable (few platforms support this) – Implementation can become more complex