Reactor模式论文上半部分

An Object Behavioral Pattern for Demultiplexing and Dispatching Handles for Synchronous Events

一个对于分离和分发同步事件句柄的对象行为模式

1 Intent/意图

The Reactor design pattern handles service requests that are delivered concurrently to an application by one or moreclients. Each service in an application may consist ofserveral methods and is represented by a separate event handlerthat is responsible for dispatching service-specific requests.Dispatching of event handlers is performed by an initiationdispatcher, which manages the registered event handlers.Demultiplexing of service requests is performed by asynchronous event demultiplexer.

Reactor设计模式处理来个一个或多个客户端的向一个应用同时发起的服务请求。应用中的每个服务可能由少数几个方法组成,通过一个单独的事件处理器表现出来,这个事件处理器负责分发特定的服务请求。事件处理器的分发是通过一个初始化的分发器(initiation dispatcher)进行,负责管理注册其上的事件处理器。分离服务请求是由异步事件分离器进行的。

2 Also Known As

Dispatcher, Notifier

分发器,通知器

3 Example

To illustrate the Reactor pattern, consider the event-driven server for a distributed logging service shown in Figure 1.Client applications use the logging service to record information about their status in a distributed environment. This status information commonly includes error notifications, debugging traces, and performance reports. Logging records are sent to a central logging server, which can write there cords to various output devices, such as a console, a printer,a file, or a network management database.

为了阐述reactor模式,考虑使用分布式的日志服务(在下图1)。客户端应用程序使用这个日志服务来记录他们在分布式环境中的状态信息。这些状态信息通常包括错误通知,调试栈以及性能报告。这些日志记录会被发送到一个中央的日志服务器上,它可以将这些记录写到多个输出设备上,像控制台,打印机,文件,网络管理数据库。

The logging server shown in Figure 1 handles logging records and connection requests sent by clients. Logging records and connection requests can arrive concurrently on multiple handles. A handle identifies network communication resources managed within an OS.

图一中的日志服务器处理通过客户端发送日志记录以及连接请求。日志记录和连接请求会同时到达多个handle上,一个handle定义了在操作系统内部管理的网络通信资源。



The logging server communicates with clients using a connection-oriented protocol, such as TCP [1]. Clients that want to log data must first send a connection request to the server. The server waits for these connection requests using a handle factory that listens on an address known to clients.When a connection request arrives, the handle factory establishes a connection between the client and the server by creating a new handle that represents an endpoint of the connection.This handle is returned to the server, which then waits for client service requests to arrive on the handle. Once clients are connected, they can send logging records concurrently to the server. The server receives these records via the connected socket handles.

日志服务器和客户端使用一种面向连接的协议进行通信,例如Tcp。客户端想要发送日志数据,首先必须发送一个连接请求给服务器。服务器使用一个handle工厂来监听已经的客户端地址,然后等待连接请求的到来。当一个连接请求到达时,这个handle工厂就会通过一种创建新的handle来建立一个客户端与服务器之间的链接,这个handle表示了一个连接到端点。这个handle是被服务器返回的,然后会等待客户端服务请求到达这个handle。一旦客户端连接上了,他们就能够同时的发送日志记录给服务器,服务器通过已经连接的socket handle收到这些记录。

Perhaps the most intuitive way to develop a concurrent logging server is to use multiple threads that can process multiple clients concurrently, as shown in Figure 2. This approach synchronously accepts network connections and spawns a “thread-per-connection” to handle client logging records.

大概开发一个并发的日志服务器最直接的方式就是使用多线程的方式,它能够并发地处理多个客户端(图二),这种方法同步接收网络连接,然后产生(一个线程对应一个连接)来处理客户端的日志记录。

However, using multi-threading to implement the processing of logging records in the server fails to resolve the following forces:

  • Efficiency: Threading may lead to poor performance due to context switching, synchronization, and data movement[2];
  • Programming simplicity: Threading may require complex concurrency control schemes;
  • Portability: Threading is not available on all OS platforms.

As a result of these drawbacks, multi-threading is often not the most efficient nor the least complex solution to develop a concurrent logging server.

