@@ -4,16 +4,21 @@ import (
4
4
"context"
5
5
"errors"
6
6
"go.uber.org/zap"
7
+ "sync"
7
8
)
8
9
9
10
// CreateTask creates a task structure and sets up its underlying workload on a provider, including sidecars if there are any in the definition
10
11
func CreateTask (ctx context.Context , logger * zap.Logger , provider Provider , definition TaskDefinition ) (* Task , error ) {
11
12
task := & Task {
12
13
Provider : provider ,
13
14
Definition : definition ,
15
+ mu : sync.RWMutex {},
14
16
logger : logger .Named ("task" ),
15
17
}
16
18
19
+ task .mu .Lock ()
20
+ defer task .mu .Unlock ()
21
+
17
22
sidecarTasks := make ([]* Task , 0 )
18
23
19
24
for _ , sidecar := range definition .Sidecars {
@@ -49,6 +54,9 @@ func CreateTask(ctx context.Context, logger *zap.Logger, provider Provider, defi
49
54
50
55
// Start starts the underlying task's workload including its sidecars if startSidecars is set to true
51
56
func (t * Task ) Start (ctx context.Context , startSidecars bool ) error {
57
+ t .mu .Lock ()
58
+ defer t .mu .Unlock ()
59
+
52
60
if startSidecars {
53
61
for _ , sidecar := range t .Sidecars {
54
62
err := sidecar .Start (ctx , startSidecars )
@@ -75,6 +83,9 @@ func (t *Task) Start(ctx context.Context, startSidecars bool) error {
75
83
76
84
// Stop stops the underlying task's workload including its sidecars if stopSidecars is set to true
77
85
func (t * Task ) Stop (ctx context.Context , stopSidecars bool ) error {
86
+ t .mu .Lock ()
87
+ defer t .mu .Unlock ()
88
+
78
89
if stopSidecars {
79
90
for _ , sidecar := range t .Sidecars {
80
91
err := sidecar .Stop (ctx , stopSidecars )
@@ -102,27 +113,42 @@ func (t *Task) Stop(ctx context.Context, stopSidecars bool) error {
102
113
103
114
// WriteFile writes to a file in the task's volume at a relative path
104
115
func (t * Task ) WriteFile (ctx context.Context , path string , bz []byte ) error {
116
+ t .mu .Lock ()
117
+ defer t .mu .Unlock ()
118
+
105
119
return t .Provider .WriteFile (ctx , t .ID , path , bz )
106
120
}
107
121
108
122
// ReadFile returns a file's contents in the task's volume at a relative path
109
123
func (t * Task ) ReadFile (ctx context.Context , path string ) ([]byte , error ) {
124
+ t .mu .RLock ()
125
+ defer t .mu .RUnlock ()
126
+
110
127
return t .Provider .ReadFile (ctx , t .ID , path )
111
128
}
112
129
113
130
// DownloadDir downloads a directory from the task's volume at path relPath to a local path localPath
114
131
func (t * Task ) DownloadDir (ctx context.Context , relPath , localPath string ) error {
132
+ t .mu .RLock ()
133
+ defer t .mu .RUnlock ()
134
+
115
135
return t .Provider .DownloadDir (ctx , t .ID , relPath , localPath )
116
136
}
117
137
118
138
// GetIP returns the task's IP
119
139
func (t * Task ) GetIP (ctx context.Context ) (string , error ) {
140
+ t .mu .RLock ()
141
+ defer t .mu .RUnlock ()
142
+
120
143
return t .Provider .GetIP (ctx , t .ID )
121
144
}
122
145
123
146
// GetExternalAddress returns the external address for a specific task port in format host:port.
124
147
// Providers choose the protocol to return the port for themselves.
125
148
func (t * Task ) GetExternalAddress (ctx context.Context , port string ) (string , error ) {
149
+ t .mu .RLock ()
150
+ defer t .mu .RUnlock ()
151
+
126
152
return t .Provider .GetExternalAddress (ctx , t .ID , port )
127
153
}
128
154
@@ -134,19 +160,30 @@ func (t *Task) RunCommand(ctx context.Context, command []string) (string, string
134
160
}
135
161
136
162
if status == TASK_RUNNING {
163
+ t .mu .Lock ()
164
+ defer t .mu .Unlock ()
137
165
return t .Provider .RunCommand (ctx , t .ID , command )
138
166
}
139
167
168
+ t .mu .Lock ()
169
+ defer t .mu .Unlock ()
170
+
140
171
return t .Provider .RunCommandWhileStopped (ctx , t .ID , t .Definition , command )
141
172
}
142
173
143
174
// GetStatus returns the task's underlying workload's status
144
175
func (t * Task ) GetStatus (ctx context.Context ) (TaskStatus , error ) {
176
+ t .mu .RLock ()
177
+ defer t .mu .RUnlock ()
178
+
145
179
return t .Provider .GetTaskStatus (ctx , t .ID )
146
180
}
147
181
148
182
// Destroy destroys the task's underlying workload, including it's sidecars if destroySidecars is set to true
149
183
func (t * Task ) Destroy (ctx context.Context , destroySidecars bool ) error {
184
+ t .mu .Lock ()
185
+ defer t .mu .Unlock ()
186
+
150
187
if destroySidecars {
151
188
for _ , sidecar := range t .Sidecars {
152
189
err := sidecar .Destroy (ctx , destroySidecars )
@@ -166,10 +203,16 @@ func (t *Task) Destroy(ctx context.Context, destroySidecars bool) error {
166
203
167
204
// SetPreStart sets a task's hook function that gets called right before the task's underlying workload is about to be started
168
205
func (t * Task ) SetPreStart (f func (context.Context , * Task ) error ) {
206
+ t .mu .Lock ()
207
+ defer t .mu .Unlock ()
208
+
169
209
t .PreStart = f
170
210
}
171
211
172
212
// SetPostStop sets a task's hook function that gets called right after the task's underlying workload is stopped
173
213
func (t * Task ) SetPostStop (f func (context.Context , * Task ) error ) {
214
+ t .mu .Lock ()
215
+ defer t .mu .Unlock ()
216
+
174
217
t .PostStop = f
175
218
}
0 commit comments