HotRestartImpl::HotRestartImpl(Options& options) : options_(options), stats_set_options_(blockMemHashOptions(options.maxStats())), shmem_(SharedMemory::initialize( RawStatDataSet::numBytes(stats_set_options_, options_.statsOptions()), options_)), log_lock_(shmem_.log_lock_), access_log_lock_(shmem_.access_log_lock_), stat_lock_(shmem_.stat_lock_), init_lock_(shmem_.init_lock_) { { // We must hold the stat lock when attaching to an existing memory segment // because it might be actively written to while we sanityCheck it. Thread::LockGuard lock(stat_lock_); stats_set_.reset(newRawStatDataSet(stats_set_options_, options.restartEpoch() == 0, shmem_.stats_set_data_, options_.statsOptions())); } my_domain_socket_ = bindDomainSocket(options.restartEpoch()); // 这里计算 child address child_address_ = createDomainSocketAddress((options.restartEpoch() + 1)); initDomainSocketAddress(&parent_address_); if (options.restartEpoch() != 0) { // 这里计算 parent address parent_address_ = createDomainSocketAddress((options.restartEpoch() + -1)); }
// If our parent ever goes away just terminate us so that we don't have to rely on ops/launching // logic killing the entire process tree. We should never exist without our parent. int rc = prctl(PR_SET_PDEATHSIG, SIGTERM); RELEASE_ASSERT(rc != -1, ""); }
defmain(): """ Script main. This script is designed so that a process watcher like runit or monit can watch this process and take corrective action if it ever goes away. """
print("starting hot-restarter with target: {}".format(sys.argv[1]))
# Start the first child process and then go into an endless loop since everything else happens via # signals. fork_and_exec() whileTrue: time.sleep(60)
# ...... # 文件头定义了一个全局变量保存 epoch restart_epoch = 0 # ...... deffork_and_exec(): """ This routine forks and execs a new child process and keeps track of its PID. Before we fork, set the current restart epoch in an env variable that processes can read if they care. """
# 引用全局变量 global restart_epoch # 设置环境变量,主要是为了后续脚本使用 os.environ['RESTART_EPOCH'] = str(restart_epoch) print("forking and execing new child process at epoch {}".format(restart_epoch)) restart_epoch += 1
child_pid = os.fork() if child_pid == 0: # Child process # 执行脚本 os.execl(sys.argv[1], sys.argv[1]) else: # Parent process print("forked new child process with PID={}".format(child_pid)) # 将 pid 保存起来,退出时全部 kill 掉 pid_list.append(child_pid)