github.com/hy3/cuto@v0.9.8-0.20160830082821-aa6652f877b7/master/jobnet/gateway.go (about) 1 package jobnet 2 3 import "fmt" 4 5 // ジョブネット内のフロー分岐・集約を表す構造体 6 type Gateway struct { 7 id string 8 Nexts []Element 9 } 10 11 // Gateway構造体のコンストラクタ関数 12 func NewGateway(id string) *Gateway { 13 gateway := new(Gateway) 14 gateway.id = id 15 return gateway 16 } 17 18 // IDを取得する 19 func (g *Gateway) ID() string { 20 return g.id 21 } 22 23 // ノードタイプを取得する 24 // 25 // return : ノードタイプ 26 func (g *Gateway) Type() elementType { 27 return ELM_GW 28 } 29 30 // 後続エレメントの追加を行う。 31 func (g *Gateway) AddNext(e Element) error { 32 g.Nexts = append(g.Nexts, e) 33 return nil 34 } 35 36 // 後続エレメントの有無を調べる。 37 func (g *Gateway) HasNext() bool { 38 return len(g.Nexts) > 0 39 } 40 41 // 後続のノード数に応じて、ゲートウェイの処理を行う。 42 // 43 // 後続ノードが存在しない場合:何も行わない。次の実行ノードとしてnilを返す。 44 // 45 // 後続ノードが1つだけの場合:何も行わない。次の実行ノードとして唯一の後続ノードを返す。 46 // 47 // 後続ノードが2つ以上の場合:各後続ノードを先頭としたPath構造体を生成し、並列実行する。次の実行ノードとして結合ゲートウェイを返す。 48 // 49 // return : 次の実行ノード 50 // 51 // return : エラー情報 52 func (g *Gateway) Execute() (Element, error) { 53 nextCnt := len(g.Nexts) 54 55 switch nextCnt { 56 case 0: 57 return nil, nil 58 case 1: 59 return g.Nexts[0], nil 60 default: 61 paths := make([]*Path, nextCnt) 62 done := make(chan struct{}, nextCnt) 63 for i := 0; i < nextCnt; i++ { 64 paths[i] = NewPath(g.Nexts[i]) 65 go paths[i].Run(done) 66 } 67 for i := 0; i < nextCnt; i++ { 68 <-done 69 } 70 for i := 0; i < nextCnt; i++ { 71 if paths[i].Err != nil { 72 err := fmt.Errorf("Error occured in branch: %s", paths[i].Err) 73 return nil, err 74 } 75 if paths[i].Goal != paths[0].Goal { 76 err := fmt.Errorf("Branch is combined by more than one gateway.") 77 return nil, err 78 } 79 } 80 return paths[0].Goal, nil 81 } 82 }