Skip to content
This repository was archived by the owner on Mar 24, 2023. It is now read-only.

Commit fe248e2

Browse files
authored
Merge pull request #934 from laverya/async-state-update
sync state update
2 parents 4dcccde + e3e413f commit fe248e2

File tree

8 files changed

+36
-42
lines changed

8 files changed

+36
-42
lines changed

pkg/lifecycle/daemon/routes_navcycle_completestep.go

+4-8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/replicatedhq/ship/pkg/api"
1313
"github.com/replicatedhq/ship/pkg/lifecycle/daemon/daemontypes"
1414
"github.com/replicatedhq/ship/pkg/lifecycle/daemon/statusonly"
15+
"github.com/replicatedhq/ship/pkg/state"
1516
"github.com/replicatedhq/ship/pkg/util/warnings"
1617
)
1718

@@ -67,14 +68,9 @@ func (d *NavcycleRoutes) handleAsync(errChan chan error, debug log.Logger, step
6768
return
6869
}
6970

70-
state, err := d.StateManager.TryLoad()
71-
if err != nil {
72-
level.Error(d.Logger).Log("event", "state.load.fail", "err", err)
73-
return
74-
}
75-
76-
newState := state.Versioned().WithCompletedStep(step)
77-
err = d.StateManager.Save(newState)
71+
_, err := d.StateManager.StateUpdate(func(currentState state.VersionedState) (state.VersionedState, error) {
72+
return currentState.WithCompletedStep(step), nil
73+
})
7874
if err != nil {
7975
level.Error(d.Logger).Log("event", "state.save.fail", "err", err, "step.id", stepID)
8076
return

pkg/lifecycle/daemon/routes_navcycle_completestep_test.go

+16-17
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ import (
1717
"github.com/replicatedhq/ship/pkg/templates"
1818
"github.com/replicatedhq/ship/pkg/test-mocks/lifecycle"
1919
planner2 "github.com/replicatedhq/ship/pkg/test-mocks/planner"
20-
"github.com/replicatedhq/ship/pkg/test-mocks/state"
2120
"github.com/replicatedhq/ship/pkg/testing/logger"
2221
"github.com/replicatedhq/ship/pkg/testing/matchers"
22+
"github.com/spf13/afero"
2323
"github.com/spf13/viper"
2424
"github.com/stretchr/testify/require"
2525
)
@@ -333,16 +333,18 @@ func TestV2CompleteStep(t *testing.T) {
333333
},
334334
},
335335
}
336-
mc := gomock.NewController(t)
337-
fakeState := state.NewMockManager(mc)
336+
338337
testLogger := &logger.TestLogger{T: t}
338+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
339+
realState := state2.NewManager(testLogger, fs, viper.New())
340+
mc := gomock.NewController(t)
339341
messenger := lifecycle.NewMockMessenger(mc)
340342
renderer := lifecycle.NewMockRenderer(mc)
341343
mockPlanner := planner2.NewMockPlanner(mc)
342344
v2 := &NavcycleRoutes{
343-
BuilderBuilder: templates.NewBuilderBuilder(testLogger, viper.New(), fakeState),
345+
BuilderBuilder: templates.NewBuilderBuilder(testLogger, viper.New(), realState),
344346
Logger: testLogger,
345-
StateManager: fakeState,
347+
StateManager: realState,
346348
Messenger: messenger,
347349
Renderer: renderer,
348350
Planner: mockPlanner,
@@ -352,14 +354,6 @@ func TestV2CompleteStep(t *testing.T) {
352354
StepProgress: &daemontypes.ProgressMap{},
353355
}
354356

355-
fakeState.EXPECT().TryLoad().Return(state2.VersionedState{
356-
V1: &state2.V1{
357-
Lifecycle: &state2.Lifeycle{
358-
StepsCompleted: make(map[string]interface{}),
359-
},
360-
},
361-
}, nil).AnyTimes()
362-
363357
if test.OnExecute != nil {
364358
v2.StepExecutor = test.OnExecute
365359
}
@@ -379,10 +373,6 @@ func TestV2CompleteStep(t *testing.T) {
379373

380374
// send request
381375
for _, testCase := range test.POSTS {
382-
if testCase.ExpectState != nil && testCase.ExpectState.Test != nil {
383-
fakeState.EXPECT().Save(testCase.ExpectState).Return(nil)
384-
}
385-
386376
resp, err := http.Post(fmt.Sprintf("%s%s", addr, testCase.POST), "application/json", strings.NewReader(""))
387377
req.NoError(err)
388378
req.Equal(testCase.ExpectStatus, resp.StatusCode)
@@ -398,6 +388,15 @@ func TestV2CompleteStep(t *testing.T) {
398388
bodyForDebug = []byte(err.Error())
399389
}
400390
req.Empty(diff, "\nexpect: %s\nactual: %s\ndiff: %s", bodyForDebug, string(bytes), strings.Join(diff, "\n"))
391+
392+
if testCase.ExpectState != nil && testCase.ExpectState.Test != nil {
393+
// there is almost certainly a better solution than this
394+
time.Sleep(time.Duration(time.Millisecond * 500))
395+
396+
loadState, err := realState.TryLoad()
397+
req.NoError(err)
398+
req.True(testCase.ExpectState.Test(loadState), testCase.ExpectState.Describe)
399+
}
401400
}
402401
}()
403402
})

