]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | # run |
2 | ||
3 | [![GoDoc](https://godoc.org/github.com/oklog/run?status.svg)](https://godoc.org/github.com/oklog/run) | |
4 | [![Build Status](https://travis-ci.org/oklog/run.svg?branch=master)](https://travis-ci.org/oklog/run) | |
5 | [![Go Report Card](https://goreportcard.com/badge/github.com/oklog/run)](https://goreportcard.com/report/github.com/oklog/run) | |
6 | [![Apache 2 licensed](https://img.shields.io/badge/license-Apache2-blue.svg)](https://raw.githubusercontent.com/oklog/run/master/LICENSE) | |
7 | ||
8 | run.Group is a universal mechanism to manage goroutine lifecycles. | |
9 | ||
10 | Create a zero-value run.Group, and then add actors to it. Actors are defined as | |
11 | a pair of functions: an **execute** function, which should run synchronously; | |
12 | and an **interrupt** function, which, when invoked, should cause the execute | |
13 | function to return. Finally, invoke Run, which blocks until the first actor | |
14 | returns. This general-purpose API allows callers to model pretty much any | |
15 | runnable task, and achieve well-defined lifecycle semantics for the group. | |
16 | ||
17 | run.Group was written to manage component lifecycles in func main for | |
18 | [OK Log](https://github.com/oklog/oklog). | |
19 | But it's useful in any circumstance where you need to orchestrate multiple | |
20 | goroutines as a unit whole. | |
21 | [Click here](https://www.youtube.com/watch?v=LHe1Cb_Ud_M&t=15m45s) to see a | |
22 | video of a talk where run.Group is described. | |
23 | ||
24 | ## Examples | |
25 | ||
26 | ### context.Context | |
27 | ||
28 | ```go | |
29 | ctx, cancel := context.WithCancel(context.Background()) | |
30 | g.Add(func() error { | |
31 | return myProcess(ctx, ...) | |
32 | }, func(error) { | |
33 | cancel() | |
34 | }) | |
35 | ``` | |
36 | ||
37 | ### net.Listener | |
38 | ||
39 | ```go | |
40 | ln, _ := net.Listen("tcp", ":8080") | |
41 | g.Add(func() error { | |
42 | return http.Serve(ln, nil) | |
43 | }, func(error) { | |
44 | ln.Close() | |
45 | }) | |
46 | ``` | |
47 | ||
48 | ### io.ReadCloser | |
49 | ||
50 | ```go | |
51 | var conn io.ReadCloser = ... | |
52 | g.Add(func() error { | |
53 | s := bufio.NewScanner(conn) | |
54 | for s.Scan() { | |
55 | println(s.Text()) | |
56 | } | |
57 | return s.Err() | |
58 | }, func(error) { | |
59 | conn.Close() | |
60 | }) | |
61 | ``` | |
62 | ||
63 | ## Comparisons | |
64 | ||
65 | Package run is somewhat similar to package | |
66 | [errgroup](https://godoc.org/golang.org/x/sync/errgroup), | |
67 | except it doesn't require actor goroutines to understand context semantics. | |
68 | ||
69 | It's somewhat similar to package | |
70 | [tomb.v1](https://godoc.org/gopkg.in/tomb.v1) or | |
71 | [tomb.v2](https://godoc.org/gopkg.in/tomb.v2), | |
72 | except it has a much smaller API surface, delegating e.g. staged shutdown of | |
73 | goroutines to the caller. |