但是,在服务器上使用多线程来实现日志记录的处理不能解决下面的问题:

  • 性能:线程可能会导致极低的性能,因为上下文切换,同步以及数据迁移;
  • 编程简单:线程可能会要求复杂的并发控制方案;
  • 可移植性:线程可能并不适用所有的操作系统;

因为这些缺陷,多线程通常不是最有效率,也不是最小的复杂度解决方案,来开发一个并发的日志服务器。

4 Context

A server application in a distributed system that receives events from one or more clients concurrently.

在分布式系统中的一个服务应用程序会同时接收一个或者多个客户端的事件。

5 Problem

Server applications in a distributed system must handle multiple clients that send them service requests. Before invokinga specific service, however, the server application must demultiplex and dispatch each incoming request to its corresponding service provider. Developing an effective server mechanisms for demultiplexing and dispatching client requests requires the resolution of the following forces:

在分布式系统中的服务应用程序必须处理多个发送服务请求的客户端。但是在调用特定服务之前,服务应用程序必须分离和分发每个进来的请求到它的对应的服务提供者。开发一个有效率的服务器机制来分离和分发客户端请求要求下面的问题的解决方案

  • Availability: The server must be available to handle incoming requests even if it is waiting for other requests to arrive.In particular, a server must not block indefinitely handling any single source of events at the exclusion of other event sources since this may significantly delay the responseness to other clients.
  • Efficiency: A server must minimize latency, maximize throughput, and avoid utilizing the CPU(s) unnecessarily.
  • Programming simplicity: The design of a server should simplify the use of suitable concurrency strategies.
  • Adaptability: Integrating new or improved services,such as changing message formats or adding server-side caching, should incur minimal modifications and maintenance costs for existing code. For instance, implementing new application services should not require modifications to the generic event demultiplexing and dispatching mechanisms.
  • Portability: Porting a server to a new OS platform should not require significant effort.
  • 可用性:服务器必须是可用的,即使在它等待其他请求的到来的时候,也能够处理进来的请求。另外,服务器在处理任何单个的事件源时,一定不能够无限期的阻塞,把其他事件源排除在外。这样会显著的延迟发给其他客户端的额响应
  • 性能:一个服务器必须是尽可能最低的延迟,尽可能最大的吞吐量,避免不必要的CPU利用。
  • 编程简单:这个服务器的设计应该简化合适的并发策略的使用。
  • 可扩展性:集成一个新的或者改进的服务,例如改变消息格式,添加服务器端缓存,应该针对现有的代码引发最小的改动和维护成本。举个例子,实现一个新的应用服务应该不需要修改通用的时间分离和分发机制。
  • 可移植性:移植一个服务器到一个新的操作系统上应该不需要做出重大的改动。

6 Solution

Integrate the synchronous demultiplexing of events and the dispatching of their corresponding event handlers that process the events. In addition, decouple the application specific dispatching and implementation of services from the general-purpose event demultiplexing and dispatching mechanisms.

集成同步的事件分离器以及处理这些事件的事件处理器的调度。除此之外,多路事件分离和调度机制解耦了特定于应用程序的调度与服务实现。

For each service the application offers, introduce a separate Event Handler that processes certain types of events. All Event Handlers implement the same interface.Event Handlers register with an InitiationDispatcher, which uses a Synchronous EventDemultiplexer to wait for events to occur. When events occur, the Synchronous Event Demultiplexer notifies the Initiation Dispatcher, which synchronously calls back to the Event Handler associated with the event. The Event Handler then dispatches the event to the method that implements the requested service.

对于每个服务,应用程序提供,介绍了一个单独的事件处理器,用于处理某些事件类型。所有的事件处理器都实现了相同的接口。事件处理器(Event Handler)通过注册到一个初始化的分发器(InitiationDispatcher)当中,这个InitiationDispatcher使用了同步事件分离器(Synchronous Event Demultiplexer)来等待事件的发生。当事件发生时,这个同步事件分离器(Synchronous Event Demultiplexer)会通知初始化分发器(InitiationDispatcher),初始化分发器(InitiationDispatcher)会同步地回调与这个时间相关联的事件处理器(Event Handler)。这个事件处理器(Event Handler)然后会分发这个事件到实现了请求服务的方法当中。

