Index: appengine/cmd/dm/distributor/impl/jobsim/parser/types.go |
diff --git a/appengine/cmd/dm/distributor/impl/jobsim/parser/types.go b/appengine/cmd/dm/distributor/impl/jobsim/parser/types.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9ef5119dc6c566832fad8054c9dbb13a2a5c9ae7 |
--- /dev/null |
+++ b/appengine/cmd/dm/distributor/impl/jobsim/parser/types.go |
@@ -0,0 +1,142 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package parser |
+ |
+import ( |
+ "bytes" |
+ "fmt" |
+ "time" |
+) |
+ |
+// A Phrase is a comma separated list of Stages. |
+type Phrase []Stage |
+ |
+func (p Phrase) String() string { |
+ if len(p) == 0 { |
+ return "" |
+ } |
+ out := bytes.Buffer{} |
+ for i, s := range p { |
+ if i != 0 { |
+ out.WriteRune(',') |
+ } |
+ out.WriteString(s.String()) |
+ } |
+ return out.String() |
+} |
+ |
+// A Stage is a variadic type which is one distinct instruction in a phase. |
+// |
+// Every time a Phrase is executed, each stage's behavior will be executed, |
+// in order. The types of stages currently available are: |
+// * FailureStage |
+// * StallStage |
+// * DepsStage |
+// * ReturnStage |
+type Stage interface { |
+ fmt.Stringer |
+ |
+ isStage() |
+} |
+ |
+func (FailureStage) isStage() {} |
+func (StallStage) isStage() {} |
+func (*ReturnStage) isStage() {} |
+func (DepsStage) isStage() {} |
+ |
+// FailureStage - a Stage with a certain percentage chance of failure |
+type FailureStage uint64 |
+ |
+func (f FailureStage) String() string { |
+ return fmt.Sprintf("%%%d", f) |
+} |
+ |
+// StallStage - a Stage which sleeps for a certain amount of time |
+type StallStage time.Duration |
+ |
+func (s StallStage) String() string { |
+ return fmt.Sprintf("@%d", (time.Duration)(s)/time.Second) |
+} |
+ |
+// ReturnStage - a Stage which returns a value for the Phrase, with a possible |
+// expiration time. The ReturnStage is a bit special, as only ONE may be |
+// present in a Phrase, and if it's present, it must be the last stage. |
+type ReturnStage struct { |
+ Value uint64 |
+ Expiration time.Duration |
+} |
+ |
+func (r *ReturnStage) String() string { |
+ if r.Expiration > 0 { |
+ return fmt.Sprintf("=%d<%d", r.Value, r.Expiration/time.Second) |
+ } |
+ return fmt.Sprintf("=%d", r.Value) |
+} |
+ |
+// DepsStage - a Stage which depends on one or more Dependencies. This |
+// translates into a re-execution point in DM. |
+type DepsStage []*Dependency |
+ |
+func (ds DepsStage) String() string { |
+ ret := bytes.Buffer{} |
+ for i, d := range ds { |
+ if i != 0 { |
+ ret.WriteRune('&') |
+ } |
+ ret.WriteString(d.String()) |
+ } |
+ return ret.String() |
+} |
+ |
+// A Dependency is the encapsulation of a sub-job. The job AT LEAST has a Name, |
+// but may have other attributes as well. |
+type Dependency struct { |
+ Name string |
+ |
+ // Indicated by {N}, this is a shorthand for making N duplicates of this |
+ // Dependency in-place but with different Shard parameter values. If this is |
+ // 0, the shard parameter are omitted, and this Dependency will only refer to |
+ // one Quest. |
+ ShardCount uint64 |
+ |
+ // AttemptNums is a RangeSlice of which attempt numbers to depend on. If it's |
+ // nil, it will only depend on Attempt #1, unless Retries is specified. |
+ AttemptNums RangeSlice |
+ |
+ // Retries will indicate the number of times this will retry failed substages |
+ // (see FailureStage). It is incompatible with a specified AttemptNums. |
+ Retries uint64 |
+ |
+ // Uniq identifies a 'globally' unique job graph. Each simulated job has 1 or |
+ // more root phrases. If this value is 0, the job will be unique within a root |
+ // phrase. If it's non-zero, it will be unique across all roots. You can have |
+ // multiple different globally unique phrases by setting this to different |
+ // values. |
+ Uniq uint64 |
+ |
+ // Substages is the description of what this Dependency will DO. If it's empty, |
+ // then this Dependency will behave as if it were `ReturnStage(1)`. |
+ Substages Phrase |
+} |
+ |
+func (d *Dependency) String() string { |
+ ret := &bytes.Buffer{} |
+ if d.ShardCount > 0 { |
+ fmt.Fprintf(ret, "{%d}", d.ShardCount) |
+ } |
+ if d.AttemptNums != nil { |
+ fmt.Fprintf(ret, "[%s]", d.AttemptNums.String()) |
+ } |
+ fmt.Fprintf(ret, d.Name) |
+ if d.Retries != 0 { |
+ fmt.Fprintf(ret, "+%d", d.Retries) |
+ } else if d.Uniq != 0 { |
+ fmt.Fprintf(ret, "^%d", d.Uniq) |
+ } |
+ if len(d.Substages) > 0 { |
+ fmt.Fprintf(ret, "(%s)", d.Substages.String()) |
+ } |
+ return ret.String() |
+} |