English | 中文版
[TOC]
- The file event subsystem uses I/O multiplexing to listen on many sockets concurrently and associates different event handlers with sockets depending on the operations they will perform.
- When a watched socket becomes ready to accept, read, write, close, etc., the corresponding file event is generated and the event loop invokes the handler previously associated with that socket.
Redis chooses the highest-performance I/O multiplexing facility available on the target system at compile time.
AE_READABLE: generated when a socket becomes readable (the client wrote to the socket or closed it), or when a new acceptable connection is available (a client connected to a listening socket).AE_WRITABLE: generated when a socket becomes writable (the client read from the socket).
-
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData)eventLoopevent loopfdsocket descriptormaskevent maskprocevent handlerclientDatauser data- return:
AE_ERRfailureAE_OKsuccess
Register an event and associate a handler with it.
-
void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask)eventLoopevent loopfdsocket descriptormaskevent mask
Unregister an event and remove its handler association.
-
int aeGetFileEvents(aeEventLoop *eventLoop, int fd)eventLoopevent loopfdsocket descriptor- return:
AE_NONEno events registeredAE_READABLEread event registeredAE_WRITABLEwrite event registeredAE_READABLE|AE_WRITABLEboth read and write registered
Return the mask of events currently registered for the socket.
-
int aeWait(int fd, int mask, long long milliseconds)fdsocket descriptormaskevent maskmillisecondstimeout in ms- return: generated socket events
Block waiting for socket events up to the given timeout.
-
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)TODO
-
int aeProcessEvents(aeEventLoop *eventLoop, int flags)TODO
-
char *aeGetApiName(void)Return the name of the underlying I/O multiplexing implementation.
-
acceptTcpHandler— accept handlerExample: handle an incoming connection on the listening socket.
Loadinggraph LR Client --connects to listening socket--> serv subgraph Server serv(Listening socket becomes AE_READABLE\naccept handler runs) end
-
readQueryFromClient— request readerExample: read a command request from a client socket when it becomes readable.
Loadinggraph LR Client --sends command request--> serv subgraph Server serv(Client socket becomes AE_READABLE,\ncommand request handler runs) end
-
sendReplyToClient— reply senderExample: write a command reply back to the client when the socket becomes writable.
Loadinggraph LR subgraph Server serv(Client socket becomes AE_WRITABLE,\nreply handler runs) end serv --sends reply--> Client
Full client-server interaction example:
graph LR
Client --client sends connection request\nserver runs accept handler--> Server
Client --client sends command request\nserver runs request handler--> Server
Server --server sends reply\nserver runs reply handler--> Client
Redis time events fall into two categories:
- One-shot events: run once at a specified time
- Periodic events: run repeatedly at fixed intervals
A time event has these main attributes:
idglobal unique ID assigned by the server (monotonic increasing)whenarrival time as a UNIX timestamp in millisecondstimeProchandler function invoked when the event arrives
An event is one-shot or periodic depending on the handler's return value:
AE_NOMORE: one-shot — the event is removed after firing once- non-
AE_NOMORE: periodic — the handler's return updates thewhenso the event fires again later
-
long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc)eventLoopevent loopmillisecondsmilliseconds from now or absolute time (API semantics)prochandlerclientDatauser datafinalizerProccallback when the event is deleted- return:
AE_ERRfailuretime event idsuccess
Add a new time event and set its handler to
proc. -
int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id)eventLoopevent loopidevent id- return:
AE_OKsuccessAE_ERRfailure
Delete a time event.
-
static aeTimeEvent *aeSearchNearestTimer(aeEventLoop *eventLoop)eventLoopevent loop- return: the nearest upcoming time event, or NULL
-
static int processTimeEvents(aeEventLoop *eventLoop)eventLoopevent loop- return: number of processed time events
Iterate over due time events and invoke their handlers.
Server run loop from the event perspective:
graph TD
start Server --> is_close{Server closing?}
is_close --yes--> Close server
is_close --no--> Wait for file events --> Process generated file events --> Process due time events --start next loop--> is_close
Scheduling and execution rules:
- The maximum blocking time for
aeApiPollis determined by the nearest time event; this avoids busy-waiting while ensuringaeApiPolldoesn't block too long. - File events are asynchronous and can appear randomly. If, after processing file events, no time events are due, the server waits again for file events. As file events are handled, time advances toward the next time event and eventually the server will process due time events.
- File and time event handlers run synchronously, in-order, and atomically — handlers are not preempted. Handlers should minimize blocking and yield when appropriate to avoid starvation.
- Because time events are processed after file events and there is no preemption, actual handling of a time event may occur slightly after its scheduled arrival time.
[1] Huang Jianhong. Redis Design and Implementation

