forked from pcelvng/task
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.go
149 lines (128 loc) · 3.42 KB
/
task.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package task
import (
"bytes"
"encoding/json"
"time"
"github.com/google/uuid"
)
// New creates a new Task with the provided type
// and info and sets the created date.
func New(tskType, info string) *Task {
now := time.Now().In(time.UTC)
return &Task{
Type: tskType,
Info: info,
ID: uuid.New().String(),
Created: now.Format(time.RFC3339),
created: now,
}
}
// NewWithID create a task with a predefined id.
// This is useful for changing tasks together
func NewWithID(tskType, info, id string) *Task {
now := time.Now().In(time.UTC)
return &Task{
Type: tskType,
Info: info,
ID: id,
Created: now.Format(time.RFC3339),
created: now,
}
}
// NewFromBytes creates a Task from
// json bytes.
func NewFromBytes(b []byte) (*Task, error) {
t := &Task{}
err := json.Unmarshal(b, t)
if err != nil {
return nil, err
}
// parse time.Time values
// if any values come in as valid zero times then
// modify the string to be a zero value so that
// omitempty json serialization is correct.
if t.Created != "" {
created, err := time.Parse(time.RFC3339, t.Created)
if err != nil {
return nil, err
}
t.created = created.In(time.UTC)
if t.created.IsZero() {
t.Created = ""
}
}
if t.Started != "" {
started, err := time.Parse(time.RFC3339, t.Started)
if err != nil {
return nil, err
}
t.started = started.In(time.UTC)
if t.started.IsZero() {
t.Started = ""
}
}
if t.Ended != "" {
ended, err := time.Parse(time.RFC3339, t.Ended)
if err != nil {
return nil, err
}
t.ended = ended.In(time.UTC)
if t.ended.IsZero() {
t.Ended = ""
}
}
return t, nil
}
func IsZero(t Task) bool {
return t.Type == "" && t.Result == "" && t.Created == "" && t.Info == ""
}
type Task struct {
Type string `json:"type"` // identifier that indicates the type of worker that knows how to complete the task
Info string `json:"info"` // information that tells the worker the specifics of executing the task
Created string `json:"created,omitempty"`
ID string `json:"id,omitempty"` // unique report id
Meta string `json:"meta,omitempty"` // additional meta data as required
// Result fields
Result Result `json:"result,omitempty"`
Msg string `json:"msg,omitempty"`
Started string `json:"started,omitempty"`
Ended string `json:"ended,omitempty"`
// actual time.Time values so that JSON is omitempty correct and time.Time
// values are not pointers.
created time.Time
started time.Time
ended time.Time
}
// Start marks the task as started
func (t *Task) Start() time.Time {
t.started = time.Now().In(time.UTC)
t.Started = t.started.Format(time.RFC3339)
return t.started
}
// End will mark the task as started by populating
// Ended and setting Result.
//
func (t *Task) End(r Result, msg string) time.Time {
t.Result = r
t.Msg = msg
t.ended = time.Now().In(time.UTC)
t.Ended = t.ended.Format(time.RFC3339)
return t.ended
}
// JSONBytes returns the task json bytes.
func (t *Task) JSONBytes() []byte {
buf := bytes.NewBuffer([]byte{})
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
enc.Encode(t)
return bytes.TrimRight(buf.Bytes(), "\n")
}
// String returns json string.
func (t *Task) JSONString() string {
return string(t.JSONBytes())
}
type Result string
const (
CompleteResult Result = "complete" // completed successfully (as far as the worker can tell)
ErrResult Result = "error" // not completed successfully (the task outcome is bad)
)