7 Structure

The key participants in the Reactor pattern include the following:

在Reactor模式中的关键角色:

Handles

  • Identify resources that are managed by an OS.These resources commonly include network connections,open files, timers, synchronization objects, etc.Handles are used in the logging server to identify socket endpoints so that a Synchronous EventDemultiplexer can wait for events to occur on them. The two types of events the logging server is interested in are connection events and read events, which represent incoming client connections and logging data,respectively. The logging server maintains a separate connection for each client. Every connection is represented in the server by a socket handle.

句柄

  • 可以看作是操作系统管理的资源。这些资源通常包括网络连接,打开的文件,定时器,同步对象等等。句柄(handles)在这个日志服务器中用来识别socket断点,以便同步事件分离器(Synchronous EventDemultiplexer)能够在他们上面等待事件发生。这个日志服务器的两种事件类型是连接事件和读事件,直观地展示了进来的客户端连接和日志数据。日志服务器为每个客户端都保持了独立的链接,每个连接在服务器上通过一个socket handle来进行表示。

Synchronous Event Demultiplexer

  • Blocks awaiting events to occur on a set of Handles.It returns when it is possible to initiate an operation on a Handle without blocking. A common demultiplexerfor I/O events is select [1], which is an event demultiplexing system call provided by the UNIX and Win32 OS platforms. The select call indicates which Handles can have operations invoked on them synchronously without blocking the application process.

同步事件分离器

  • 在一个handle集合上阻塞地等待事件发生,当它有可能在一个handle 上开始了一个操作时,它就会返回,结束阻塞。一个常用的I/O事件分离器就是select,它是一个被UNIX和window平台提供的事件分离系统调用,这个select能够指明了在哪个handles上有操作能够被进行同步调用了,不会去阻塞应用进程。

Initiation Dispatcher

  • Defines an interface for registering, removing, and dispatching Event Handlers. Ultimately, the Synchronous Event Demultiplexer is responsible for waiting until new events occur. When it detects new events, it informs the InitiationDispatcher to call back application-specific event handlers. Common events include connection acceptance events, data input and output events, and timeout events.

初始化分发器(初始化的调度器)

  • 定义了一个注册、移除,以及调度事件处理器的接口,从根本上讲,同步事件分离器(Synchronous Event Demultiplexer)是负责等待一个新的事件发生。当它发现了一个新的事件之后,它会通知初始化的调度器(InitiationDispatcher)来回调特定于应用的事件处理器。普通事件包括连接接收事件,数据输入输出事件,超时事件。

Event Handler

  • Specifies an interface consisting of a hook method [3]that abstractly represents the dispatching operation for service-specific events. This method must be implemented by application-specific services.

事件处理器

  • 指一个由回调钩子方法组成的接口,能够抽象地表示面向服务的事件的调度操作。这个方法必须被面向应用的服务所实现。

Concrete Event Handler

  • Implements the hook method, as well as the methods to process these events in an application-specific manner. Applications register Concrete EventHandlers with the Initiation Dispatcher to process certain types of events. When these events arrive,the Initiation Dispatcher calls back the hook method of the appropriate Concrete EventHandler.

    There are two Concrete Event Handlers in the logging server: Logging Handler and Logging Acceptor. The Logging Handler is responsiblefor receiving and processing logging records. The Logging Acceptor creates and connects LoggingHandlers that process subsequent logging records from clients.

具体的事件处理器

  • 实现了回调钩子方法,也就是以一种面向应用的方法处理这些事件的方法。应用程序注册具体的事件处理器(Concrete EventHandlers)到初始化调度器(Initiation Dispatcher)上,用来处理某一类事件。当这些事件到达时,初始化调度器(Initiation Dispatcher)就会回调合适的具体的事件处理器(Concrete EventHandler)中的钩子方法。
  • 在日志服务器上有两种具体事件处理器(Concrete Event Handlers):日志处理器(Logging Handler)和日志接收器(Logging Acceptor)。日志处理器(Logging Handler)是用来接收和处理日志记录的。日志接收器(Logging Acceptor)是用来创建和连接日志处理器(Logging Handler),处理后面来自客户端的日志记录。

