func (ih *InputHandler) ReadInput(ch chan entity.InputData) { input := entity.NewInputData() input.Name = ih.GetName() input.State = entity.INPUT_DATA_CONTINUE ih.State = ext.INPUT_STATE_RUNNING for i := 0; i < 10; i++ { input.Data = []byte("aaaa") ch <- *input time.Sleep(100 * time.Millisecond) } ih.State = ext.INPUT_STATE_DONE input.State = entity.INPUT_DATA_END input.Data = nil ch <- *input return }
func (ih *InputHandler) ReadInput(ch chan entity.InputData) { var err error input := entity.NewInputData() input.Name = ih.config.Name input.State = entity.INPUT_DATA_CONTINUE defer func() { if err != nil { input.State = entity.INPUT_DATA_END ih.State = ext.INPUT_STATE_ERROR ch <- *input log.Printf("Handler exited with error: %s\n", err.Error()) } }() session, err := ih.createSession(ih.config) if err != nil { return } ih.State = ext.INPUT_STATE_RUNNING //Set a pipe for session's output. //Remote session will blocked(sleep) if pipe is full. r, err := session.StdoutPipe() if err != nil { return } //Data receiving needs start separately with main thread. //This thread blocks until first data received. go func() { defer session.Close() buffer := make([]byte, 1024) for { //r.Read will block(sleep) if pipe is empty. readBytes, err := r.Read(buffer) if err != nil { break } else { input.Data = buffer[:readBytes] input.State = entity.INPUT_DATA_CONTINUE } ch <- *input } ih.State = ext.INPUT_STATE_DONE if err != nil { ih.State = ext.INPUT_STATE_ERROR } else { input.State = entity.INPUT_DATA_END } input.Data = nil // Pass a copy of "input". // It is needed to avoid the "input" // updated unfortunately by this goroutine // while the main thread refers. ch <- *input }() //Start session. if err := session.Run(ih.config.Command); err != nil { return } ih.State = ext.INPUT_STATE_DONE }