1# Event Framework {#event} 2 3SPDK provides a framework for writing asynchronous, polled-mode, 4shared-nothing server applications. The event framework is intended to be 5optional; most other SPDK components are designed to be integrated into an 6application without specifically depending on the SPDK event library. The 7framework defines several concepts - reactors, events, and pollers - that are 8described in the following sections. The event framework spawns one thread per 9core (reactor) and connects the threads with lockless queues. Messages 10(events) can then be passed between the threads. On modern CPU architectures, 11message passing is often much faster than traditional locking. For a 12discussion of the theoretical underpinnings of this framework, see @ref 13concurrency. 14 15The event framework public interface is defined in event.h. 16 17## Event Framework Design Considerations {#event_design} 18 19Simple server applications can be written in a single-threaded fashion. This 20allows for straightforward code that can maintain state without any locking or 21other synchronization. However, to scale up (for example, to allow more 22simultaneous connections), the application may need to use multiple threads. 23In the ideal case where each connection is independent from all other 24connections, the application can be scaled by creating additional threads and 25assigning connections to them without introducing cross-thread 26synchronization. Unfortunately, in many real-world cases, the connections are 27not entirely independent and cross-thread shared state is necessary. SPDK 28provides an event framework to help solve this problem. 29 30## SPDK Event Framework Components {#event_components} 31 32### Events {#event_component_events} 33 34To accomplish cross-thread communication while minimizing synchronization 35overhead, the framework provides message passing in the form of events. The 36event framework runs one event loop thread per CPU core. These threads are 37called reactors, and their main responsibility is to process incoming events 38from a queue. Each event consists of a bundled function pointer and its 39arguments, destined for a particular CPU core. Events are created using 40spdk_event_allocate() and executed using spdk_event_call(). Unlike a 41thread-per-connection server design, which achieves concurrency by depending 42on the operating system to schedule many threads issuing blocking I/O onto a 43limited number of cores, the event-driven model requires use of explicitly 44asynchronous operations to achieve concurrency. Asynchronous I/O may be issued 45with a non-blocking function call, and completion is typically signaled using 46a callback function. 47 48### Reactors {#event_component_reactors} 49 50Each reactor has a lock-free queue for incoming events to that core, and 51threads from any core may insert events into the queue of any other core. The 52reactor loop running on each core checks for incoming events and executes them 53in first-in, first-out order as they are received. Event functions should 54never block and should preferably execute very quickly, since they are called 55directly from the event loop on the destination core. 56 57### Pollers {#event_component_pollers} 58 59The framework also defines another type of function called a poller. Pollers 60may be registered with the spdk_poller_register() function. Pollers, like 61events, are functions with arguments that can be bundled and executed. 62However, unlike events, pollers are executed repeatedly until unregistered and 63are executed on the thread they are registered on. The reactor event loop 64intersperses calls to the pollers with other event processing. Pollers are 65intended to poll hardware as a replacement for interrupts. Normally, pollers 66are executed on every iteration of the main event loop. Pollers may also be 67scheduled to execute periodically on a timer if low latency is not required. 68 69### Application Framework {#event_component_app} 70 71The framework itself is bundled into a higher level abstraction called an "app". Once 72spdk_app_start() is called, it will block the current thread until the application 73terminates by calling spdk_app_stop() or an error condition occurs during the 74initialization code within spdk_app_start(), itself, before invoking the caller's 75supplied function. 76 77### Custom shutdown callback {#event_component_shutdown} 78 79When creating SPDK based application user may add custom shutdown callback which 80will be called before the application framework starts the shutdown process. 81To do that set shutdown_cb function callback in spdk_app_opts structure passed 82to spdk_app_start(). Custom shutdown callback should call spdk_app_stop() before 83returning to continue application shutdown process. 84