Syncthing: Be able to run Syncthing as a windows service

0

When using the recommended way to set Syncthing up to automatically start and run in background in Windows with Task Scheduler following the official guide under https://docs.syncthing.net/users/autostart.html#autostart-windows-taskschd, ending the task does not stop Syncthing from running in background.

The reason is that Syncthing spawns a sub-process, so that there are two syncthing.exe processes running at the time. The higher one is the monitor process (see https://docs.syncthing.net/users/syncthing.html#cmdoption-no-restart), and only this one is controlled by Task Scheduler. Thus, ending the task only kills the monitor process, but leaves the main one untouched.

I do not think that there is any solution to the problem right now, as running Syncthing with the -no-restart option would prevent automatic updates and other panic recoveries, which I do not think is desirable. On the other hand, the current state makes it impossible to simply shut Syncthing down using Task Scheduler, which is also not good from the user's perspective, i.e. the user thinks that they have made Syncthing exit, while in reality the synchronisation is still going on invisibly in background.

I will think of a possible workaround using Task Scheduler, but with the current monitor-main process construct, there may be none.

tomasz1986 picture tomasz1986  ·  19 Oct 2020

Most helpful comment

2

I think "unless it's a single user machine" covers a very large majority of Windows boxes running Syncthing, and the rest are managed by people who understand the nuances. But it's a side track anyway.

calmh picture calmh  ·  19 Oct 2020

All comments

0

-no-restart does not control if there is a monitor process since quite a while: There always is a monitor process (e.g. for panic handling). And the monitor stops the child process when it gets terminated, so it should work. Looks like whatever the Task Scheduler does to terminate the process does not result in a os.Interrupt signal, but directly terminates the process (equivalent of SIGKILL).
Maybe the culprit is the option "If the running task does not end when requested, force it to stop" and the scheduler is just too impatient when stopping. Could you test if unchecking that helps please.

imsodin picture imsodin  ·  19 Oct 2020
0

Maybe the culprit is the option "If the running task does not end when requested, force it to stop" and the scheduler is just too impatient when stopping. Could you test if unchecking that helps please.

There is no difference, unfortunately. I have just tried, and only the monitor process gets killed regardless of the setting.

-no-restart does not control if there is a monitor process since quite a while: There always is a monitor process (e.g. for panic handling).

I guess then that the information from https://docs.syncthing.net/includes/env-vars.html?highlight=stnorestart is outdated also, right?

tomasz1986 picture tomasz1986  ·  19 Oct 2020
0

I guess then that the information from https://docs.syncthing.net/includes/env-vars.html?highlight=stnorestart is outdated also, right?

Yes it is.

I don't think there's anything we can do here. The best info I found on this says it's not possible and suggest using taskkill instead: https://superuser.com/questions/959364/on-windows-how-can-i-gracefully-ask-a-running-program-to-terminate
A quick search also didn't turn up any option to run a command on stop (to trigger shutdown through the API). Looks like it's simply not capable to gracefully terminate a task. We should probably add a warning about that to the docs.

imsodin picture imsodin  ·  19 Oct 2020
2

The code required to support running as a Windows service isn't enormous; it's basically a couple of start/stop callbacks and there are Go packages for it. Might be an option to implement that ourselves and recommend running as a service instead.

calmh picture calmh  ·  19 Oct 2020
0

The best info I found on this says it's not possible and suggest using taskkill instead

Yeah, it would be nice to be able to run custom commands on task end, but there is no such functionality in Task Scheduler. You would need a second task to poll the state of the first one and act on it, which is convoluted and prone to errors.

We should probably add a warning about that to the docs.

I will try to add the warning sometime this week.

Might be an option to implement that ourselves and recommend running as a service instead.

Service is problematic though. It would need to be run as a per-user service (see https://docs.microsoft.com/en-us/windows/application-management/per-user-services-in-windows), which is available only in Windows 10 and up. Otherwise, a normal service runs system-wide, which is usually not suitable for Syncthing, unless we are talking about a single-user machine. It is also impossible to control services without administrative access, unless you fiddle around with service permissions, which itself requires administrative access to begin with :wink:.

A built-in service functionality would be a replacement/alternative for the current NSSM solution though.

tomasz1986 picture tomasz1986  ·  19 Oct 2020
2

I think "unless it's a single user machine" covers a very large majority of Windows boxes running Syncthing, and the rest are managed by people who understand the nuances. But it's a side track anyway.

calmh picture calmh  ·  19 Oct 2020
1

I took the liberty of repurposing this issue as there is no bug and opened an issue on the docs repo: https://github.com/syncthing/docs/issues/577

imsodin picture imsodin  ·  19 Oct 2020
0

I've also had trouble with the monitor process. I'm using Syncthing as a service wrapped by nssm under LocalService account since a long time. However, nssm has the weakness not being configurable to react on Syncthing's exit codes. To solve problematic "monitor respawns child when child was killed" and "upgrade exits instead of respawning a child process because monitor exits and nssm sees it" I've made a batch script to mimick the Syncthing monitor process behaviour suitably for nssm. ( https://github.com/Catfriend1/syncthing-msi/blob/v1.8.0/Syncthing/syncthing_service.cmd ) nssm starts this script instead of Syncthing and upgrade, restart or user shutdown behaviour is all fine now. Maybe this could also help task scheduler users?

Catfriend1 picture Catfriend1  ·  20 Oct 2020
0

However, nssm has the weakness not being configurable to react on Syncthing's exit codes. To solve problematic "monitor respawns child when child was killed" and "upgrade exits instead of respawning a child process because monitor exits and nssm sees it"

It's been a while since I've run Syncthing on Windows, but the method outlined on step 12 here was always reliable for me during upgrades and graceful shutdowns via Syncthing itself.

ProactiveServices picture ProactiveServices  ·  20 Oct 2020
1

@ProactiveServices cool info, thanks. I didn't know about the nssm cli to configure exit code specific behaviour 👍

Catfriend1 picture Catfriend1  ·  20 Oct 2020
0

Honestly, nssm/FireDaemon both do the job.

Magissia picture Magissia  ·  17 Nov 2020