Browse code

Move Go() promise-like func from utils to pkg/promise

This is the first of two steps to break the archive package's dependence
on utils so that archive may be moved into pkg. Also, the `Go()`
function is small, concise, and not specific to the docker internals, so
it is a good candidate for pkg.

Signed-off-by: Rafe Colton <rafael.colton@gmail.com>

Rafe Colton authored on 2014/09/30 15:16:27
Showing 8 changed files
... ...
@@ -33,6 +33,7 @@ import (
33 33
 	flag "github.com/docker/docker/pkg/mflag"
34 34
 	"github.com/docker/docker/pkg/parsers"
35 35
 	"github.com/docker/docker/pkg/parsers/filters"
36
+	"github.com/docker/docker/pkg/promise"
36 37
 	"github.com/docker/docker/pkg/signal"
37 38
 	"github.com/docker/docker/pkg/term"
38 39
 	"github.com/docker/docker/pkg/timeutils"
... ...
@@ -648,7 +649,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
648 648
 		v.Set("stdout", "1")
649 649
 		v.Set("stderr", "1")
650 650
 
651
-		cErr = utils.Go(func() error {
651
+		cErr = promise.Go(func() error {
652 652
 			return cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), tty, in, cli.out, cli.err, nil, nil)
653 653
 		})
654 654
 	}
... ...
@@ -2220,7 +2221,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
2220 2220
 			}
2221 2221
 		}
2222 2222
 
2223
-		errCh = utils.Go(func() error {
2223
+		errCh = promise.Go(func() error {
2224 2224
 			return cli.hijack("POST", "/containers/"+runResult.Get("Id")+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil)
2225 2225
 		})
2226 2226
 	} else {
... ...
@@ -2477,7 +2478,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
2477 2477
 			stderr = cli.err
2478 2478
 		}
2479 2479
 	}
