func (t *Terminal) Make(kind string, arg interface{}) (elem Element, err error) { log.Printf("Making %s as %s with %v", t.carrier().Path(), kind, arg) t.carrier().TxLock() defer t.carrier().TxUnlock() if t.carrier().Get() != nil { return nil, errors.New("anchor already has an element") } switch kind { case Chan: capacity, ok := arg.(int) if !ok { return nil, errors.New("invalid argument") } u := &urn{ kind: Chan, elem: &scrubValve{t, valve.MakeValve(capacity)}, } t.carrier().Set(u) return u.elem, nil case Proc: cmd, ok := arg.(proc.Cmd) if !ok { return nil, errors.New("invalid argument") } u := &urn{ kind: Proc, elem: proc.MakeProc(cmd), } t.carrier().Set(u) go func() { defer func() { recover() }() if cmd.Scrub { defer t.Scrub() } u.elem.(proc.Proc).Wait() }() return u.elem, nil case OnJoin: u := &urn{ kind: OnJoin, elem: t.genus.NewArrivals(), } t.carrier().Set(u) return u.elem, nil case OnLeave: u := &urn{ kind: OnLeave, elem: t.genus.NewDepartures(), } t.carrier().Set(u) return u.elem, nil } return nil, errors.New("element kind not known") }
func (t *Terminal) Make(kind string, arg interface{}) (elem Element, err error) { log.Printf("Making %s at %s, using %v", kind, t.carrier().Path(), arg) t.carrier().TxLock() defer t.carrier().TxUnlock() if t.carrier().Get() != nil { return nil, errors.New("anchor already has an element") } switch kind { case Chan: capacity, ok := arg.(int) if !ok { return nil, errors.New("invalid argument") } u := &urn{ kind: Chan, elem: &scrubValve{t, valve.MakeValve(capacity)}, } t.carrier().Set(u) return u.elem, nil case Proc: cmd, ok := arg.(proc.Cmd) if !ok { return nil, errors.New("invalid argument") } u := &urn{ kind: Proc, elem: proc.MakeProc(cmd), } t.carrier().Set(u) go func() { defer func() { recover() }() if cmd.Scrub { defer t.Scrub() } u.elem.(proc.Proc).Wait() }() return u.elem, nil case Docker: run, ok := arg.(ds.Run) if !ok { return nil, errors.New("invalid argument") } x, err := docker.MakeContainer(run) if err != nil { return nil, err } u := &urn{ kind: Docker, elem: x, } t.carrier().Set(u) go func() { defer func() { recover() }() if run.Scrub { defer t.Scrub() } u.elem.(docker.Container).Wait() }() return u.elem, nil case Nameserver: ns, err := dns.MakeNameserver(arg.(string)) if err != nil { return nil, err } u := &urn{ kind: Nameserver, elem: ns, } t.carrier().Set(u) return u.elem, nil case OnJoin: u := &urn{ kind: OnJoin, elem: t.genus.NewArrivals(), } t.carrier().Set(u) return u.elem, nil case OnLeave: u := &urn{ kind: OnLeave, elem: t.genus.NewDepartures(), } t.carrier().Set(u) return u.elem, nil } return nil, errors.New("element kind not known") }