beanstalk源码剖析——文件结构和启动程序
1. 文件结构组织
beanstalk的源码文件物理组织如下:
makefile文件:Makefile
数据结构定义: dat.h
主程序: main.c
Server实例: serv.c
协议处理: prot.c
连接管理: conn.c
tube管理: tube.c
job管理: job.c
集合管理: ms.c
daemon监听端口: net.c
epoll抽象: linux.c
堆操作: heap.c
daemon框架: sd-daemon.h sd-daemon.c
binlog处理: file.c walg.c
系统时间: time.c
rehash用的质数: primes.c
辅助工具: util.c
freebsd支持: darwin.c freebsd.c
版本处理: verc.sh vers.sh
测试程序: testjobs.c testheap.c testserv.c testutil.c
文档文件: LICENSE README
adm:系统管理工具
launchd Readme systemd upstart
ct:测试工具
ct.c ct.h gen internal.h License
doc:文档
beanstalkd.1 beanstalkd.1.html beanstalkd.ronn protocol.md protocol.txt
pkg:其他辅助工具
beanstalkd.spec.in bloghead.in dist.sh mail.sh newstail.in
2. 启动程序
启动程序和普通的命令行程序的结构一致,这一部分也可以采用第三方库。这里作者为了避免对第三方程序的依赖,采用了自己实现。
int main(int argc, char **argv) { int r; struct job list = {}; progname = argv[0]; setlinebuf(stdout); //设置行缓冲 optparse(&srv, argv+1); //解析输入参数 if (verbose) { printf("pid %d\n", getpid()); } //绑定监听端口 r = make_server_socket(srv.addr, srv.port); if (r == -1) twarnx("make_server_socket()"), exit(111); srv.sock.fd = r; //初始化协议 prot_init(); //切换用户,处理信号 if (srv.user) su(srv.user); set_sig_handlers(); //日志初始化移到wal.c模块会更清晰一些 if (srv.wal.use) { // We want to make sure that only one beanstalkd tries // to use the wal directory at a time. So acquire a lock // now and never release it. if (!waldirlock(&srv.wal)) { twarnx("failed to lock wal dir %s", srv.wal.dir); exit(10); } list.prev = list.next = &list; walinit(&srv.wal, &list); r = prot_replay(&srv, &list); if (!r) { twarnx("failed to replay log"); return 1; } } //启动Server实例 srvserve(&srv); return 0; }