2480
-	errCh = utils.Go(func() error {
2480
+	errCh = promise.Go(func() error {
2481 2481
 		return cli.hijack("POST", "/exec/"+execID+"/start", execConfig.Tty, in, out, stderr, hijacked, execConfig)
2482 2482
 	})
2483 2483
 
... ...
@@ -14,9 +14,9 @@ import (
14 14
 	"github.com/docker/docker/api"
15 15
 	"github.com/docker/docker/dockerversion"
16 16
 	"github.com/docker/docker/pkg/log"
17
+	"github.com/docker/docker/pkg/promise"
17 18
 	"github.com/docker/docker/pkg/stdcopy"
18 19
 	"github.com/docker/docker/pkg/term"
19
-	"github.com/docker/docker/utils"
20 20
 )
21 21
 
22 22
 func (cli *DockerCli) dial() (net.Conn, error) {
... ...
@@ -78,7 +78,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
78 78
 	}
79 79
 
80 80
 	if stdout != nil || stderr != nil {
81
-		receiveStdout = utils.Go(func() (err error) {
81
+		receiveStdout = promise.Go(func() (err error) {
82 82
 			defer func() {
83 83
 				if in != nil {
84 84
 					if setRawTerminal && cli.isTerminalIn {
... ...
@@ -104,7 +104,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
104 104
 		})
105 105
 	}
106 106
 
107
-	sendStdin := utils.Go(func() error {
107
+	sendStdin := promise.Go(func() error {
108 108
 		if in != nil {
109 109
 			io.Copy(rwc, in)
110 110
 			log.Debugf("[hijack] End of stdin")
... ...
@@ -23,6 +23,7 @@ import (
23 23
 	imagepkg "github.com/docker/docker/image"
24 24
 	"github.com/docker/docker/pkg/log"
25 25
 	"github.com/docker/docker/pkg/parsers"
26
+	"github.com/docker/docker/pkg/promise"
26 27
 	"github.com/docker/docker/pkg/symlink"
27 28
 	"github.com/docker/docker/pkg/system"
28 29
 	"github.com/docker/docker/pkg/tarsum"
... ...
@@ -516,7 +517,7 @@ func (b *Builder) create() (*daemon.Container, error) {
516 516
 func (b *Builder) run(c *daemon.Container) error {
517 517
 	var errCh chan error
518 518
 	if b.Verbose {
519
-		errCh = utils.Go(func() error {
519
+		errCh = promise.Go(func() error {
520 520
 			// FIXME: call the 'attach' job so that daemon.Attach can be made private
521 521
 			//
522 522
 			// FIXME (LK4D4): Also, maybe makes sense to call "logs" job, it is like attach
... ...
@@ -10,6 +10,7 @@ import (
10 10
 	"github.com/docker/docker/pkg/ioutils"
11 11
 	"github.com/docker/docker/pkg/jsonlog"
12 12
 	"github.com/docker/docker/pkg/log"
13
+	"github.com/docker/docker/pkg/promise"
13 14
 	"github.com/docker/docker/utils"
14 15
 )
15 16
 
... ...
@@ -246,7 +247,7 @@ func (daemon *Daemon) Attach(streamConfig *StreamConfig, openStdin, stdinOnce, t
246 246
 		}()
247 247
 	}
248 248
 
249
-	return utils.Go(func() error {
249
+	return promise.Go(func() error {
250 250
 		defer func() {
251 251
 			if cStdout != nil {
252 252
 				cStdout.Close()
... ...
@@ -27,6 +27,7 @@ import (
27 27
 	"github.com/docker/docker/pkg/log"
28 28
 	"github.com/docker/docker/pkg/networkfs/etchosts"
29 29
 	"github.com/docker/docker/pkg/networkfs/resolvconf"
30
+	"github.com/docker/docker/pkg/promise"
30 31
 	"github.com/docker/docker/pkg/symlink"
31 32
 	"github.com/docker/docker/runconfig"
32 33
 	"github.com/docker/docker/utils"
... ...
@@ -1117,7 +1118,7 @@ func (container *Container) waitForStart() error {
1117 1117
 	// process or until the process is running in the container
1118 1118
 	select {
1119 1119
 	case <-container.monitor.startSignal:
1120
-	case err := <-utils.Go(container.monitor.Start):
1120
+	case err := <-promise.Go(container.monitor.Start):
1121 1121
 		return err
1122 1122
 	}
1123 1123
 
... ...
@@ -15,6 +15,7 @@ import (
15 15
 	"github.com/docker/docker/pkg/broadcastwriter"
16 16
 	"github.com/docker/docker/pkg/ioutils"
17 17
 	"github.com/docker/docker/pkg/log"
18
+	"github.com/docker/docker/pkg/promise"
18 19
 	"github.com/docker/docker/runconfig"
19 20
 	"github.com/docker/docker/utils"
20 21
 )
... ...
@@ -254,7 +255,7 @@ func (container *Container) Exec(execConfig *execConfig) error {
254 254
 
255 255
 	// We use a callback here instead of a goroutine and an chan for
256 256
 	// syncronization purposes
257
-	cErr := utils.Go(func() error { return container.monitorExec(execConfig, callback) })
257
+	cErr := promise.Go(func() error { return container.monitorExec(execConfig, callback) })
258 258
 
259 259
 	// Exec should not return until the process is actually running
260 260
 	select {
261 261
new file mode 100644
... ...
@@ -0,0 +1,11 @@
0
+package promise
1
+
2
+// Go is a basic promise implementation: it wraps calls a function in a goroutine,
3
+// and returns a channel which will later return the function's return value.
4
+func Go(f func() error) chan error {
5
+	ch := make(chan error, 1)
6
+	go func() {
7
+		ch <- f()
8
+	}()
9
+	return ch
10
+}
... ...
@@ -30,16 +30,6 @@ type KeyValuePair struct {
30 30
 	Value string
31 31
 }
32 32
 
33
-// Go is a basic promise implementation: it wraps calls a function in a goroutine,
34
-// and returns a channel which will later return the function's return value.
35
-func Go(f func() error) chan error {
36
-	ch := make(chan error, 1)
37
-	go func() {
38
-		ch <- f()
39
-	}()
40
-	return ch
41
-}
42
-
43 33
 // Request a given URL and return an io.Reader
44 34
 func Download(url string) (resp *http.Response, err error) {
45 35
 	if resp, err = http.Get(url); err != nil {