Skip to content

Commit

Permalink
Rename table raw_requests to request_archives. Store full, finalized …
Browse files Browse the repository at this point in the history
…request args. Add Grapher.RequestArgs to get those final req args.
  • Loading branch information
daniel-nichter committed Feb 13, 2019
1 parent 5dd58e4 commit deaecbd
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 124 deletions.
6 changes: 6 additions & 0 deletions job-runner/chain/redis_repo_test.go
Expand Up @@ -193,6 +193,9 @@ func TestGetAll(t *testing.T) {
State: proto.STATE_PENDING,
SequenceId: "job1",
SequenceRetry: 0,
Data: map[string]interface{}{
"a": "b",
},
},
},
}
Expand All @@ -211,6 +214,9 @@ func TestGetAll(t *testing.T) {
State: proto.STATE_RUNNING,
SequenceId: "jobA",
SequenceRetry: 0,
Data: map[string]interface{}{
"foo": "bar",
},
},
},
}
Expand Down
37 changes: 23 additions & 14 deletions proto/proto.go
Expand Up @@ -58,10 +58,10 @@ type Job struct {
Id string `json:"id"` // unique id
Name string `json:"name"` // name of the job
Type string `json:"type"` // user-specific job type
Bytes []byte `json:"bytes"` // return value of Job.Serialize method
Bytes []byte `json:"bytes,omitempty"` // return value of Job.Serialize method
State byte `json:"state"` // STATE_* const
Args map[string]interface{} `json:"args"` // the jobArgs a job was created with
Data map[string]interface{} `json:"data"` // job-specific data during Job.Run
Args map[string]interface{} `json:"args,omitempty"` // the jobArgs a job was created with
Data map[string]interface{} `json:"data,omitempty"` // job-specific data during Job.Run
Retry uint `json:"retry"` // retry N times if first run fails
RetryWait uint `json:"retryWait"` // wait time (milliseconds) between retries
SequenceId string `json:"sequenceStartId"` // ID for first job in sequence
Expand All @@ -79,17 +79,17 @@ type JobChain struct {

// Request represents something that a user asks Spin Cycle to do.
type Request struct {
Id string `json:"id"` // unique identifier for the request
Type string `json:"type"` // the type of request
State byte `json:"state"` // STATE_* const
User string `json:"user"` // the user who made the request
Args map[string]interface{} `json:",omitempty"` // the jobArgs
Id string `json:"id"` // unique identifier for the request
Type string `json:"type"` // the type of request
State byte `json:"state"` // STATE_* const
User string `json:"user"` // the user who made the request
Args []RequestArg `json:"args,omitempty"` // final request args (request_archives.args)

CreatedAt time.Time `json:"createdAt"` // when the request was created
StartedAt *time.Time `json:"startedAt"` // when the request was sent to the job runner
FinishedAt *time.Time `json:"finishedAt"` // when the job runner finished the request. doesn't indicate success/failure

JobChain *JobChain `json:",omitempty"` // the job chain
JobChain *JobChain `json:",omitempty"` // job chain (request_archives.job_chain)
TotalJobs int `json:"totalJobs"` // the number of jobs in the request's job chain
FinishedJobs int `json:"finishedJobs"` // the number of finished jobs in the request

Expand Down Expand Up @@ -123,14 +123,23 @@ type RequestSpec struct {
Args []RequestArg
}

// RequestArg represents one request arg.
// RequestArg represents an request argument and its metadata.
type RequestArg struct {
Name string
Desc string
Required bool
Default string
Pos int // position in request spec relative to required:, optional:, or static: stanza
Name string
Desc string
Type string // required, optional, static
Given bool // true if Required or Optional and value given
Default interface{} // default value if Optional or Static
Value interface{} // final value
}

const (
ARG_TYPE_REQUIRED = "required"
ARG_TYPE_OPTIONAL = "optional"
ARG_TYPE_STATIC = "static"
)

// JobLog represents a log entry for a finished job.
type JobLog struct {
// These three fields uniquely identify an entry in the job log.
Expand Down
56 changes: 54 additions & 2 deletions request-manager/grapher/grapher.go
Expand Up @@ -69,6 +69,58 @@ func (gf *grapherFactory) Make(req proto.Request) *Grapher {
return NewGrapher(req, gf.jf, gf.config, gf.idf.Make()) // create a Grapher with a new id Generator
}

func (o *Grapher) RequestArgs(requestType string, args map[string]interface{}) ([]proto.RequestArg, error) {
reqArgs := []proto.RequestArg{}

seq, ok := o.AllSequences[requestType]
if !ok {
return nil, fmt.Errorf("cannot find definition for request: %s", requestType)
}
if !seq.Request {
return nil, fmt.Errorf("%s is not a request", requestType)
}

for i, arg := range seq.Args.Required {
val, ok := args[arg.Name]
if !ok {
return nil, fmt.Errorf("required arg '%s' not set", arg.Name)
}
reqArgs = append(reqArgs, proto.RequestArg{
Pos: i,
Name: arg.Name,
Type: proto.ARG_TYPE_REQUIRED,
Value: val,
Given: true,
})
}

for i, arg := range seq.Args.Optional {
val, ok := args[arg.Name]
if !ok {
val = arg.Default
}
reqArgs = append(reqArgs, proto.RequestArg{
Pos: i,
Name: arg.Name,
Type: proto.ARG_TYPE_OPTIONAL,
Default: arg.Default,
Value: val,
Given: ok,
})
}

for i, arg := range seq.Args.Static {
reqArgs = append(reqArgs, proto.RequestArg{
Pos: i,
Name: arg.Name,
Type: proto.ARG_TYPE_STATIC,
Value: arg.Default,
})
}

return reqArgs, nil
}

// CreateGraph will create a graph. The user must provide a Sequence Name, to indicate
// what graph will be created. The caller must also provide the first set of args.
func (o *Grapher) CreateGraph(sequenceName string, args map[string]interface{}) (*Graph, error) {
Expand All @@ -84,8 +136,8 @@ func (o *Grapher) CreateGraph(sequenceName string, args map[string]interface{})
return g, nil
}

func (g *Grapher) Sequences() map[string]*SequenceSpec {
return g.AllSequences
func (o *Grapher) Sequences() map[string]*SequenceSpec {
return o.AllSequences
}

// buildSequence will take in a sequence spec and return a Graph that represents the sequence
Expand Down

0 comments on commit deaecbd

Please sign in to comment.