state/remote: Don't hang in PersistState

We were calling from PersistState into RefreshState, but RefreshState is
protected by the same lock as PersistState and so the call would deadlock.

Instead, we introduce a new entry point refreshState which can be used
when already holding the lock.
This commit is contained in:
Martin Atkins 2018-10-02 14:55:43 -07:00
parent 331cb07a05
commit 78f1d1d1c0
1 changed files with 7 additions and 1 deletions

View File

@ -55,7 +55,13 @@ func (s *State) WriteState(state *states.State) error {
func (s *State) RefreshState() error { func (s *State) RefreshState() error {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.refreshState()
}
// refreshState is the main implementation of RefreshState, but split out so
// that we can make internal calls to it from methods that are already holding
// the s.mu lock.
func (s *State) refreshState() error {
payload, err := s.Client.Get() payload, err := s.Client.Get()
if err != nil { if err != nil {
return err return err
@ -95,7 +101,7 @@ func (s *State) PersistState() error {
// We might be writing a new state altogether, but before we do that // We might be writing a new state altogether, but before we do that
// we'll check to make sure there isn't already a snapshot present // we'll check to make sure there isn't already a snapshot present
// that we ought to be updating. // that we ought to be updating.
err := s.RefreshState() err := s.refreshState()
if err != nil { if err != nil {
return fmt.Errorf("failed checking for existing remote state: %s", err) return fmt.Errorf("failed checking for existing remote state: %s", err)
} }