Documentation ¶
Overview ¶
Package goro provides utilities for spawning and subsequently managing the liftime(s) of one or more goroutines. This package relies heavily on the context package to provide consistent cancellation semantics for long-lived goroutines. The goal of this package is to provide a unified way to cancel and wait on running goroutines as is often seen in "service" or "daemon" types with Start()/Stop() lifecycle functions and to unify the multiplicity of approaches that have been adopted over time.
Note: If you're looking for a short-lived (e.g. request-scoped) group of transient goroutines, you probably want `errgroup.Group` from https://golang.org/x/sync/errgroup.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Group ¶ added in v1.13.0
type Group struct {
// contains filtered or unexported fields
}
Group manages a set of long-running goroutines. Goroutines are spawned individually with Group.Go and after that interrupted and waited-on as a single unit. The expected use-case for this type is as a member field of a `common.Daemon` (or similar) type that spawns one or more goroutines in its Start() function and then stops those same goroutines in its Stop() function. The zero-value of this type is valid. A Group must not be copied after first use.
Example ¶
// The MIT License // // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. // // Copyright (c) 2020 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. package main import ( "context" "fmt" "time" "go.temporal.io/server/internal/goro" ) type ExampleService struct { gorogrp goro.Group // goroutines managed in here } func (svc *ExampleService) Start() { // launch two background goroutines svc.gorogrp.Go(svc.backgroundLoop1) svc.gorogrp.Go(svc.backgroundLoop2) } func (svc *ExampleService) Stop() { // stop all goroutines in the goro.Group svc.gorogrp.Cancel() // interrupt the background goroutines svc.gorogrp.Wait() // wait for the background goroutines to finish } func (svc *ExampleService) backgroundLoop1(ctx context.Context) error { fmt.Println("starting backgroundLoop1") defer fmt.Println("stopping backgroundLoop1") for { select { case <-time.After(1 * time.Minute): // do something every minute case <-ctx.Done(): return nil } } } func (svc *ExampleService) backgroundLoop2(ctx context.Context) error { fmt.Println("starting backgroundLoop2") defer fmt.Println("stopping backgroundLoop2") for { select { case <-time.After(10 * time.Second): // do something every 10 seconds case <-ctx.Done(): return nil } } } func main() { var svc ExampleService svc.Start() svc.Stop() // it is safe to call svc.Stop() multiple times svc.Stop() svc.Stop() svc.Stop() }
Output: starting backgroundLoop1 starting backgroundLoop2 stopping backgroundLoop1 stopping backgroundLoop2
func (*Group) Cancel ¶ added in v1.13.0
func (g *Group) Cancel()
Cancel cancels the `context.Context` that was passed to all goroutines spawned via `Go` on this `Group`.
func (*Group) Go ¶ added in v1.13.0
Go spawns a goroutine whose lifecycle will be managed via this Group object. All functions passed to Go on the same instance of Group will be given the same `context.Context` object, which will be used to indicate cancellation. If the supplied func does not abide by `ctx.Done()` of the provided `context.Context` then `Wait()` on this `Group` will hang until all functions exit on their own (possibly never).
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle is a threadsafe and multi-stop safe handle to a single running goroutine.
Example ¶
package main import ( "context" "fmt" "go.temporal.io/server/internal/goro" ) func main() { h := goro.Go(context.Background(), func(ctx context.Context) error { <-ctx.Done() fmt.Println("shutting down") return ctx.Err() }) fmt.Println(h.Err()) h.Cancel() <-h.Done() fmt.Println(h.Err()) }
Output: <nil> shutting down context canceled
func Go ¶
Go launches the supplied function in its own goroutine and returns back a *Handle that serves as a handle to the goroutine itself.
func (*Handle) Cancel ¶
func (h *Handle) Cancel()
Cancel requests that this goroutine stop by cancelling the associated context object. This function is threadsafe and idempotent. Note that this function _requests_ termination, it does not forcefully kill the goroutine.