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

svc: support closing via context #13

Merged
merged 2 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion svc/svc.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package svc

import "os/signal"
import (
"context"
"os/signal"
)

// Create variable signal.Notify function so we can mock it in tests
var signalNotify = signal.Notify
Expand All @@ -27,6 +30,13 @@ type Service interface {
Stop() error
}

// Context interface contains an optional Context function which a Service can implement.
// When implemented the context.Done() channel will be used in addition to signal handling
// to exit a process.
type Context interface {
Context() context.Context
}

// Environment contains information about the environment
// your application is running in.
type Environment interface {
Expand Down
13 changes: 11 additions & 2 deletions svc/svc_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

// Run runs your Service.
//
// Run will block until one of the signals specified in sig is received.
// Run will block until one of the signals specified in sig is received or a provided context is done.
// If sig is empty syscall.SIGINT and syscall.SIGTERM are used by default.
func Run(service Service, sig ...os.Signal) error {
env := environment{}
Expand All @@ -27,7 +27,16 @@ func Run(service Service, sig ...os.Signal) error {

signalChan := make(chan os.Signal, 1)
signalNotify(signalChan, sig...)
<-signalChan

var doneChan <-chan struct{}
if s, ok := service.(Context); ok {
doneChan = s.Context().Done()
}

select {
case <-signalChan:
case <-doneChan:
}

return service.Stop()
}
Expand Down