go-hep.org/x/hep@v0.38.1/fwk/outputstream.go (about) 1 // Copyright ©2017 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fwk 6 7 import ( 8 "reflect" 9 ) 10 11 // OutputStream implements a task writing data to an OutputStreamer. 12 // 13 // OutputStream is concurrent-safe. 14 // 15 // OutputStream declares a property 'Ports', a []fwk.Port, which will 16 // be used to declare the input ports the task will access to, 17 // writing out data via the underlying OutputStreamer. 18 // 19 // OutputStream declares a property 'Streamer', a fwk.OutputStreamer, 20 // which will be used to actually write data to. 21 type OutputStream struct { 22 TaskBase 23 24 streamer OutputStreamer 25 ctrl StreamControl 26 } 27 28 // Configure declares the input ports defined by the 'Ports' property. 29 func (tsk *OutputStream) Configure(ctx Context) error { 30 var err error 31 32 for _, port := range tsk.ctrl.Ports { 33 err = tsk.DeclInPort(port.Name, port.Type) 34 if err != nil { 35 return err 36 } 37 } 38 39 return err 40 } 41 42 // StartTask starts the OutputStreamer task 43 func (tsk *OutputStream) StartTask(ctx Context) error { 44 return nil 45 } 46 47 // StopTask stops the OutputStreamer task 48 func (tsk *OutputStream) StopTask(ctx Context) error { 49 return tsk.disconnect() 50 } 51 52 func (tsk *OutputStream) connect(ctrl StreamControl) error { 53 ctrl.Ports = make([]Port, len(tsk.ctrl.Ports)) 54 copy(ctrl.Ports, tsk.ctrl.Ports) 55 56 tsk.ctrl = ctrl 57 err := tsk.streamer.Connect(ctrl.Ports) 58 if err != nil { 59 return err 60 } 61 62 go tsk.write() 63 64 return err 65 } 66 67 func (tsk *OutputStream) disconnect() error { 68 return tsk.streamer.Disconnect() 69 } 70 71 func (tsk *OutputStream) write() { 72 for { 73 select { 74 75 case ctx := <-tsk.ctrl.Ctx: 76 tsk.ctrl.Err <- tsk.streamer.Write(ctx) 77 78 case <-tsk.ctrl.Quit: 79 return 80 } 81 } 82 } 83 84 // Process gets data from the store and 85 // writes it out via the underlying OutputStreamer 86 func (tsk *OutputStream) Process(ctx Context) error { 87 var err error 88 89 tsk.ctrl.Ctx <- ctx 90 err = <-tsk.ctrl.Err 91 if err != nil { 92 return err 93 } 94 95 return err 96 } 97 98 func newOutputStream(typ, name string, mgr App) (Component, error) { 99 var err error 100 101 tsk := &OutputStream{ 102 TaskBase: NewTask(typ, name, mgr), 103 streamer: nil, 104 ctrl: StreamControl{ 105 Ports: make([]Port, 0), 106 }, 107 } 108 109 err = tsk.DeclProp("Ports", &tsk.ctrl.Ports) 110 if err != nil { 111 return nil, err 112 } 113 114 err = tsk.DeclProp("Streamer", &tsk.streamer) 115 if err != nil { 116 return nil, err 117 } 118 119 return tsk, err 120 } 121 122 func init() { 123 Register(reflect.TypeOf(OutputStream{}), newOutputStream) 124 }