github.com/unirita/cuto@v0.9.8-0.20160830082821-aa6652f877b7/master/remote/request.go (about) 1 // Copyright 2015 unirita Inc. 2 // Created 2015/04/10 honda 3 4 package remote 5 6 import ( 7 "bufio" 8 "fmt" 9 "net" 10 "strings" 11 "time" 12 13 "github.com/unirita/cuto/log" 14 "github.com/unirita/cuto/master/config" 15 "github.com/unirita/cuto/message" 16 ) 17 18 type response struct { 19 msg string 20 err error 21 } 22 23 // 送受信メッセージの終端文字 24 const MsgEnd = "\n" 25 26 // ホスト名がhost、ポート番号がportのservantへ接続し、ジョブ実行要求を送信する。 27 // servantから返信されたジョブ実行結果を関数外へ返す。 28 // 29 // param : host ホスト名。 30 // 31 // param : port ポート番号。 32 // 33 // param : req リクエストメッセージ。 34 // 35 // return : 返信メッセージ。 36 // 37 // return : エラー情報。 38 func SendRequest(host string, port int, req string, stCh chan<- string) (string, error) { 39 const bufSize = 1024 40 timeout := time.Duration(config.Job.ConnectionTimeoutSec) * time.Second 41 42 addr := fmt.Sprintf("%s:%d", host, port) 43 conn, err := net.DialTimeout("tcp", addr, timeout) 44 if err != nil { 45 return ``, err 46 } 47 defer conn.Close() 48 49 log.Debug(req) 50 _, err = conn.Write([]byte(req + MsgEnd)) 51 if err != nil { 52 return ``, err 53 } 54 55 scanner := bufio.NewScanner(conn) 56 57 for { 58 select { 59 case res := <-readResponse(scanner): 60 if res.err != nil { 61 return ``, res.err 62 } 63 log.Debug(res.msg) 64 if res.msg == message.HEARTBEAT { 65 // ハートビートメッセージの場合はバッファサイズを初期化する。 66 continue 67 } else if strings.HasPrefix(res.msg, message.ST_HEADER) { 68 st := res.msg[len(message.ST_HEADER):] 69 stCh <- st 70 continue 71 } 72 73 return res.msg, nil 74 case <-time.After(timeout): 75 return ``, fmt.Errorf("Connetion timeout.") 76 } 77 } 78 } 79 80 func readResponse(scanner *bufio.Scanner) <-chan *response { 81 ch := make(chan *response, 10) 82 go func() { 83 res := new(response) 84 if scanner.Scan() { 85 res.msg = scanner.Text() 86 } else { 87 res.err = scanner.Err() 88 } 89 ch <- res 90 if res.err != nil { 91 return 92 } 93 }() 94 95 return ch 96 }