pkg/lifecycle/render/config/daemonresolver_test.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ import (
88

99
"github.com/mitchellh/cli"
1010
"github.com/replicatedhq/libyaml"
11-
"github.com/spf13/afero"
12-
"github.com/spf13/viper"
13-
"github.com/stretchr/testify/require"
14-
1511
"github.com/replicatedhq/ship/pkg/api"
1612
"github.com/replicatedhq/ship/pkg/lifecycle/daemon"
1713
"github.com/replicatedhq/ship/pkg/lifecycle/daemon/headless"
@@ -21,6 +17,9 @@ import (
2117
templates "github.com/replicatedhq/ship/pkg/templates"
2218
"github.com/replicatedhq/ship/pkg/testing/logger"
2319
"github.com/replicatedhq/ship/pkg/ui"
20+
"github.com/spf13/afero"
21+
"github.com/spf13/viper"
22+
"github.com/stretchr/testify/require"
2423
)
2524

2625
type daemonResolverTestCase struct {

pkg/specs/persist.go

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"strings"
88

99
"github.com/pkg/errors"
10-
1110
"github.com/replicatedhq/ship/pkg/state"
1211
)
1312

pkg/specs/replicatedapp/graphql.go

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import (
1414
"github.com/pkg/errors"
1515
"github.com/replicatedhq/ship/pkg/api"
1616
"github.com/replicatedhq/ship/pkg/state"
17-
1817
"github.com/spf13/viper"
1918
)
2019

pkg/specs/stategetter/client_test.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import (
66
"path/filepath"
77
"testing"
88

9-
"github.com/stretchr/testify/require"
10-
119
"github.com/replicatedhq/ship/pkg/state"
1210
"github.com/replicatedhq/ship/pkg/testing/logger"
13-
1411
"github.com/spf13/afero"
12+
"github.com/stretchr/testify/require"
1513
)
1614

1715
func TestStateGetter_GetFiles(t *testing.T) {

pkg/state/manager.go

+12-7
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,12 @@ var _ Manager = &MManager{}
5353

5454
// MManager is the saved output of a plan run to load on future runs
5555
type MManager struct {
56-
Logger log.Logger
57-
FS afero.Afero
58-
V *viper.Viper
59-
patcher patch.Patcher
60-
mut sync.Mutex
56+
Logger log.Logger
57+
FS afero.Afero
58+
V *viper.Viper
59+
patcher patch.Patcher
60+
stateUpdateMut sync.Mutex
61+
StateRWMut sync.RWMutex
6162
}
6263

6364
func (m *MManager) Save(v VersionedState) error {
@@ -87,8 +88,8 @@ type Update func(VersionedState) (VersionedState, error)
8788

8889
// applies the provided updater to the current state. Returns the new state and err
8990
func (m *MManager) StateUpdate(updater Update) (State, error) {
90-
m.mut.Lock()
91-
defer m.mut.Unlock()
91+
m.stateUpdateMut.Lock()
92+
defer m.stateUpdateMut.Unlock()
9293

9394
currentState, err := m.TryLoad()
9495
if err != nil {
@@ -266,6 +267,8 @@ func (m *MManager) SerializeUpstreamContents(contents *UpstreamContents) error {
266267

267268
// TryLoad will attempt to load a state file from disk, if present
268269
func (m *MManager) TryLoad() (State, error) {
270+
m.StateRWMut.RLock()
271+
defer m.StateRWMut.RUnlock()
269272
stateFrom := m.V.GetString("state-from")
270273
if stateFrom == "" {
271274
stateFrom = "file"
@@ -426,6 +429,8 @@ func (m *MManager) RemoveStateFile() error {
426429
}
427430

428431
func (m *MManager) serializeAndWriteState(state VersionedState) error {
432+
m.StateRWMut.Lock()
433+
defer m.StateRWMut.Unlock()
429434
debug := level.Debug(log.With(m.Logger, "method", "serializeAndWriteState"))
430435
state = state.migrateDeprecatedFields()
431436

pkg/state/manager_test.go

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/replicatedhq/ship/pkg/constants"
1212
"github.com/replicatedhq/ship/pkg/testing/logger"
1313
"github.com/replicatedhq/ship/pkg/util"
14-
1514
"github.com/spf13/afero"
1615
"github.com/spf13/viper"
1716
"github.com/stretchr/testify/require"

0 commit comments

Comments
 (0)