3 // 'pipe' score interface
5 // The PIPE score interface works much like the ENV interace, but also attaches
6 // a pipe to STDOUT which captures <x>=<y> repsonse values.
18 pipeEnvironmentPrefix = "ORC_"
22 RegisterInterface("pipe", newPipeInterface)
25 type PipeInterface struct {
30 func newPipeInterface(task *TaskRequest) (iface ScoreInterface) {
31 ei := new(PipeInterface)
38 // pipeListener is the goroutine that sits on the stdout pipe and
39 // processes what it sees.
40 func pipeListener(task *TaskRequest, outpipe *os.File) {
43 r := bufio.NewReader(outpipe)
45 lb, _, err := r.ReadLine()
50 o.Warn("pipeListener failed: %s", err)
54 if strings.Index(linein, "=") >= 0 {
55 bits := strings.SplitN(linein, "=", 2)
56 task.MyResponse.Response[bits[0]] = bits[1]
62 func (ei *PipeInterface) Prepare() bool {
63 lr, lw, err := os.Pipe()
67 // save the writing end of the pipe so we can close our local end of it during cleanup.
70 // start the pipe listener
71 go pipeListener(ei.task, lr)
76 func (ei *PipeInterface) SetupProcess() (ee *ExecutionEnvironment) {
77 ee = NewExecutionEnvironment()
78 for k,v := range ei.task.Params {
79 ee.Environment[pipeEnvironmentPrefix+k] = v
81 ee.Files = make([]*os.File, 2)
82 ee.Files[1] = ei.pipew
86 func (ei *PipeInterface) Cleanup() {
87 // close the local copy of the pipe.
89 // if the child didn't start, this will also EOF the
90 // pipeListener which will clean up that goroutine.