欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

beanstalkd源码分析--命令处理流程

程序员文章站 2024-02-14 12:47:58
...

概述

本文讲述了beanstalk的命令处理流程。

处理客户端连接请求

前面已经讲过,当服务启动时会把处理函数设置成srvaccept,用来建立客户端的tcp连接请求。

void
srvserve(Server *s) 
{
    ...
    // 设置处理函数
    s->sock.f = (Handle)srvaccept;
    ...

    // 进入死循环,用来处理连接建立和读写事件
    // 当一个客户端连接到来时,先建立连接
    for (;;) {
        period = prottick(s);

        int rw = socknext(&sock, period);
        if (rw == -1) {
            twarnx("socknext");
            exit(1);
        }

        if (rw) {
            sock->f(sock->x, rw);
        }
    }

和客户端建立连接后

当和客户端完成tcp三次握手,建立tcp连接后,把回调函数设成处理命令的函数,如下:

void
h_accept(const int fd, const short which, Server *s)
{
    ...
    c->sock.f = (Handle)prothandle;
    c->sock.fd = cfd;

    // 把cfd加入到事件监控队列中,监控该cfd的读事件
    r = sockwant(&c->sock, 'r'); 
    ...
}

回调函数设置完成后,还需要把完成连接的cfd加入到事件处理机制中,来处理该cfd的读/写的请求。

进入命令处理函数

static void
prothandle(Conn *c, int ev)
{
    h_conn(c->sock.fd, ev, c);
}

读取客户端命令,并处理

以下函数处理连接的状态,若读取正确,调用do_cmd处理命令。

static void
h_conn(const int fd, const short which, Conn *c)
{
    ...
    conn_data(c);
    while (cmd_data_ready(c) && (c->cmd_len = cmd_len(c))) do_cmd(c);
    ...
}

总结

本文总结了beanstalk的命令处理整个流程。可见,beanstalk的代码简洁,易懂,代码风格也很好。具体的命令实现,请看下回分解。