diff --git a/internal/manager/api_impl/worker_mgt.go b/internal/manager/api_impl/worker_mgt.go index 87612e4e..64edf2a2 100644 --- a/internal/manager/api_impl/worker_mgt.go +++ b/internal/manager/api_impl/worker_mgt.go @@ -81,16 +81,24 @@ func (f *Flamenco) RequestWorkerStatusChange(e echo.Context, workerUUID string) return sendAPIError(e, http.StatusInternalServerError, "error fetching worker: %v", err) } - // Store the status change. logger = logger.With(). Str("status", string(dbWorker.Status)). Str("requested", string(change.Status)). Bool("lazy", change.IsLazy). Logger() - logger.Info().Msg("worker status change requested") - dbWorker.StatusRequested = change.Status - dbWorker.LazyStatusRequest = change.IsLazy + + if dbWorker.Status == change.Status { + // Requesting that the worker should go to its current status basically + // means cancelling any previous status change request. + dbWorker.StatusRequested = "" + dbWorker.LazyStatusRequest = false + } else { + dbWorker.StatusRequested = change.Status + dbWorker.LazyStatusRequest = change.IsLazy + } + + // Store the status change. if err := f.persist.SaveWorker(e.Request().Context(), dbWorker); err != nil { logger.Error().Err(err).Msg("error saving worker after status change request") return sendAPIError(e, http.StatusInternalServerError, "error saving worker: %v", err) diff --git a/internal/manager/api_impl/worker_mgt_test.go b/internal/manager/api_impl/worker_mgt_test.go index 19f383be..cb259711 100644 --- a/internal/manager/api_impl/worker_mgt_test.go +++ b/internal/manager/api_impl/worker_mgt_test.go @@ -162,3 +162,49 @@ func TestRequestWorkerStatusChange(t *testing.T) { assert.NoError(t, err) assertResponseEmpty(t, echo) } + +func TestRequestWorkerStatusChangeRevert(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mf := newMockedFlamenco(mockCtrl) + worker := testWorker() + + // Mimick that a status change request to 'asleep' was already performed. + worker.StatusRequested = api.WorkerStatusAsleep + worker.LazyStatusRequest = true + + workerUUID := worker.UUID + currentStatus := worker.Status + + mf.persistence.EXPECT().FetchWorker(gomock.Any(), workerUUID).Return(&worker, nil) + + // Perform a request to go to the current worker status. This should cancel + // the previous status change request. + requestStatus := currentStatus + savedWorker := worker + savedWorker.StatusRequested = "" + savedWorker.LazyStatusRequest = false + mf.persistence.EXPECT().SaveWorker(gomock.Any(), &savedWorker).Return(nil) + + // Expect a broadcast of the change + mf.broadcaster.EXPECT().BroadcastWorkerUpdate(api.SocketIOWorkerUpdate{ + Id: worker.UUID, + Nickname: worker.Name, + Status: currentStatus, + Updated: worker.UpdatedAt, + Version: worker.Software, + StatusChange: nil, + }) + + echo := mf.prepareMockedJSONRequest(api.WorkerStatusChangeRequest{ + Status: requestStatus, + + // This shouldn't matter; requesting the current status should simply erase + // the previous status change request. + IsLazy: true, + }) + err := mf.flamenco.RequestWorkerStatusChange(echo, workerUUID) + assert.NoError(t, err) + assertResponseEmpty(t, echo) +}