1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Worker// Package status tracks actions run by various tools, combining the counts 16*333d2b36SAndroid Build Coastguard Worker// (total actions, currently running, started, finished), and giving that to 17*333d2b36SAndroid Build Coastguard Worker// multiple outputs. 18*333d2b36SAndroid Build Coastguard Workerpackage status 19*333d2b36SAndroid Build Coastguard Worker 20*333d2b36SAndroid Build Coastguard Workerimport ( 21*333d2b36SAndroid Build Coastguard Worker "sync" 22*333d2b36SAndroid Build Coastguard Worker "time" 23*333d2b36SAndroid Build Coastguard Worker) 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker// Action describes an action taken (or as Ninja calls them, Edges). 26*333d2b36SAndroid Build Coastguard Workertype Action struct { 27*333d2b36SAndroid Build Coastguard Worker // Description is a shorter, more readable form of the command, meant 28*333d2b36SAndroid Build Coastguard Worker // for users. It's optional, but one of either Description or Command 29*333d2b36SAndroid Build Coastguard Worker // should be set. 30*333d2b36SAndroid Build Coastguard Worker Description string 31*333d2b36SAndroid Build Coastguard Worker 32*333d2b36SAndroid Build Coastguard Worker // Outputs is the (optional) list of outputs. Usually these are files, 33*333d2b36SAndroid Build Coastguard Worker // but they can be any string. 34*333d2b36SAndroid Build Coastguard Worker Outputs []string 35*333d2b36SAndroid Build Coastguard Worker 36*333d2b36SAndroid Build Coastguard Worker // Inputs is the (optional) list of inputs. Usually these are files, 37*333d2b36SAndroid Build Coastguard Worker // but they can be any string. 38*333d2b36SAndroid Build Coastguard Worker Inputs []string 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker // Command is the actual command line executed to perform the action. 41*333d2b36SAndroid Build Coastguard Worker // It's optional, but one of either Description or Command should be 42*333d2b36SAndroid Build Coastguard Worker // set. 43*333d2b36SAndroid Build Coastguard Worker Command string 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker // ChangedInputs is the (optional) list of inputs that have changed 46*333d2b36SAndroid Build Coastguard Worker // since last time this action was run. 47*333d2b36SAndroid Build Coastguard Worker ChangedInputs []string 48*333d2b36SAndroid Build Coastguard Worker} 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Worker// ActionResult describes the result of running an Action. 51*333d2b36SAndroid Build Coastguard Workertype ActionResult struct { 52*333d2b36SAndroid Build Coastguard Worker // Action is a pointer to the original Action struct. 53*333d2b36SAndroid Build Coastguard Worker *Action 54*333d2b36SAndroid Build Coastguard Worker 55*333d2b36SAndroid Build Coastguard Worker // Output is the output produced by the command (usually stdout&stderr 56*333d2b36SAndroid Build Coastguard Worker // for Actions that run commands) 57*333d2b36SAndroid Build Coastguard Worker Output string 58*333d2b36SAndroid Build Coastguard Worker 59*333d2b36SAndroid Build Coastguard Worker // Error is nil if the Action succeeded, or set to an error if it 60*333d2b36SAndroid Build Coastguard Worker // failed. 61*333d2b36SAndroid Build Coastguard Worker Error error 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker Stats ActionResultStats 64*333d2b36SAndroid Build Coastguard Worker} 65*333d2b36SAndroid Build Coastguard Worker 66*333d2b36SAndroid Build Coastguard Workertype ActionResultStats struct { 67*333d2b36SAndroid Build Coastguard Worker // Number of milliseconds spent executing in user mode 68*333d2b36SAndroid Build Coastguard Worker UserTime uint32 69*333d2b36SAndroid Build Coastguard Worker 70*333d2b36SAndroid Build Coastguard Worker // Number of milliseconds spent executing in kernel mode 71*333d2b36SAndroid Build Coastguard Worker SystemTime uint32 72*333d2b36SAndroid Build Coastguard Worker 73*333d2b36SAndroid Build Coastguard Worker // Max resident set size in kB 74*333d2b36SAndroid Build Coastguard Worker MaxRssKB uint64 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Worker // Minor page faults 77*333d2b36SAndroid Build Coastguard Worker MinorPageFaults uint64 78*333d2b36SAndroid Build Coastguard Worker 79*333d2b36SAndroid Build Coastguard Worker // Major page faults 80*333d2b36SAndroid Build Coastguard Worker MajorPageFaults uint64 81*333d2b36SAndroid Build Coastguard Worker 82*333d2b36SAndroid Build Coastguard Worker // IO input in kB 83*333d2b36SAndroid Build Coastguard Worker IOInputKB uint64 84*333d2b36SAndroid Build Coastguard Worker 85*333d2b36SAndroid Build Coastguard Worker // IO output in kB 86*333d2b36SAndroid Build Coastguard Worker IOOutputKB uint64 87*333d2b36SAndroid Build Coastguard Worker 88*333d2b36SAndroid Build Coastguard Worker // Voluntary context switches 89*333d2b36SAndroid Build Coastguard Worker VoluntaryContextSwitches uint64 90*333d2b36SAndroid Build Coastguard Worker 91*333d2b36SAndroid Build Coastguard Worker // Involuntary context switches 92*333d2b36SAndroid Build Coastguard Worker InvoluntaryContextSwitches uint64 93*333d2b36SAndroid Build Coastguard Worker 94*333d2b36SAndroid Build Coastguard Worker Tags string 95*333d2b36SAndroid Build Coastguard Worker} 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Worker// Counts describes the number of actions in each state 98*333d2b36SAndroid Build Coastguard Workertype Counts struct { 99*333d2b36SAndroid Build Coastguard Worker // TotalActions is the total number of expected changes. This can 100*333d2b36SAndroid Build Coastguard Worker // generally change up or down during a build, but it should never go 101*333d2b36SAndroid Build Coastguard Worker // below the number of StartedActions 102*333d2b36SAndroid Build Coastguard Worker TotalActions int 103*333d2b36SAndroid Build Coastguard Worker 104*333d2b36SAndroid Build Coastguard Worker // RunningActions are the number of actions that are currently running 105*333d2b36SAndroid Build Coastguard Worker // -- the number that have called StartAction, but not FinishAction. 106*333d2b36SAndroid Build Coastguard Worker RunningActions int 107*333d2b36SAndroid Build Coastguard Worker 108*333d2b36SAndroid Build Coastguard Worker // StartedActions are the number of actions that have been started with 109*333d2b36SAndroid Build Coastguard Worker // StartAction. 110*333d2b36SAndroid Build Coastguard Worker StartedActions int 111*333d2b36SAndroid Build Coastguard Worker 112*333d2b36SAndroid Build Coastguard Worker // FinishedActions are the number of actions that have been finished 113*333d2b36SAndroid Build Coastguard Worker // with FinishAction. 114*333d2b36SAndroid Build Coastguard Worker FinishedActions int 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Worker EstimatedTime time.Time 117*333d2b36SAndroid Build Coastguard Worker} 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Worker// ToolStatus is the interface used by tools to report on their Actions, and to 120*333d2b36SAndroid Build Coastguard Worker// present other information through a set of messaging functions. 121*333d2b36SAndroid Build Coastguard Workertype ToolStatus interface { 122*333d2b36SAndroid Build Coastguard Worker // SetTotalActions sets the expected total number of actions that will 123*333d2b36SAndroid Build Coastguard Worker // be started by this tool. 124*333d2b36SAndroid Build Coastguard Worker // 125*333d2b36SAndroid Build Coastguard Worker // This call be will ignored if it sets a number that is less than the 126*333d2b36SAndroid Build Coastguard Worker // current number of started actions. 127*333d2b36SAndroid Build Coastguard Worker SetTotalActions(total int) 128*333d2b36SAndroid Build Coastguard Worker SetEstimatedTime(estimatedTime time.Time) 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Worker // StartAction specifies that the associated action has been started by 131*333d2b36SAndroid Build Coastguard Worker // the tool. 132*333d2b36SAndroid Build Coastguard Worker // 133*333d2b36SAndroid Build Coastguard Worker // A specific *Action should not be specified to StartAction more than 134*333d2b36SAndroid Build Coastguard Worker // once, even if the previous action has already been finished, and the 135*333d2b36SAndroid Build Coastguard Worker // contents rewritten. 136*333d2b36SAndroid Build Coastguard Worker // 137*333d2b36SAndroid Build Coastguard Worker // Do not re-use *Actions between different ToolStatus interfaces 138*333d2b36SAndroid Build Coastguard Worker // either. 139*333d2b36SAndroid Build Coastguard Worker StartAction(action *Action) 140*333d2b36SAndroid Build Coastguard Worker 141*333d2b36SAndroid Build Coastguard Worker // FinishAction specifies the result of a particular Action. 142*333d2b36SAndroid Build Coastguard Worker // 143*333d2b36SAndroid Build Coastguard Worker // The *Action embedded in the ActionResult structure must have already 144*333d2b36SAndroid Build Coastguard Worker // been passed to StartAction (on this interface). 145*333d2b36SAndroid Build Coastguard Worker // 146*333d2b36SAndroid Build Coastguard Worker // Do not call FinishAction twice for the same *Action. 147*333d2b36SAndroid Build Coastguard Worker FinishAction(result ActionResult) 148*333d2b36SAndroid Build Coastguard Worker 149*333d2b36SAndroid Build Coastguard Worker // Verbose takes a non-important message that is never printed to the 150*333d2b36SAndroid Build Coastguard Worker // screen, but is in the verbose build log, etc 151*333d2b36SAndroid Build Coastguard Worker Verbose(msg string) 152*333d2b36SAndroid Build Coastguard Worker // Status takes a less important message that may be printed to the 153*333d2b36SAndroid Build Coastguard Worker // screen, but overwritten by another status message. The full message 154*333d2b36SAndroid Build Coastguard Worker // will still appear in the verbose build log. 155*333d2b36SAndroid Build Coastguard Worker Status(msg string) 156*333d2b36SAndroid Build Coastguard Worker // Print takes an message and displays it to the screen and other 157*333d2b36SAndroid Build Coastguard Worker // output logs, etc. 158*333d2b36SAndroid Build Coastguard Worker Print(msg string) 159*333d2b36SAndroid Build Coastguard Worker // Error is similar to Print, but treats it similarly to a failed 160*333d2b36SAndroid Build Coastguard Worker // action, showing it in the error logs, etc. 161*333d2b36SAndroid Build Coastguard Worker Error(msg string) 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker // Finish marks the end of all Actions being run by this tool. 164*333d2b36SAndroid Build Coastguard Worker // 165*333d2b36SAndroid Build Coastguard Worker // SetTotalEdges, StartAction, and FinishAction should not be called 166*333d2b36SAndroid Build Coastguard Worker // after Finish. 167*333d2b36SAndroid Build Coastguard Worker Finish() 168*333d2b36SAndroid Build Coastguard Worker} 169*333d2b36SAndroid Build Coastguard Worker 170*333d2b36SAndroid Build Coastguard Worker// MsgLevel specifies the importance of a particular log message. See the 171*333d2b36SAndroid Build Coastguard Worker// descriptions in ToolStatus: Verbose, Status, Print, Error. 172*333d2b36SAndroid Build Coastguard Workertype MsgLevel int 173*333d2b36SAndroid Build Coastguard Worker 174*333d2b36SAndroid Build Coastguard Workerconst ( 175*333d2b36SAndroid Build Coastguard Worker VerboseLvl MsgLevel = iota 176*333d2b36SAndroid Build Coastguard Worker StatusLvl 177*333d2b36SAndroid Build Coastguard Worker PrintLvl 178*333d2b36SAndroid Build Coastguard Worker ErrorLvl 179*333d2b36SAndroid Build Coastguard Worker) 180*333d2b36SAndroid Build Coastguard Worker 181*333d2b36SAndroid Build Coastguard Workerfunc (l MsgLevel) Prefix() string { 182*333d2b36SAndroid Build Coastguard Worker switch l { 183*333d2b36SAndroid Build Coastguard Worker case VerboseLvl: 184*333d2b36SAndroid Build Coastguard Worker return "verbose: " 185*333d2b36SAndroid Build Coastguard Worker case StatusLvl: 186*333d2b36SAndroid Build Coastguard Worker return "status: " 187*333d2b36SAndroid Build Coastguard Worker case PrintLvl: 188*333d2b36SAndroid Build Coastguard Worker return "" 189*333d2b36SAndroid Build Coastguard Worker case ErrorLvl: 190*333d2b36SAndroid Build Coastguard Worker return "error: " 191*333d2b36SAndroid Build Coastguard Worker default: 192*333d2b36SAndroid Build Coastguard Worker panic("Unknown message level") 193*333d2b36SAndroid Build Coastguard Worker } 194*333d2b36SAndroid Build Coastguard Worker} 195*333d2b36SAndroid Build Coastguard Worker 196*333d2b36SAndroid Build Coastguard Worker// StatusOutput is the interface used to get status information as a Status 197*333d2b36SAndroid Build Coastguard Worker// output. 198*333d2b36SAndroid Build Coastguard Worker// 199*333d2b36SAndroid Build Coastguard Worker// All of the functions here are guaranteed to be called by Status while 200*333d2b36SAndroid Build Coastguard Worker// holding it's internal lock, so it's safe to assume a single caller at any 201*333d2b36SAndroid Build Coastguard Worker// time, and that the ordering of calls will be correct. It is not safe to call 202*333d2b36SAndroid Build Coastguard Worker// back into the Status, or one of its ToolStatus interfaces. 203*333d2b36SAndroid Build Coastguard Workertype StatusOutput interface { 204*333d2b36SAndroid Build Coastguard Worker // StartAction will be called once every time ToolStatus.StartAction is 205*333d2b36SAndroid Build Coastguard Worker // called. counts will include the current counters across all 206*333d2b36SAndroid Build Coastguard Worker // ToolStatus instances, including ones that have been finished. 207*333d2b36SAndroid Build Coastguard Worker StartAction(action *Action, counts Counts) 208*333d2b36SAndroid Build Coastguard Worker 209*333d2b36SAndroid Build Coastguard Worker // FinishAction will be called once every time ToolStatus.FinishAction 210*333d2b36SAndroid Build Coastguard Worker // is called. counts will include the current counters across all 211*333d2b36SAndroid Build Coastguard Worker // ToolStatus instances, including ones that have been finished. 212*333d2b36SAndroid Build Coastguard Worker FinishAction(result ActionResult, counts Counts) 213*333d2b36SAndroid Build Coastguard Worker 214*333d2b36SAndroid Build Coastguard Worker // Message is the equivalent of ToolStatus.Verbose/Status/Print/Error, 215*333d2b36SAndroid Build Coastguard Worker // but the level is specified as an argument. 216*333d2b36SAndroid Build Coastguard Worker Message(level MsgLevel, msg string) 217*333d2b36SAndroid Build Coastguard Worker 218*333d2b36SAndroid Build Coastguard Worker // Flush is called when your outputs should be flushed / closed. No 219*333d2b36SAndroid Build Coastguard Worker // output is expected after this call. 220*333d2b36SAndroid Build Coastguard Worker Flush() 221*333d2b36SAndroid Build Coastguard Worker 222*333d2b36SAndroid Build Coastguard Worker // Write lets StatusOutput implement io.Writer 223*333d2b36SAndroid Build Coastguard Worker Write(p []byte) (n int, err error) 224*333d2b36SAndroid Build Coastguard Worker} 225*333d2b36SAndroid Build Coastguard Worker 226*333d2b36SAndroid Build Coastguard Worker// Status is the multiplexer / accumulator between ToolStatus instances (via 227*333d2b36SAndroid Build Coastguard Worker// StartTool) and StatusOutputs (via AddOutput). There's generally one of these 228*333d2b36SAndroid Build Coastguard Worker// per build process (though tools like multiproduct_kati may have multiple 229*333d2b36SAndroid Build Coastguard Worker// independent versions). 230*333d2b36SAndroid Build Coastguard Workertype Status struct { 231*333d2b36SAndroid Build Coastguard Worker counts Counts 232*333d2b36SAndroid Build Coastguard Worker outputs []StatusOutput 233*333d2b36SAndroid Build Coastguard Worker 234*333d2b36SAndroid Build Coastguard Worker // Protects counts and outputs, and allows each output to 235*333d2b36SAndroid Build Coastguard Worker // expect only a single caller at a time. 236*333d2b36SAndroid Build Coastguard Worker lock sync.Mutex 237*333d2b36SAndroid Build Coastguard Worker} 238*333d2b36SAndroid Build Coastguard Worker 239*333d2b36SAndroid Build Coastguard Worker// AddOutput attaches an output to this object. It's generally expected that an 240*333d2b36SAndroid Build Coastguard Worker// output is attached to a single Status instance. 241*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) AddOutput(output StatusOutput) { 242*333d2b36SAndroid Build Coastguard Worker if output == nil { 243*333d2b36SAndroid Build Coastguard Worker return 244*333d2b36SAndroid Build Coastguard Worker } 245*333d2b36SAndroid Build Coastguard Worker 246*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 247*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 248*333d2b36SAndroid Build Coastguard Worker 249*333d2b36SAndroid Build Coastguard Worker s.outputs = append(s.outputs, output) 250*333d2b36SAndroid Build Coastguard Worker} 251*333d2b36SAndroid Build Coastguard Worker 252*333d2b36SAndroid Build Coastguard Worker// StartTool returns a new ToolStatus instance to report the status of a tool. 253*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) StartTool() ToolStatus { 254*333d2b36SAndroid Build Coastguard Worker return &toolStatus{ 255*333d2b36SAndroid Build Coastguard Worker status: s, 256*333d2b36SAndroid Build Coastguard Worker } 257*333d2b36SAndroid Build Coastguard Worker} 258*333d2b36SAndroid Build Coastguard Worker 259*333d2b36SAndroid Build Coastguard Worker// Finish will call Flush on all the outputs, generally flushing or closing all 260*333d2b36SAndroid Build Coastguard Worker// of their outputs. Do not call any other functions on this instance or any 261*333d2b36SAndroid Build Coastguard Worker// associated ToolStatus instances after this has been called. 262*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) Finish() { 263*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 264*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 265*333d2b36SAndroid Build Coastguard Worker 266*333d2b36SAndroid Build Coastguard Worker for _, o := range s.outputs { 267*333d2b36SAndroid Build Coastguard Worker o.Flush() 268*333d2b36SAndroid Build Coastguard Worker } 269*333d2b36SAndroid Build Coastguard Worker} 270*333d2b36SAndroid Build Coastguard Worker 271*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) updateTotalActions(diff int) { 272*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 273*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Worker s.counts.TotalActions += diff 276*333d2b36SAndroid Build Coastguard Worker} 277*333d2b36SAndroid Build Coastguard Worker 278*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) SetEstimatedTime(estimatedTime time.Time) { 279*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 280*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 281*333d2b36SAndroid Build Coastguard Worker 282*333d2b36SAndroid Build Coastguard Worker s.counts.EstimatedTime = estimatedTime 283*333d2b36SAndroid Build Coastguard Worker} 284*333d2b36SAndroid Build Coastguard Worker 285*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) startAction(action *Action) { 286*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 287*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 288*333d2b36SAndroid Build Coastguard Worker 289*333d2b36SAndroid Build Coastguard Worker s.counts.RunningActions += 1 290*333d2b36SAndroid Build Coastguard Worker s.counts.StartedActions += 1 291*333d2b36SAndroid Build Coastguard Worker 292*333d2b36SAndroid Build Coastguard Worker for _, o := range s.outputs { 293*333d2b36SAndroid Build Coastguard Worker o.StartAction(action, s.counts) 294*333d2b36SAndroid Build Coastguard Worker } 295*333d2b36SAndroid Build Coastguard Worker} 296*333d2b36SAndroid Build Coastguard Worker 297*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) finishAction(result ActionResult) { 298*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 299*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 300*333d2b36SAndroid Build Coastguard Worker 301*333d2b36SAndroid Build Coastguard Worker s.counts.RunningActions -= 1 302*333d2b36SAndroid Build Coastguard Worker s.counts.FinishedActions += 1 303*333d2b36SAndroid Build Coastguard Worker 304*333d2b36SAndroid Build Coastguard Worker for _, o := range s.outputs { 305*333d2b36SAndroid Build Coastguard Worker o.FinishAction(result, s.counts) 306*333d2b36SAndroid Build Coastguard Worker } 307*333d2b36SAndroid Build Coastguard Worker} 308*333d2b36SAndroid Build Coastguard Worker 309*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) message(level MsgLevel, msg string) { 310*333d2b36SAndroid Build Coastguard Worker s.lock.Lock() 311*333d2b36SAndroid Build Coastguard Worker defer s.lock.Unlock() 312*333d2b36SAndroid Build Coastguard Worker 313*333d2b36SAndroid Build Coastguard Worker for _, o := range s.outputs { 314*333d2b36SAndroid Build Coastguard Worker o.Message(level, msg) 315*333d2b36SAndroid Build Coastguard Worker } 316*333d2b36SAndroid Build Coastguard Worker} 317*333d2b36SAndroid Build Coastguard Worker 318*333d2b36SAndroid Build Coastguard Workerfunc (s *Status) Status(msg string) { 319*333d2b36SAndroid Build Coastguard Worker s.message(StatusLvl, msg) 320*333d2b36SAndroid Build Coastguard Worker} 321*333d2b36SAndroid Build Coastguard Worker 322*333d2b36SAndroid Build Coastguard Workertype toolStatus struct { 323*333d2b36SAndroid Build Coastguard Worker status *Status 324*333d2b36SAndroid Build Coastguard Worker 325*333d2b36SAndroid Build Coastguard Worker counts Counts 326*333d2b36SAndroid Build Coastguard Worker // Protects counts 327*333d2b36SAndroid Build Coastguard Worker lock sync.Mutex 328*333d2b36SAndroid Build Coastguard Worker} 329*333d2b36SAndroid Build Coastguard Worker 330*333d2b36SAndroid Build Coastguard Workervar _ ToolStatus = (*toolStatus)(nil) 331*333d2b36SAndroid Build Coastguard Worker 332*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) SetTotalActions(total int) { 333*333d2b36SAndroid Build Coastguard Worker diff := 0 334*333d2b36SAndroid Build Coastguard Worker 335*333d2b36SAndroid Build Coastguard Worker d.lock.Lock() 336*333d2b36SAndroid Build Coastguard Worker if total >= d.counts.StartedActions && total != d.counts.TotalActions { 337*333d2b36SAndroid Build Coastguard Worker diff = total - d.counts.TotalActions 338*333d2b36SAndroid Build Coastguard Worker d.counts.TotalActions = total 339*333d2b36SAndroid Build Coastguard Worker } 340*333d2b36SAndroid Build Coastguard Worker d.lock.Unlock() 341*333d2b36SAndroid Build Coastguard Worker 342*333d2b36SAndroid Build Coastguard Worker if diff != 0 { 343*333d2b36SAndroid Build Coastguard Worker d.status.updateTotalActions(diff) 344*333d2b36SAndroid Build Coastguard Worker } 345*333d2b36SAndroid Build Coastguard Worker} 346*333d2b36SAndroid Build Coastguard Worker 347*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) SetEstimatedTime(estimatedTime time.Time) { 348*333d2b36SAndroid Build Coastguard Worker d.status.SetEstimatedTime(estimatedTime) 349*333d2b36SAndroid Build Coastguard Worker} 350*333d2b36SAndroid Build Coastguard Worker 351*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) StartAction(action *Action) { 352*333d2b36SAndroid Build Coastguard Worker totalDiff := 0 353*333d2b36SAndroid Build Coastguard Worker 354*333d2b36SAndroid Build Coastguard Worker d.lock.Lock() 355*333d2b36SAndroid Build Coastguard Worker d.counts.RunningActions += 1 356*333d2b36SAndroid Build Coastguard Worker d.counts.StartedActions += 1 357*333d2b36SAndroid Build Coastguard Worker 358*333d2b36SAndroid Build Coastguard Worker if d.counts.StartedActions > d.counts.TotalActions { 359*333d2b36SAndroid Build Coastguard Worker totalDiff = d.counts.StartedActions - d.counts.TotalActions 360*333d2b36SAndroid Build Coastguard Worker d.counts.TotalActions = d.counts.StartedActions 361*333d2b36SAndroid Build Coastguard Worker } 362*333d2b36SAndroid Build Coastguard Worker d.lock.Unlock() 363*333d2b36SAndroid Build Coastguard Worker 364*333d2b36SAndroid Build Coastguard Worker if totalDiff != 0 { 365*333d2b36SAndroid Build Coastguard Worker d.status.updateTotalActions(totalDiff) 366*333d2b36SAndroid Build Coastguard Worker } 367*333d2b36SAndroid Build Coastguard Worker d.status.startAction(action) 368*333d2b36SAndroid Build Coastguard Worker} 369*333d2b36SAndroid Build Coastguard Worker 370*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) FinishAction(result ActionResult) { 371*333d2b36SAndroid Build Coastguard Worker d.lock.Lock() 372*333d2b36SAndroid Build Coastguard Worker d.counts.RunningActions -= 1 373*333d2b36SAndroid Build Coastguard Worker d.counts.FinishedActions += 1 374*333d2b36SAndroid Build Coastguard Worker d.lock.Unlock() 375*333d2b36SAndroid Build Coastguard Worker 376*333d2b36SAndroid Build Coastguard Worker d.status.finishAction(result) 377*333d2b36SAndroid Build Coastguard Worker} 378*333d2b36SAndroid Build Coastguard Worker 379*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) Verbose(msg string) { 380*333d2b36SAndroid Build Coastguard Worker d.status.message(VerboseLvl, msg) 381*333d2b36SAndroid Build Coastguard Worker} 382*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) Status(msg string) { 383*333d2b36SAndroid Build Coastguard Worker d.status.message(StatusLvl, msg) 384*333d2b36SAndroid Build Coastguard Worker} 385*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) Print(msg string) { 386*333d2b36SAndroid Build Coastguard Worker d.status.message(PrintLvl, msg) 387*333d2b36SAndroid Build Coastguard Worker} 388*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) Error(msg string) { 389*333d2b36SAndroid Build Coastguard Worker d.status.message(ErrorLvl, msg) 390*333d2b36SAndroid Build Coastguard Worker} 391*333d2b36SAndroid Build Coastguard Worker 392*333d2b36SAndroid Build Coastguard Workerfunc (d *toolStatus) Finish() { 393*333d2b36SAndroid Build Coastguard Worker d.lock.Lock() 394*333d2b36SAndroid Build Coastguard Worker defer d.lock.Unlock() 395*333d2b36SAndroid Build Coastguard Worker 396*333d2b36SAndroid Build Coastguard Worker if d.counts.TotalActions != d.counts.StartedActions { 397*333d2b36SAndroid Build Coastguard Worker d.status.updateTotalActions(d.counts.StartedActions - d.counts.TotalActions) 398*333d2b36SAndroid Build Coastguard Worker } 399*333d2b36SAndroid Build Coastguard Worker 400*333d2b36SAndroid Build Coastguard Worker // TODO: update status to correct running/finished edges? 401*333d2b36SAndroid Build Coastguard Worker d.counts.RunningActions = 0 402*333d2b36SAndroid Build Coastguard Worker d.counts.TotalActions = d.counts.StartedActions 403*333d2b36SAndroid Build Coastguard Worker} 404