拓扑查询(7)
xsServerFind 返回带引用的租约,必须配对 xsServerRelease;枚举回调的参数只在回调内借用,保存前必须 xsServerRetain。host 由其 server lease 共同保护。xsServerFind 查询
按全局唯一名查找 server,返回 retained lease。
XS_ServerInfo* pSrv = xsServerFind("demo");
if ( pSrv != NULL ) {
/* 使用拓扑信息 ... */
xsServerRelease(pSrv);
}
xsServerRetain / xsServerRelease 查询
延长 server lease / 归还引用。连接存续期、枚举回调外保存前都要 Retain。
xsHostFind 查询
在 server 内按名查找 host;结果由传入的 server lease 共同保护(不需要单独 release)。
xsEnumServers / xsEnumHosts 查询
枚举全部 server / 某 server 的全部 host。参数只在回调内借用。
static bool PrintServer(XS_ServerInfo* pServer, void* pUserData)
{
printf("server: %s (%s)\n", pServer->Name, pServer->Class);
return true; /* 继续枚举 */
}
xsEnumServers(PrintServer, NULL);
xsConfigRoot 查询
返回 xs.json 顶层 Custom(非预设字段的全部内容),供应用读取自定义旋钮。
热重载(7)
reload 是期望状态协调任务,不是同步命令。终态机:ACCEPTED → PREPARING → SUCCEEDED / FAILED / SUPERSEDED / CANCELLED;同 server 新意图覆盖未执行的旧意图,pending 上限 64。
xsReloadHostSubmit 重载
提交一个 host 的重载意图(以所属 server 为发布单元)。
xsReloadServerSubmit 重载
按名称提交整个 server 的重载意图。
xsReloadAllSubmit 重载
整批事务:全部 server 的候选预编译,任何失败整体回滚。
xsReloadQuery 重载
查询意图终态;结果含内容指纹 Revision 与目标描述。
| XS_ReloadResult 字段 | 说明 |
|---|---|
Id / State | 意图 ID 与七态之一 |
Revision | 不可变输入快照的内容指纹(无配置输入时含脚本指纹) |
Target[160] / Message[256] | 目标描述与结果消息(失败原因) |
XS_ReloadId iId = xsReloadHostSubmit(pHost);
XS_ReloadResult tRes;
if ( iId != 0 && xsReloadQuery(iId, &tRes) )
printf("reload #%llu: %d\n",
(unsigned long long)tRes.Id, (int)tRes.State);
xsReloadHost / xsReloadServer / xsReloadAll 重载
bool 兼容包装——只表示 Submit 是否返回非零,不等待终态。
定时器(2)
xsTimerAfter 定时器
一次性定时器,绑定 owner 所属 generation——换代自动作废旧代定时器,不会打进新代。
static void OnTick(void* pUserData)
{
printf("tick: %s\n", (const char*)pUserData);
}
/* ServiceInit 里:5 秒后触发一次 */
(void)xsTimerAfter(pHost, 5000, OnTick, "hello");
xsTimerCancel 定时器
取消定时器。已触发或换代作废的 ID 返回 false。
部署与嵌套(3)
xsAppPath 部署
应用(可执行文件)目录,UTF-8——与配置目录一致,是解析相对路径的锚点。
xsExtensionEnabled 部署
按注册表名(= build 参数名,与启动横幅/--version 一致)查询本变体是否编入某扩展。大小写不敏感;requires 展开的依赖项同样可见;未知名/空串/NULL 返回 false 且不设置错误。编译期等价写法是 #ifdef XS_USE_<名>。
if ( xsExtensionEnabled("sqlite") ) {
/* 本宿主编入了 sqlite,可直接使用 */
db_open(&db);
} /* 查询不编入则走替代路径 */
xsExtensionCount / xsExtensionName 部署
枚举本变体编入的扩展:count 返回数量,name 按下标取名字(= build 参数名,与启动横幅/--version 同一数据源)。返回静态常量的借用指针,进程期内有效、无需释放;越界返回 NULL 且不设置错误。default 变体下 count 为 0;枚举出的名字喂给 xsExtensionEnabled 必为 true。
for ( uint32 i = 0; i < xsExtensionCount(); i++ ) {
printf("%u: %s
", i, xsExtensionName(i));
}
xsCreateTCC / xsDestroyTCC 嵌套
创建预置好标准 include/lib 路径与符号导入的嵌套编译器——应用层插件系统的地基。
状态交接(1)
xsSwapTake 交接
仅在新代 ServiceInit 内有效:取走旧代 ServiceSwap 导出的快照。无交接数据返回 NULL。
static void ServiceInit(XS_HostInfo* pHost)
{
xvalue* pState = xsSwapTake(pHost);
if ( pState != NULL ) {
G_iCounter = xrtValueInt64(
xrtValueObjectGet(pState, "counter"));
xrtValueRelease(pState); /* 取走后自己释放 */
}
}
TLS 证书热替换(1)
xsTlsRefresh 证书热替换
对指定 server 重新读取证书并原子热替换:不重启进程、不触发脚本重载、不断开存量连接。新连接立即使用新证书(含 SNI per-host 证书)。与 xacme 组合即全自动续签闭环——签发完成后调用本 API 完成无感切换。
/* xacme 签发新证书到磁盘后 */
if ( !xsTlsRefresh("main", aErr, sizeof(aErr)) )
printf("refresh failed: %s\n", aErr);
/* 成功后新连接即用新证书;存量连接不受影响 */