go-hep.org/x/hep@v0.38.1/fwk/inputstream.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 // InputStream implements a task reading data from an InputStreamer. 12 // 13 // InputStream is concurrent-safe. 14 // 15 // InputStream declares a property 'Ports', a []fwk.Port, which will 16 // be used to declare the output ports the streamer will publish, 17 // loading in data from the underlying InputStreamer. 18 // 19 // InputStream declares a property 'Streamer', a fwk.InputStreamer, 20 // which will be used to actually read data from. 21 type InputStream struct { 22 TaskBase 23 24 streamer InputStreamer 25 ctrl StreamControl 26 } 27 28 // Configure declares the output ports defined by the 'Ports' property. 29 func (tsk *InputStream) Configure(ctx Context) error { 30 for _, port := range tsk.ctrl.Ports { 31 err := tsk.DeclOutPort(port.Name, port.Type) 32 if err != nil { 33 return err 34 } 35 } 36 return nil 37 } 38 39 // StartTask starts the InputStreamer task 40 func (tsk *InputStream) StartTask(ctx Context) error { 41 return nil 42 } 43 44 // StopTask stops the InputStreamer task 45 func (tsk *InputStream) StopTask(ctx Context) error { 46 return tsk.disconnect() 47 } 48 49 func (tsk *InputStream) connect(ctrl StreamControl) error { 50 ctrl.Ports = make([]Port, len(tsk.ctrl.Ports)) 51 copy(ctrl.Ports, tsk.ctrl.Ports) 52 53 tsk.ctrl = ctrl 54 err := tsk.streamer.Connect(ctrl.Ports) 55 if err != nil { 56 return err 57 } 58 59 go tsk.read() 60 61 return err 62 } 63 64 func (tsk *InputStream) disconnect() error { 65 return tsk.streamer.Disconnect() 66 } 67 68 func (tsk *InputStream) read() { 69 for { 70 select { 71 72 case ctx := <-tsk.ctrl.Ctx: 73 tsk.ctrl.Err <- tsk.streamer.Read(ctx) 74 75 case <-tsk.ctrl.Quit: 76 return 77 } 78 } 79 } 80 81 // Process loads data from the underlying InputStreamer 82 // and puts it in the event store. 83 func (tsk *InputStream) Process(ctx Context) error { 84 var err error 85 86 tsk.ctrl.Ctx <- ctx 87 err = <-tsk.ctrl.Err 88 89 if err != nil { 90 return err 91 } 92 93 return err 94 } 95 96 func newInputStream(typ, name string, mgr App) (Component, error) { 97 var err error 98 99 tsk := &InputStream{ 100 TaskBase: NewTask(typ, name, mgr), 101 streamer: nil, 102 ctrl: StreamControl{ 103 Ports: make([]Port, 0), 104 }, 105 } 106 107 err = tsk.DeclProp("Ports", &tsk.ctrl.Ports) 108 if err != nil { 109 return nil, err 110 } 111 112 err = tsk.DeclProp("Streamer", &tsk.streamer) 113 if err != nil { 114 return nil, err 115 } 116 117 return tsk, err 118 } 119 120 // inputStream provides fake input events when no input file is present 121 type inputStream struct { 122 TaskBase 123 } 124 125 func (tsk *inputStream) StartTask(ctx Context) error { 126 return nil 127 } 128 129 func (tsk *inputStream) StopTask(ctx Context) error { 130 return nil 131 } 132 133 func (tsk *inputStream) Process(ctx Context) error { 134 return nil 135 } 136 137 func init() { 138 Register(reflect.TypeOf(InputStream{}), newInputStream) 139 }