Repository navigation
✨ 新增 sctl service:把 serve 注册为用户级系统服务 - #11
Open
lonelyman0108 wants to merge 2 commits into
Open
lonelyman0108 wants to merge 2 commits into
lonelyman0108 wants to merge 2 commits into
Conversation
sctl serve 只能前台运行,文档让用户自己配置服务管理器却不提供工具,手写定义还容易 和 CLI 的数据目录、监听地址对不上。 - sctl service install|uninstall|start|stop|restart|status:macOS launchd LaunchAgent、 Linux systemd --user、Windows 登录触发的计划任务,不需要管理员权限 - install 固化当前生效的 --data-dir(绝对路径)、--listen-address、非默认 --log-level; 二进制优先用 PATH 里的同一文件,Homebrew 升级后不失效 - 隐藏参数 serve --service:日志只写文件;Windows 上脱离独占的控制台 - 等 daemon 时以控制令牌变化识别新进程;安装前和 start 前遇到已在运行的 daemon 时不启动服务 - schtasks / launchctl 只把非零退出当作“不存在”,命令本身无法运行时如实报错 - spec:docs/specs/2026-10-23-service.md
Member
|
是只适配了linux么?mac/windows是不是也要处理一下 |
Member
|
我晚点去windows里面跑一下 |
|
辛苦哥哥。 哥哥这个sctl原生功能真是太好了,ggnb!!已在本机严肃配置,哈哈哈哈。我现在在本机是用一个每 2 分钟的计划任务轮询 |
在 Windows 11 真机上验证发现: - restart 和覆盖安装只靠 /Run 配 StopExisting,任务计划程序停掉旧实例后立刻启动新实例,新实例绑定端口 失败就退出,服务从此不在运行。/End 约 20ms 返回,旧进程约 1 秒后才退出,所以 stop、uninstall、restart 和覆盖安装结束实例后都等监听地址能被绑定(/End 前地址就空着时不等),再按需 /Run;不等的话 stop 后紧接着 start 会把还没退出的旧实例当成在运行,什么都不启动。MultipleInstancesPolicy 改为 IgnoreNew - RestartOnFailure 不会拉起启动后崩溃的 daemon(强制结束后 3 分钟内没有重新运行),删掉它,cli.md 与 spec 改为如实说明 Windows 上崩溃后要 sctl service start - service.New 接收监听地址 - logging 测试在 Windows 上死锁:对管道 Sync(FlushFileBuffers)会阻塞到读端读完,读端改为并行;日志文件 句柄不关闭,Windows 上不用 t.TempDir - TestLaunchd 的期望路径按宿主平台拼接
Member
|
在一台 Windows 11(Build 26200)真机上把这个 PR 跑了一遍,修复已推到本分支(69b17b0)。 发现的问题
修复
修复后真机验证(隔离数据目录与端口)
遗留
|
|
辛苦哥哥,ggnb!! 哥哥说的这个「给 sctl 任务加重复触发器」。我实际是另开了一个任务轮询端口,跟 sctl 任务分开的,所以 stop 语义那个问题我这边是用 哥哥说的这个「进程活着只是不响应」确实我漏了。原来 Stop 完固定睡 2 秒再 Start。现在改成两个条件都满足才继续: $released = $false
for ($i = 0; $i -lt 40; $i++) {
$state = Get-State # 任务状态
$busy = Test-Port -P $port # 端口占用
if ($state -ne 'Running' -and -not $busy) { $released = $true; break }
Start-Sleep -Milliseconds 500
}
if (-not $released) {
# 20 秒还没释放,记一笔跳过这轮,下轮再说
return
}
Start-ScheduledTask -TaskName 'sctl serve'任务得不再是 Running(否则
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


背景
sctl serve只能在前台运行。文档让用户“交给系统服务管理器”,但没有提供工具;手写的服务定义也容易和 CLI 的数据目录、监听地址对不上。Spec:docs/specs/2026-10-23-service.md。改动
sctl service install|uninstall|start|stop|restart|status~/Library/LaunchAgents/com.scriptscat.sctl.plist)~/.config/systemd/user/sctl.service,按绝对路径 enable)StopExisting)install固化本次调用实际生效的--data-dir(转成绝对路径,包括来自SCTL_DATA_DIR的)、--listen-address和非默认的--log-level。二进制路径优先用PATH里的同一个文件,Homebrew 升级后服务不会失效。serve --service:日志只写<data dir>/logs,stderr 只留给运行时崩溃信息;Windows 上进程独占控制台时脱离它。install前和start前,只要已有 daemon 能连上(包括其他数据目录的 daemon),就不再启动服务。control.Address()/control.Healthy(),logging.Setup增加toStderr参数。验证
go build/vet ./...(含GOOS=windows)、go test ./... -race通过;golangci-lint 在 darwin/linux/windows 三个平台上都是 0 issues。kill -9:1 秒内被拉起service.stderr.log为 0 字节,日志只写 sctl.logstart报告已在运行、不启动服务,restart退出码 3,不误报成功~/Documents下时,launchd 启动的进程会被 macOS 隐私保护(TCC)卡住,cli.md 已写明。未验证 / 已知限制
RestartOnFailure是否能拉起启动后才崩溃的 daemon 没有确认;文档如实写了,建议崩溃后用sctl service start。brew services二选一(同一个端口),文档已说明。已按 review 修正:
waitDaemon误报成功、安装前检查依赖令牌、schtasks 吞错误、/End与/Run的竞态、bootstrap 重试窗口太短、XDG_CONFIG_HOME不一致、ProcessType=Background、uninstall 报告不准、--log-level帮助文字过时。