Skip to content

Commit

Permalink
[CLD-5461] Add fix so that when force is used a release can run in pa…
Browse files Browse the repository at this point in the history
…rallel with another one in progress forcing its way (#21)

* CLD-5461 Add fix so that when force is used a release can run in parallel with another one in progress forcing its way

* CLD-5461 Fix tests and add test case for force true

---------

Co-authored-by: Stylianos Rigas <[email protected]>
  • Loading branch information
stylianosrigas and Stylianos Rigas committed Jun 28, 2023
1 parent 63b4a70 commit 4e2c6e7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 26 deletions.
56 changes: 33 additions & 23 deletions internal/supervisor/ring.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,37 +234,47 @@ func (s *RingSupervisor) releaseRing(ring *model.Ring, logger log.FieldLogger) s
}

func (s *RingSupervisor) checkRingReleasePending(ring *model.Ring, logger log.FieldLogger) string {
logger.Debug("Checking if other Rings are locked...")
logger.Debugf("Checking if pending ring release should be forced...")

ringsLocked, err := s.store.GetRingsLocked()
release, err := s.store.GetRingRelease(ring.DesiredReleaseID)
if err != nil {
logger.WithError(err).Error("Failed to query for rings that are under lock")
logger.WithError(err).Error("Failed to get the ring release for the ring pending work")
return model.RingStateReleaseFailed
}

ringsReleaseInProgress, err := s.store.GetRingsReleaseInProgress()
if err != nil {
logger.WithError(err).Error("Failed to query for rings that are under release")
return model.RingStateReleaseFailed
}
if !release.Force {
logger.Debug("Checking if other Rings are locked...")

//The total rings locked at this time will be at least 1
if len(ringsLocked) > 1 || len(ringsReleaseInProgress) > 0 {
logger.Debug("Another ring is under lock and being updated...")
return model.InstallationGroupReleasePending
}
ringsLocked, err := s.store.GetRingsLocked()
if err != nil {
logger.WithError(err).Error("Failed to query for rings that are under lock")
return model.RingStateReleaseFailed
}

logger.Debugf("Checking ring %s prioritization", ring.ID)
rings, err := s.store.GetUnlockedRingsPendingWork()
if err != nil {
logger.WithError(err).Error("Failed to get rings pending work for prioritization check")
return model.RingStateReleaseFailed
}
ringsReleaseInProgress, err := s.store.GetRingsReleaseInProgress()
if err != nil {
logger.WithError(err).Error("Failed to query for rings that are under release")
return model.RingStateReleaseFailed
}

//The total rings locked at this time will be at least 1
if len(ringsLocked) > 1 || len(ringsReleaseInProgress) > 0 {
logger.Debug("Another ring is under lock and being updated...")
return model.InstallationGroupReleasePending
}

logger.Debugf("Checking ring %s prioritization", ring.ID)
rings, err := s.store.GetUnlockedRingsPendingWork()
if err != nil {
logger.WithError(err).Error("Failed to get rings pending work for prioritization check")
return model.RingStateReleaseFailed
}

for _, rg := range rings {
if rg.Priority < ring.Priority {
logger.Debugf("Ring %s is in priority", rg.ID)
return model.RingStateReleasePending
for _, rg := range rings {
if rg.Priority < ring.Priority {
logger.Debugf("Ring %s is in priority", rg.ID)
return model.RingStateReleasePending
}
}
}

Expand Down
52 changes: 49 additions & 3 deletions internal/supervisor/ring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package supervisor_test

import (
"testing"
"time"

"github.com/mattermost/elrond/internal/store"
"github.com/mattermost/elrond/internal/supervisor"
Expand Down Expand Up @@ -174,17 +175,62 @@ func TestRingSupervisorSupervise(t *testing.T) {
sqlStore := store.MakeTestSQLStore(t, logger)
supervisor := supervisor.NewRingSupervisor(sqlStore, &mockRingProvisioner{}, "instanceID", logger)

release, err := sqlStore.GetOrCreateRingRelease(&model.RingRelease{
Version: "test-version",
Image: "test-image",
Force: false,
EnvVariables: nil,
CreateAt: time.Now().UnixNano(),
})
require.NoError(t, err)

Ring := &model.Ring{
State: tc.InitialState,
ActiveReleaseID: release.ID,
DesiredReleaseID: release.ID,
}

installationGroup := model.InstallationGroup{
Name: "group1",
State: model.InstallationGroupStable,
}

err = sqlStore.CreateRing(Ring, &installationGroup)
require.NoError(t, err)

supervisor.Supervise(Ring)

Ring, err = sqlStore.GetRing(Ring.ID)
require.NoError(t, err)
require.Equal(t, tc.ExpectedState, Ring.State)
})

t.Run(tc.Description, func(t *testing.T) {
logger := testlib.MakeLogger(t)
sqlStore := store.MakeTestSQLStore(t, logger)
supervisor := supervisor.NewRingSupervisor(sqlStore, &mockRingProvisioner{}, "instanceID", logger)

release, err := sqlStore.GetOrCreateRingRelease(&model.RingRelease{
Version: "test-version",
Image: "test-image",
Force: true,
EnvVariables: nil,
CreateAt: time.Now().UnixNano(),
})
require.NoError(t, err)

Ring := &model.Ring{
State: tc.InitialState,
ActiveReleaseID: "active-release-id",
State: tc.InitialState,
ActiveReleaseID: release.ID,
DesiredReleaseID: release.ID,
}

installationGroup := model.InstallationGroup{
Name: "group1",
State: model.InstallationGroupStable,
}

err := sqlStore.CreateRing(Ring, &installationGroup)
err = sqlStore.CreateRing(Ring, &installationGroup)
require.NoError(t, err)

supervisor.Supervise(Ring)
Expand Down

0 comments on commit 4e2c6e7

Please sign in to comment.