# wink **Repository Path**: oscstudio/wink ## Basic Information - **Project Name**: wink - **Description**: Wink is oscstudio library - **Primary Language**: C++ - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-01-11 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 码云基础服务工具包 在开发服务程序时,我们通常需要支持解析用户参数,以 daemon 的方式运行,还有支持日志, 对于一些特定的场景,我们还要支持自动重启,异常退出追踪。不同的服务都需要实现一套, 非常麻烦,而 wink 库则是解决这一问题。 ## 命令行模板 `wink::ProcessArgvTemplate` 类是命令行模板类,当用户使用时,需要实现以下几个函数: + usage 打印用户帮助信息并退出,-? -h --help 命令行参数开启。 + version 打印版本信息并退出,-v --version ,当参数中含有 --quiet(-q) 不打印详细版本信息。 + appinitialize 传入标记的配置文件路径(可能是 null),用户需要自己规划和解析。 + daemonizetask -s (--signal) 用户自定义。 + daemonize -D (--daemon) daemon 实现代码。 当输入参数 -d (--debug) 时,标记为 DebugModel ,用户可以根据自己需要,自行设置。 ```c++ 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](./example/argv_example.cc) ## 文件系统简单抽象 在开发服务器程序时,需要支持默认配置,对于配置文件我们优先选择用户使用 `-c (--config)` 指定的 配置文件,而后是当前目录的配置文件,最后是安装目录的配置 `config` 目录下的配置文件,如果利用 nginx 一样的机制,即在编译时就设置好 PREFIX ,这样导致无法平滑的移动到不同机器不同目录, 所以我们利用 可执行程序自身目录来解析配置文件,对于 OSX FreeBSD Linux, 获取可执行程序的自身路径不尽相同,所以我们写了抽象函数来支持这些。在 [dotnet/coreclr](https://github.com/dotnet/coreclr/blob/master/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp#L44) 中有 GetEntrypointExecutableAbsolutePath ,我们将其移植过来,并加以整合。 当然还有一些其他的文件系统函数。可以查看 [fs.hpp](./include/wink/fs.hpp) ## 守护进程和函数栈追踪 wink 支持守护进程,分别支持守护进程的创建,停止和重启,daemon 退出调用函数,改变进程标题(也就是修改 ps 显示,在 Linux 系统下是 /proc/$PID/cmdline),设置函数栈追踪(在遇到 SIGSEGV,SIGABRT 信号时打印函数栈),函数声明如下 ```c++ #include #include #include #include namespace wink { using DaemonizeCall = std::function; 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](./example/asio_server) 平滑重启意味着子进程接受到信号后并不会退出,而是关闭监听套接字,然后等待所有请求处理完毕,因此可能因为其他原因,进程无法正常的结束,一直存活,虽然不会影响到新的进程工作,但是还是需要处理。 wink 给旧的进程设置了定时器,当定时器超时后,将会结束就进程,默认情况下定时器超时为 `480s`,用户完全可以使用如下操作修改定时器参数。 ```cmake add_compile_options("-DGRACEFUL_DELAYTIME=120") ``` ## Wink 守护进程 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](https://github.com/sheredom/utf8.h) | | cpptoml | [https://github.com/skystrife/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| ## License Wink 使用 MIT License. 一些第三方源文件请查看 [Other Licenses](./licenses/otherlicenses.md)