Skip to content

Commit 325ca9d

Browse files
authored
[Platform API] Get and wait for Jobs & Reload App Service Configuration (#105)
1 parent 230fc20 commit 325ca9d

File tree

3 files changed

+181
-0
lines changed

3 files changed

+181
-0
lines changed

pkg/controlplane/http/session.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/v3io/v3io-go/pkg/controlplane"
3131
"github.com/v3io/v3io-go/pkg/errors"
3232

33+
"github.com/nuclio/errors"
3334
"github.com/nuclio/logger"
3435
"github.com/valyala/fasthttp"
3536
)
@@ -245,6 +246,115 @@ func (s *session) GetRunningUserAttributesSync(getRunningUserAttributesInput *v3
245246
return &userNameOutput, err
246247
}
247248

249+
// ReloadAppServicesConfigAndWaitForCompletion reloads the app service config in the backend and waits for job completion (blocking)
250+
func (s *session) ReloadAppServicesConfigAndWaitForCompletion(ctx context.Context, retryInterval, timeout time.Duration) error {
251+
jobId, err := s.ReloadAppServicesConfig(ctx)
252+
if err != nil {
253+
return errors.Wrap(err, "Failed reloading app service config")
254+
}
255+
256+
return s.WaitForJobCompletion(ctx, jobId, retryInterval, timeout)
257+
}
258+
259+
// ReloadAppServicesConfig reloads the app service config in the backend (blocking)
260+
func (s *session) ReloadAppServicesConfig(ctx context.Context) (string, error) {
261+
reloadAppServicesConfigInput := v3ioc.ReloadAppServicesConfigInput{
262+
ControlPlaneInput: v3ioc.ControlPlaneInput{
263+
Ctx: ctx,
264+
},
265+
}
266+
267+
reloadAppServicesConfigJobOutput := v3ioc.ReloadAppServicesConfigJobOutput{}
268+
269+
err := s.createResource(ctx,
270+
"configurations/app_services/reloads",
271+
"cluster_configuration_reload",
272+
&reloadAppServicesConfigInput.ControlPlaneInput,
273+
map[string]string{},
274+
&reloadAppServicesConfigJobOutput.ControlPlaneOutput,
275+
&reloadAppServicesConfigJobOutput.JobAttributes)
276+
277+
if err != nil {
278+
return "", err
279+
}
280+
281+
return reloadAppServicesConfigJobOutput.ID, nil
282+
}
283+
284+
// WaitForJobCompletion waits for completion of job with given id (blocking)
285+
func (s *session) WaitForJobCompletion(ctx context.Context, jobId string, retryInterval, timeout time.Duration) error {
286+
getJobsInput := v3ioc.GetJobsInput{
287+
ControlPlaneInput: v3ioc.ControlPlaneInput{
288+
ID: jobId,
289+
Ctx: ctx,
290+
},
291+
}
292+
293+
deadline := time.Now().Add(timeout)
294+
295+
for time.Now().Before(deadline) {
296+
getJobsOutput, err := s.GetJobs(&getJobsInput)
297+
if err != nil {
298+
return errors.Wrap(err, "Failed getting job")
299+
}
300+
301+
switch getJobsOutput.State {
302+
case v3ioc.JobStateCompleted:
303+
s.logger.DebugWithCtx(ctx,
304+
"Job Completed",
305+
"jobId", jobId,
306+
"jobResult", getJobsOutput.Result)
307+
return nil
308+
case v3ioc.JobStateFailed:
309+
s.logger.WarnWithCtx(ctx,
310+
"Job has failed",
311+
"jobId", jobId,
312+
"jobResult", getJobsOutput.Result)
313+
return errors.New(
314+
"Job has failed")
315+
case v3ioc.JobStateCanceled:
316+
s.logger.WarnWithCtx(ctx,
317+
"Job was canceled",
318+
"jobId", jobId,
319+
"jobResult", getJobsOutput.Result)
320+
return errors.New("Job was canceled")
321+
default:
322+
s.logger.DebugWithCtx(ctx,
323+
"Job in progress",
324+
"jobId", jobId,
325+
"retryInterval", retryInterval,
326+
"timeout", timeout)
327+
328+
// TODO: create and use backoff
329+
time.Sleep(retryInterval)
330+
}
331+
}
332+
333+
return errors.New("Timed out waiting for job completion")
334+
}
335+
336+
// GetJobs gets jobs (blocking)
337+
func (s *session) GetJobs(getJobsInput *v3ioc.GetJobsInput) (*v3ioc.GetJobsOutput, error) {
338+
339+
// prepare job response resource
340+
getJobsOutput := v3ioc.GetJobsOutput{}
341+
342+
// specific path for job detail endpoint
343+
detailPath := fmt.Sprintf("jobs/%s", getJobsInput.ID)
344+
345+
err := s.getResource(getJobsInput.Ctx,
346+
detailPath,
347+
&getJobsInput.ControlPlaneInput,
348+
&getJobsOutput.ControlPlaneOutput,
349+
&getJobsOutput.JobAttributes)
350+
351+
if err != nil {
352+
return nil, err
353+
}
354+
355+
return &getJobsOutput, err
356+
}
357+
248358
func (s *session) createResource(ctx context.Context,
249359
path string,
250360
kind string,

pkg/controlplane/resources.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,40 @@ const (
166166
SessionKind Kind = "session"
167167
AccessKeyKind Kind = "accessKey"
168168
)
169+
170+
type JobState string
171+
172+
const (
173+
JobStateCreated JobState = "created"
174+
JobStateDispatched JobState = "dispatched"
175+
JobStateInProgress JobState = "in_progress"
176+
JobStateCompleted JobState = "completed"
177+
JobStateCanceled JobState = "canceled"
178+
JobStateRepublishing JobState = "republishing"
179+
JobStateFailed JobState = "failed"
180+
)
181+
182+
type JobWebHook struct {
183+
Method string `json:"method,omitempty"`
184+
Target string `json:"target,omitempty"`
185+
Resource string `json:"resource,omitempty"`
186+
Status int `json:"status,omitempty"`
187+
Payload string `json:"payload,omitempty"`
188+
}
189+
190+
type JobAttributes struct {
191+
Kind string `json:"kind,omitempty"`
192+
Params string `json:"params,omitempty"`
193+
UIFields string `json:"ui_fields,omitempty"`
194+
MaxTotalExecutionTime int `json:"max_total_execution_time,omitempty"`
195+
MaxWorkerExecutionTime int `json:"max_worker_execution_time,omitempty"`
196+
Delay float64 `json:"delay,omitempty"`
197+
State JobState `json:"state,omitempty"`
198+
Result string `json:"result,omitempty"`
199+
CreatedAt string `json:"created_at,omitempty"`
200+
OnSuccess []JobWebHook `json:"on_success,omitempty"`
201+
OnFailure []JobWebHook `json:"on_failure,omitempty"`
202+
LinkedResources string `json:"linked_resources,omitempty"`
203+
UpdatedAt string `json:"updated_at,omitempty"`
204+
Handler string `json:"handler,omitempty"`
205+
}

pkg/controlplane/types.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ type Session interface {
4949

5050
// GetRunningUserAttributesSync returns user's attributes related to session's access key (blocking)
5151
GetRunningUserAttributesSync(*GetRunningUserAttributesInput) (*GetRunningUserAttributesOutput, error)
52+
53+
// ReloadAppServicesConfigAndWaitForCompletion reloads the app service config in the backend and waits for job completion (blocking)
54+
ReloadAppServicesConfigAndWaitForCompletion(ctx context.Context, retryInterval, timeout time.Duration) error
55+
56+
// ReloadAppServicesConfig reloads the app service config in the backend (blocking)
57+
ReloadAppServicesConfig(ctx context.Context) (string, error)
58+
59+
// WaitForJobCompletion waits for completion of job with given id (blocking)
60+
WaitForJobCompletion(ctx context.Context, jobId string, retryInterval, timeout time.Duration) error
61+
62+
// GetJobs gets jobs (blocking)
63+
GetJobs(getJobsInput *GetJobsInput) (*GetJobsOutput, error)
5264
}
5365

5466
type ControlPlaneInput struct {
@@ -151,3 +163,25 @@ type GetRunningUserAttributesOutput struct {
151163
ControlPlaneOutput
152164
UserAttributes
153165
}
166+
167+
// GetJobsInput specifies how to get a job
168+
type GetJobsInput struct {
169+
ControlPlaneInput
170+
}
171+
172+
// GetJobsOutput specifies holds the response from get jobs
173+
type GetJobsOutput struct {
174+
ControlPlaneOutput
175+
JobAttributes
176+
}
177+
178+
// ReloadAppServicesConfigInput specifies how to reload the app services configuration
179+
type ReloadAppServicesConfigInput struct {
180+
ControlPlaneInput
181+
}
182+
183+
// ReloadAppServicesConfigJobOutput specifies holds the response from reload app services config
184+
type ReloadAppServicesConfigJobOutput struct {
185+
ControlPlaneOutput
186+
JobAttributes
187+
}

0 commit comments

Comments
 (0)