在开发服务程序时,我们通常需要支持解析用户参数,以 daemon 的方式运行,还有支持日志, 对于一些特定的场景,我们还要支持自动重启,异常退出追踪。不同的服务都需要实现一套, 非常麻烦,而 wink 库则是解决这一问题。
wink::ProcessArgvTemplate
类是命令行模板类,当用户使用时,需要实现以下几个函数:
当输入参数 -d (--debug) 时,标记为 DebugModel ,用户可以根据自己需要,自行设置。
namespace wink {
void ProcessArgvTemplate::usage() {
fprintf(stderr, "hello argv_example usage\n");
}
void ProcessArgvTemplate::version(bool quiet) {
if (quiet) {
fprintf(stderr, "1.0\n");
} else {
fprintf(stderr, "argv_example 1.0\n");
}
}
bool ProcessArgvTemplate::appinitialize(const char* file) {
if (file)
fprintf(stderr, "config file: %s\n", file);
else
fprintf(stderr, "Please search your default config\n");
fprintf(stderr, "saved_ value your can do it some thing\n");
return true;
}
int ProcessArgvTemplate::daemonizetask(const char* sig) {
fprintf(stderr, "-s %s\n", sig);
return 0;
}
bool ProcessArgvTemplate::daemonize() {
/// start a process as a daemon
return true;
}
}
详细的例子在 example/argv_example.cc
在开发服务器程序时,需要支持默认配置,对于配置文件我们优先选择用户使用 -c (--config)
指定的
配置文件,而后是当前目录的配置文件,最后是安装目录的配置 config
目录下的配置文件,如果利用
nginx 一样的机制,即在编译时就设置好 PREFIX ,这样导致无法平滑的移动到不同机器不同目录,
所以我们利用 可执行程序自身目录来解析配置文件,对于 OSX FreeBSD Linux, 获取可执行程序的自身路径不尽相同,所以我们写了抽象函数来支持这些。在 dotnet/coreclr 中有 GetEntrypointExecutableAbsolutePath ,我们将其移植过来,并加以整合。
当然还有一些其他的文件系统函数。可以查看 fs.hpp
wink 支持守护进程,分别支持守护进程的创建,停止和重启,daemon 退出调用函数,改变进程标题(也就是修改 ps 显示,在 Linux 系统下是 /proc/$PID/cmdline),设置函数栈追踪(在遇到 SIGSEGV,SIGABRT 信号时打印函数栈),函数声明如下
#include <string>
#include <algorithm>
#include <functional>
#include <cstdarg>
namespace wink {
using DaemonizeCall = std::function<void()>;
namespace Signal {
enum DeamonizeSignal {
Exit = SIGUSR1, ///
Graceful = SIGUSR2 ///
};
}
bool initialize(const std::string &name, const std::string &pidfile,
std::size_t slaves, const DaemonizeCall &call = {});
#if defined(__linux__) || defined(__CYGWIN__)
void initializetitle(int argc, char** argv);
#else
inline void initializetitle(int argc, char** argv) {}
#endif
bool changetitle(const char *title);
bool symbolize();
bool restart(const std::string &name, const std::string &pidfile,
bool force = true);
bool stop(const std::string &name, const std::string &pidfile);
}; // namespace daemonize
更多的细节可以查看代码。
当支持 -s restart
参数将支持平滑重启,强制重启为 -s restart -f
,当然在调用 daemonize::restart
函数时,可以显式的设置,也可以使用 isforced
变量支持,此变量为 ProcessArgvTemplate
的成员变量。为支持异步信号安全,如 asio 程序需要使用 signal_set 实现平滑重启在 work process 进程中的处理,否则程序会自动退出。
平滑重启代码示例在 example/asio_server
平滑重启意味着子进程接受到信号后并不会退出,而是关闭监听套接字,然后等待所有请求处理完毕,因此可能因为其他原因,进程无法正常的结束,一直存活,虽然不会影响到新的进程工作,但是还是需要处理。
wink 给旧的进程设置了定时器,当定时器超时后,将会结束就进程,默认情况下定时器超时为 480s
,用户完全可以使用如下操作修改定时器参数。
add_compile_options("-DGRACEFUL_DELAYTIME=120")
wink 支持崩溃自动重启,通常来说,崩溃自动重启次数为 200, 但用户可以设置 WINK_CRASH_LIMIT
环境变量去减小或者加大 Wink 的崩溃自动重启限制。
POSIX 系统(FreeBSD,MacOS,NetBSD,Linux)可以在 *.unix.cc
中实现其代码,如果移植到 Windows 可以添加 *.win32.cc
wink 使用了一些第三方组件,下表中有列出:
组件 | URL |
---|---|
utf8.h | https://github.com/sheredom/utf8.h |
cpptoml | https://github.com/skystrife/cpptoml |
clara | https://github.com/catchorg/Clara |
MPark.Variant | https://github.com/mpark/variant |
fmt | https://github.com/fmtlib/fmt |
string-view-lite | https://github.com/martinmoene/string-view-lite |
absl_string_view | https://github.com/abseil/abseil-cpp |
threadpool | https://github.com/llvm-mirror/llvm/blob/master/include/llvm/Support/ThreadPool.h |
blake2 | https://github.com/BLAKE2/libb2 |
rhash-sha3 | https://github.com/rhash/RHash |
Wink 使用 MIT License. 一些第三方源文件请查看 Other Licenses
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。