The structure of the participants of the Reactor pattern is illustrated in the following OMT class diagram:

Reactor模式的各个角色的架构在下面的OMT类图中进行阐述:


8 Dynamics

8.1 General Collaborations(通常的协作)

The following collaborations occur in the Reactor pattern:

  • When an application registers a Concrete Event Handler with the Initiation Dispatcher the application indicates the type of event(s) this Event Handler wants the Initiation Dispatcher to notify it about when the event(s) occur on the associated Handle.
  • 当一个应用程序将一个具体的事件处理器(Concrete Event Handle)注册到初始化调度器(Initiation Dispatcher)上时,这个应用会指定事件类型,当相关的句柄(handle)上发生这个类型的事件时,事件处理器( Event Handler)想要初始化调度器(Initiation Dispatcher)通知它。
  • The Initiation Dispatcher requests each Event Handler to pass back its internal Handle. This Handle identifies the Event Handler to the OS.
  • 初始化调度器( Initiation Dispatcher)要求每个事件处理器( Event Handler )回传它内部的句柄(handle)。这个句柄(handle)向操作系统标识了事件处理器(Event Handler)。
  • After all Event Handlers are registered, an application calls handle_events to start the Initiation Dispatcher's event loop. At this point, the Initiation Dispatcher combines the Handle from each registeredEvent Handler and uses the Synchronous Event Demultiplexer to wait for events to occur on these Handles. For instance, the TCP protocol layer uses the select synchronous event demultiplexing operation to wait for client logging record events to arrive on connected socket Handles.
  • 在所有的事件处理器(Event Handlers)都注册完毕之后,应用程序会调用handle_events 方法来开始这个初始化调度器( Initiation Dispatcher)的事件循环。在这个点上,初始化调度器(Initiation Dispatcher )组合了从每个已经注册的事件处理器(Event Handler)上回传的handle,并且使用同步事件分离器(Synchronous Event Demultiplexer)来等待在这些句柄(handles)上事件的发生。例如,TCP协议层使用select 同步事件分离器操作来等待客户端到达已连接的套接字(socket)句柄的日志记录事件。
  • The Synchronous Event Demultiplexer notifies the Initiation Dispatcher when a Handle corresponding to an event source becomes “ready,” e.g., that a TCP socket is “ready for reading.”
  • 当一个句柄(handle)变成准备状态,同步事件分离器(Synchronous Event Demultiplexer)通知初始化调度器( Initiation Dispatcher
  • The Initiation Dispatcher triggers Event Handler hook method in response to events on the readyHandles. When events occur, the Initiation Dispatcher uses the Handles activated by the event sources as “keys” to locate and dispatch the appropriate Event Handler's hook method.
  • 初始化调度器( Initiation Dispatcher)触发事件处理器的钩子方法来响应在句柄(handle)上准备好的事件。当事件发生时,初始化调度器( Initiation Dispatcher )使用被事件源激活的句柄(handle)作为定位和调度正确的事件处理的回调方法的key。
  • The Initiation Dispatcher calls back to the handle_event hook method of the Event Handler to perform application-specific functionality in response to an event. The type of event that occurred can be passed as a parameter to the method and used internally by this method to perform additional service specific demultiplexing and dispatching. An alternative dispatching approach is described in Section 9.4.
  • 初始化调度器(Initiation Dispatcher )回调事件处理器(Event Handler)当中的handle_event的钩子方法,来执行特定于程序的功能,以响应一个事件。发生的事件的类型能够作为参数传递到这个方法,然后在这个方法内部使用,以完成附加的业务功能

The following interaction diagram illustrates the collaboration between application code and participants in the Reactor pattern:

下面的交互类图阐述了应用代码和在Reactor模式中各个角色的协作关系:




猜你喜欢

转载自blog.csdn.net/u013828625/article/details/79784590