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>
This commit is contained in:
Rafe Colton 2014-09-29 23:16:27 -07:00
parent 8128339bc8
commit b845a62149
8 changed files with 26 additions and 20 deletions

View File

@ -33,6 +33,7 @@ import (
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/pkg/timeutils"
@ -648,7 +649,7 @@ func (cli *DockerCli) CmdStart(args ...string) error {
v.Set("stdout", "1")
v.Set("stderr", "1")
cErr = utils.Go(func() error {
cErr = promise.Go(func() error {
return cli.hijack("POST", "/containers/"+cmd.Arg(0)+"/attach?"+v.Encode(), tty, in, cli.out, cli.err, nil, nil)
})
}
@ -2220,7 +2221,7 @@ func (cli *DockerCli) CmdRun(args ...string) error {
}
}
errCh = utils.Go(func() error {
errCh = promise.Go(func() error {
return cli.hijack("POST", "/containers/"+runResult.Get("Id")+"/attach?"+v.Encode(), config.Tty, in, out, stderr, hijacked, nil)
})
} else {
@ -2477,7 +2478,7 @@ func (cli *DockerCli) CmdExec(args ...string) error {
stderr = cli.err
}
}
errCh = utils.Go(func() error {
errCh = promise.Go(func() error {
return cli.hijack("POST", "/exec/"+execID+"/start", execConfig.Tty, in, out, stderr, hijacked, execConfig)
})

View File

@ -14,9 +14,9 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/dockerversion"
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/term"
"github.com/docker/docker/utils"
)
func (cli *DockerCli) dial() (net.Conn, error) {
@ -78,7 +78,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
}
if stdout != nil || stderr != nil {
receiveStdout = utils.Go(func() (err error) {
receiveStdout = promise.Go(func() (err error) {
defer func() {
if in != nil {
if setRawTerminal && cli.isTerminalIn {
@ -104,7 +104,7 @@ func (cli *DockerCli) hijack(method, path string, setRawTerminal bool, in io.Rea
})
}
sendStdin := utils.Go(func() error {
sendStdin := promise.Go(func() error {
if in != nil {
io.Copy(rwc, in)
log.Debugf("[hijack] End of stdin")

View File

@ -23,6 +23,7 @@ import (
imagepkg "github.com/docker/docker/image"
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/tarsum"
@ -516,7 +517,7 @@ func (b *Builder) create() (*daemon.Container, error) {
func (b *Builder) run(c *daemon.Container) error {
var errCh chan error
if b.Verbose {
errCh = utils.Go(func() error {
errCh = promise.Go(func() error {
// FIXME: call the 'attach' job so that daemon.Attach can be made private
//
// FIXME (LK4D4): Also, maybe makes sense to call "logs" job, it is like attach

View File

@ -10,6 +10,7 @@ import (
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/jsonlog"
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/utils"
)
@ -246,7 +247,7 @@ func (daemon *Daemon) Attach(streamConfig *StreamConfig, openStdin, stdinOnce, t
}()
}
return utils.Go(func() error {
return promise.Go(func() error {
defer func() {
if cStdout != nil {
cStdout.Close()

View File

@ -27,6 +27,7 @@ import (
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/pkg/networkfs/etchosts"
"github.com/docker/docker/pkg/networkfs/resolvconf"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/pkg/symlink"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
@ -1117,7 +1118,7 @@ func (container *Container) waitForStart() error {
// process or until the process is running in the container
select {
case <-container.monitor.startSignal:
case err := <-utils.Go(container.monitor.Start):
case err := <-promise.Go(container.monitor.Start):
return err
}

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/docker/pkg/broadcastwriter"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/log"
"github.com/docker/docker/pkg/promise"
"github.com/docker/docker/runconfig"
"github.com/docker/docker/utils"
)
@ -254,7 +255,7 @@ func (container *Container) Exec(execConfig *execConfig) error {
// We use a callback here instead of a goroutine and an chan for
// syncronization purposes
cErr := utils.Go(func() error { return container.monitorExec(execConfig, callback) })
cErr := promise.Go(func() error { return container.monitorExec(execConfig, callback) })
// Exec should not return until the process is actually running
select {

11
pkg/promise/promise.go Normal file
View File

@ -0,0 +1,11 @@
package promise
// Go is a basic promise implementation: it wraps calls a function in a goroutine,
// and returns a channel which will later return the function's return value.
func Go(f func() error) chan error {
ch := make(chan error, 1)
go func() {
ch <- f()
}()
return ch
}

View File

@ -30,16 +30,6 @@ type KeyValuePair struct {
Value string
}
// Go is a basic promise implementation: it wraps calls a function in a goroutine,
// and returns a channel which will later return the function's return value.
func Go(f func() error) chan error {
ch := make(chan error, 1)
go func() {
ch <- f()
}()
return ch
}
// Request a given URL and return an io.Reader
func Download(url string) (resp *http.Response, err error) {
if resp, err = http.Get(url); err != nil {