github.com/hy3/cuto@v0.9.8-0.20160830082821-aa6652f877b7/db/tx/jobnettx.go (about) 1 // Copyright 2015 unirita Inc. 2 // Created 2015/04/10 shanxia 3 4 package tx 5 6 import ( 7 "fmt" 8 "sync" 9 10 "github.com/unirita/cuto/db" 11 "github.com/unirita/cuto/db/query" 12 "github.com/unirita/cuto/log" 13 "github.com/unirita/cuto/utctime" 14 ) 15 16 // ジョブIDをキーに持つ 17 type JobMap map[string]*db.JobResult 18 19 // ジョブ実行結果を保持する。 20 type ResultMap struct { 21 JobnetResult *db.JobNetworkResult // ジョブネットワーク情報の構造体。 22 jobresults JobMap // ジョブネットワーク内のジョブ状態を保存するMap。 23 conn db.IConnection // DBコネクション 24 } 25 26 // ジョブネットワークの開始状態を記録する。 27 // 28 // param : jobnetName ジョブネットワーク名。 29 // 30 // param : dbname データベース名。 31 // 32 // return : ジョブ実行結果を保持する構造体ポインタ。 33 // 34 // return : error 35 func StartJobNetwork(jobnetName string, dbname string) (*ResultMap, error) { 36 jn := db.NewJobNetworkResult(jobnetName, utctime.Now().String(), db.RUNNING) 37 38 conn, err := db.Open(dbname) 39 if err != nil { 40 return nil, err 41 } 42 resMap := &ResultMap{jn, make(JobMap), conn} 43 44 if err := resMap.insertJobNetwork(); err != nil { 45 return nil, err 46 } 47 return resMap, nil 48 } 49 50 // ジョブネットワークの実行結果を復元する。 51 func ResumeJobNetwork(nid int, dbname string) (*ResultMap, error) { 52 conn, err := db.Open(dbname) 53 if err != nil { 54 return nil, err 55 } 56 jn, err := query.GetJobnetwork(conn, nid) 57 if err != nil { 58 return nil, err 59 } 60 61 jr, err := query.GetJobMapOfTargetNetwork(conn, nid) 62 if err != nil { 63 return nil, err 64 } 65 66 resMap := &ResultMap{ 67 JobnetResult: jn, 68 jobresults: jr, 69 conn: conn, 70 } 71 72 return resMap, nil 73 } 74 75 // ネットワーク終了時に結果情報を設定する。同時にDBコネクションも切断する。 76 // 77 // param : status ジョブネットワークのステータス。 78 // 79 // param : detail ジョブネットワークに記録する詳細メッセージ。 80 // 81 // return : error 82 func (r *ResultMap) EndJobNetwork(status int, detail string) error { 83 if r.conn == nil { 84 return fmt.Errorf("Can't access DB file.") 85 } 86 defer r.conn.Close() 87 88 if r.JobnetResult == nil { 89 return fmt.Errorf("Invalid Jobnetwork info.") 90 } 91 r.JobnetResult.EndDate = utctime.Now().String() 92 r.JobnetResult.Status = status 93 r.JobnetResult.Detail = detail 94 95 for _, jobresult := range r.jobresults { 96 if r.JobnetResult.Status < jobresult.Status { 97 r.JobnetResult.Status = jobresult.Status 98 } 99 } 100 101 if err := r.updateJobNetwork(); err != nil { 102 return err 103 } 104 return nil 105 } 106 107 // DBコネクションを返す。 108 func (r *ResultMap) GetConnection() db.IConnection { 109 return r.conn 110 } 111 112 // ジョブネットワークレコードをInsertする。 113 func (r *ResultMap) insertJobNetwork() error { 114 var isCommit bool 115 tx, err := r.conn.GetDbMap().Begin() 116 if err != nil { 117 return err 118 } 119 defer func() { 120 if !isCommit { 121 tx.Rollback() 122 } 123 }() 124 125 now := utctime.Now().String() 126 r.JobnetResult.CreateDate = now 127 r.JobnetResult.UpdateDate = now 128 129 err = tx.Insert(r.JobnetResult) 130 if err != nil { 131 return err 132 } 133 if err = tx.Commit(); err != nil { 134 return err 135 } 136 log.Debug(fmt.Sprintf("networkId[%v]", r.JobnetResult.ID)) 137 isCommit = true 138 return nil 139 } 140 141 // ジョブネットワークレコードをUpdateする。 142 func (r *ResultMap) updateJobNetwork() error { 143 var isCommit bool 144 tx, err := r.conn.GetDbMap().Begin() 145 if err != nil { 146 return err 147 } 148 defer func() { 149 if !isCommit { 150 tx.Rollback() 151 } 152 }() 153 r.JobnetResult.UpdateDate = utctime.Now().String() 154 155 if _, err = tx.Update(r.JobnetResult); err != nil { 156 return err 157 } 158 if err = tx.Commit(); err != nil { 159 return err 160 } 161 isCommit = true 162 return nil 163 } 164 165 // DBコネクションを外部から渡す。テスト用のメソッド。 166 func (r *ResultMap) SetConnection(conn db.IConnection) { 167 r.conn = conn 168 } 169 170 var localMutex sync.Mutex // JobMap dedicated mutex. 171 172 // getter JobResult 173 func (r *ResultMap) GetJobResults(jobId string) (*db.JobResult, bool) { 174 res, exist := r.jobresults[jobId] 175 return res, exist 176 } 177 178 // setter JobResult. (thread safe) 179 func (r *ResultMap) AddJobResults(jobId string, jobRes *db.JobResult) { 180 localMutex.Lock() 181 defer localMutex.Unlock() 182 r.jobresults[jobId] = jobRes 183 } 184 185 // test function 186 func NewResultMap() *ResultMap { 187 return &ResultMap{ 188 JobnetResult: nil, 189 jobresults: make(JobMap), 190 } 191 }