Skip to content

Commit

Permalink
Export functions to shut down the process ungracefully
Browse files Browse the repository at this point in the history
Those are useful in more places than just the platform specific entry points.

PiperOrigin-RevId: 686506254
  • Loading branch information
torsm authored and copybara-github committed Oct 16, 2024
1 parent 188f43b commit ad7fc07
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 18 deletions.
22 changes: 14 additions & 8 deletions fleetspeak/src/client/entry/entry_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"syscall"
"time"

"github.com/google/fleetspeak/fleetspeak/src/common/fscontext"

log "github.com/golang/glog"
)

Expand All @@ -28,15 +30,10 @@ func RunMain(innerMain InnerMain, _ /* windowsServiceName */ string) {
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

context.AfterFunc(ctx, func() {
log.Info("Main context stopped, shutting down...")
time.AfterFunc(shutdownTimeout, func() {
if err := dumpProfile(*profileDir, "goroutine", 2); err != nil {
log.Errorf("Failed to dump goroutine profile: %v", err)
}
log.Exitf("Fleetspeak failed to shut down in %v. Exiting ungracefully.", shutdownTimeout)
})
stop := fscontext.AfterDelayFunc(ctx, shutdownTimeout, func() {
ExitUngracefully(fmt.Errorf("process did not exit within %s", shutdownTimeout))
})
defer stop()

cancelSignal := notifyFunc(func(si os.Signal) {
runtime.GC()
Expand Down Expand Up @@ -83,6 +80,15 @@ func notifyFunc(callback func(os.Signal), signals ...os.Signal) func() {
}
}

// ExitUngracefully can be called to exit the process after a failed attempt to
// properly free all resources.
func ExitUngracefully(cause error) {
if err := dumpProfile(*profileDir, "goroutine", 2); err != nil {
log.Errorf("Failed to dump goroutine profile: %v", err)
}
log.Exitf("Exiting ungracefully due to %v", cause)
}

// dumpProfile writes the given pprof profile to disk with the given debug flag.
func dumpProfile(profileDir, profileName string, pprofDebugFlag int) error {
profileDumpPath := filepath.Join(profileDir, fmt.Sprintf("fleetspeakd-%s-pprof-%d-%v", profileName, os.Getpid(), time.Now().Format("2006-01-02-15-04-05.000")))
Expand Down
24 changes: 14 additions & 10 deletions fleetspeak/src/client/entry/entry_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ package entry
import (
"context"
"errors"
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"

log "github.com/golang/glog"
"github.com/google/fleetspeak/fleetspeak/src/common/fscontext"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/svc"
)
Expand All @@ -30,7 +31,10 @@ func (m *fleetspeakService) Execute(args []string, r <-chan svc.ChangeRequest, c
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

enforceShutdownTimeout(ctx)
stop := fscontext.AfterDelayFunc(ctx, shutdownTimeout, func() {
ExitUngracefully(fmt.Errorf("process did not exit within %s", shutdownTimeout))
})
defer stop()

sighupCh := make(chan os.Signal, 1)
defer close(sighupCh)
Expand Down Expand Up @@ -84,7 +88,10 @@ func (m *fleetspeakService) ExecuteAsRegularProcess() {
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()

enforceShutdownTimeout(ctx)
stop := fscontext.AfterDelayFunc(ctx, shutdownTimeout, func() {
ExitUngracefully(fmt.Errorf("process did not exit within %s", shutdownTimeout))
})
defer stop()

err := m.innerMain(ctx, nil)
if err != nil {
Expand All @@ -108,13 +115,10 @@ func RunMain(innerMain InnerMain, windowsServiceName string) {
}
}

func enforceShutdownTimeout(ctx context.Context) {
context.AfterFunc(ctx, func() {
log.Info("Main context stopped, shutting down...")
time.AfterFunc(shutdownTimeout, func() {
log.Exitf("Fleetspeak failed to shut down in %v. Exiting ungracefully.", shutdownTimeout)
})
})
// ExitUngracefully can be called to exit the process after a failed attempt to
// properly free all resources.
func ExitUngracefully(cause error) {
log.Exitf("Exiting ungracefully due to %v", cause)
}

// tryDisableStderr redirects [os.Stderr] to [os.DevNull]. When running as a
Expand Down

0 comments on commit ad7fc07

Please sign in to comment.