nats-io / nats-server

High-Performance server for NATS.io, the cloud and edge native messaging system.
https://nats.io
Apache License 2.0
15.94k stars 1.41k forks source link

Graceful shutdown on windows without installing as service #3809

Closed choofy closed 1 year ago

choofy commented 1 year ago

Feature Request

As software developer who wants to integrate the nats executable in his own product, so that his own product is "batteries included" without the user having to install Nats separately, I want to be able to stop Nats gracefully from my product, so that I do not see messages dropped anymore when I kill Nats on windows.

On Linux, it is possible to kill a process gracefully using signals, but that does not work on windows.

Use Case:

Graceful stop of Nats on windows without having to install it as a service.

Proposed Change:

Who Benefits From The Change(s)?

Alternative Approaches

BentTranberg commented 1 year ago

I'm not a NATS developer. Just a developer using NATS.

Can this be solved with any predefined messages in NATS?

so that I do not see messages dropped anymore when I kill Nats on windows.

What exactly do you mean when you say you kill NATS on Windows? How do you start, run and stop NATS? Do you run it as a child process within your app? Are messages also dropped if you just close a NATS that was started manually? Which programming language and runtime platform is this? Asking in case me or anybody else out there should try to find a solution for the situation - a solution that does not involve modifying NATS.

I think the mechanism described in "Proposed Change" looks like the kind of hack we'd rather not see in a professional product like NATS, but the --signal stop also working for NATS in console mode would be nice.

NATS server could also hold on to a named mutex while running, and that mutex would only be created if a parameter like --mutex myMutex is supplied. I guess this would be a Windows only mechanism. Utilities or your own programs could then wait for the mutex to be released at the termination of NATS. This would only be in effect if that parameter is specified, so would not jeopardize existing deployments of NATS.

tbeets commented 1 year ago

Understand the functionality desire @choofy .

The root issue re-emerges at some regularity. Windows, not being UNIX, fundamentally has a different architecture (multiple actually) for process signaling.

Console applications in Windows (as NATS is generally when not configured as a Windows service) suffer from intractable "console group limitations" mentioned in root issue.

If running NATS as a Windows service doesn't work for your application, recommendation is to wrap NATS and execute as an embedded server. Here's an example. In this manner, you have a pointer to the server and can manage lifecycle in a way that fits your specific need (including bespoke up/down/reload mechanism, etc. that you implement).

tbeets commented 1 year ago

Recommendation to leverage existing feature to install NATS server as a Windows service or implement application-specific server lifecycle using NATS embedded server technique.

choofy commented 1 year ago

Dear Todd,

Thank you for yor reply and code examples. It still feels a bit awkward that in order to gracefully stop an application on windows, I have to 'hack around' and create my own loader (basically, create my own application that uses your nats implementation -- when I understand you correctly).

Your proposed solution would be acceptable to me if Nats would, in addition to the executables, also officially build and publish .so/.dll files so that I would not have to do that myself.

But your current solution is not something that works for me, I just want to use NATS, I do not want to develop it.

As @BentTranberg mentions, it would be expected from a professional product like NATS that the --signal stop also works on standalone windows programs (without services) like it does on Linux. It feels too easy to get away with that by just saying "create your own copy of Nats and embed it in your software".

How about his proposal of using a Mutex for that on windows? I like that proposal. No messing around on file systems. Just:

All it requires is a NATS goroute that awaits the mutex and initiates the graceful stop. Seems like little more than a one-liner.

I believe this is a rather elegant solution, with almost no code changes, that would greatly enhance the use cases for Nats. Not many people will create an "embedded server" themselves, that just is too much hassle for everyone that is not really familiar with go.

@tbeets Although you already closed the ticket, please (re)consider this suggestion.