Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

service(windows): add support for PreShutdown #257

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

saracen
Copy link
Contributor

@saracen saracen commented Feb 2, 2021

This adds support for PreShutdown as described here.

This allows multiple "StopPending" state updates to let Windows know that a service is still shutting down, incrementing a "CheckPoint" to let WIndows know progress is being made. By default, this extends the timeout for stopping a service to 3 minutes.

If more than 3 minutes are required (a database that absolutely requires more time to avoid corruption, for example), the time can be additionally extended by setting the PreshutdownTimeout option during installation of the service.

Modified stopPause as an example:

diff --git a/example/stopPause/main.go b/example/stopPause/main.go
index ec7d598..313c0f3 100644
--- a/example/stopPause/main.go
+++ b/example/stopPause/main.go
@@ -27,7 +27,7 @@ func (p *program) run() {
 }
 func (p *program) Stop(s service.Service) error {
        // Stop should not block. Return with a few seconds.
-       <-time.After(time.Second * 13)
+       <-time.After(5 * time.Minute)
        return nil
 }

@@ -36,6 +36,9 @@ func main() {
                Name:        "GoServiceExampleStopPause",
                DisplayName: "Go Service Example: Stop Pause",
                Description: "This is an example Go service that pauses on stop.",
+               Option: map[string]interface{}{
+                       "PreshutdownTimeout": 1000 * 60 * 60,
+               },
        }

        prg := &program{}

Without PreshutdownTimeout, Stop() will only survive 3 minutes. With PreshutdownTimeout extended to an hour, Stop() will exit after 5 minutes.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 12.799% when pulling 4956c89 on saracen:preshutdown into ef35c56 on kardianos:master.

@saracen
Copy link
Contributor Author

saracen commented Feb 2, 2021

@kardianos for additional context, we need this for GitLab's Runner. Runner has jobs running that we don't immediately want to terminate, some of them can take a really long time, so ideally we'd want to block until they're complete.

@kardianos
Copy link
Owner

The defaults aren't good here. Maybe could add a configuration options, but not 5 min timeout by default.

@saracen
Copy link
Contributor Author

saracen commented Oct 10, 2022

@kardianos

The defaults aren't good here. Maybe could add a configuration options, but not 5 min timeout by default.

What 5 minute timeout are you referring to? If it's the above stopPause code snippet, that's just an example of an application not wanting to be shut down after the default 3 minutes that exists now. Setting PreshutdownTimeout will allow this to be exceeded, but defaults to zero.

@Ahuge
Copy link

Ahuge commented Oct 25, 2022

This is exactly the PR that I have been looking for!

I have a cleanup service that needs to happen and may take up to a few minutes to fully complete. Being able to setup the PreShutdownInfo seems like the correct solution from MS.

I was doing research into this so here are some additional docs for @kardianos in case context is needed.

Talking about allowing windows services and how to allow for longer shutdown times, this talks about globally and per-service (PreShutdownTimeout).
https://www.coretechnologies.com/blog/windows-services/increase-shutdown-time/

MS page on the SERVICE_PRESHUTDOWN_INFO struct: https://learn.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_preshutdown_info.

Thank you @saracen for proposing this!

@Ahuge
Copy link

Ahuge commented Oct 25, 2022

If it makes it any easier, I have done a rebase of this code on top of master so that there are no conflicts.

You can see that branch here: https://github.com/Ahuge/service/tree/ah/feature/windows-preshutdown

@saracen
Copy link
Contributor Author

saracen commented May 20, 2023

@kardianos I've resolved the merge conflicts with this one.

Please see my previous comment in regards to the 5 minute default concern.

@shrinidhi111
Copy link

shrinidhi111 commented Sep 6, 2023

Is there a specific code I can run in this PreShutDown state?

So I can add a log like "entering preshutdown" ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants