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  }