Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add StateLocker interface to backend operations #17422

Merged
merged 3 commits into from
Feb 27, 2018
Merged

Conversation

jbardin
Copy link
Member

@jbardin jbardin commented Feb 23, 2018

The additional UI code to report the status of obtaining a lock to the user broke the state locking order by having the state refreshed without a lock when creating the initial context. While the lock was still honored for the duration of the actual operations being applied, the command could be starting with a stale version of the state. Most of the time this is not a major issue, since the refresh phase would update the state again, but strict CAS operations used by the Consul backend (and other operations strictly comparing the state.Serial) would fail writing the new state.

Fixes #17407

We start by simplifying the use of clistate.Lock by creating a clistate.Locker interface, which stores the context of locking a state, to allow unlock to be called without knowledge of how the state was locked. This allows the backend code to bring the needed UI methods to the point where the state is locked, and still unlock the state from an outer scope.

That new Locker is then added to the backend.Operation, so the lowest level function scopes of the backend code can lock the state before it's read, while still allowing the different operations to unlock the state when they complete.

Simplify the use of clistate.Lock by creating a clistate.Locker
instance, which stores the context of locking a state, to allow unlock
to be called without knowledge of how the state was locked.

This alows the backend code to bring the needed UI methods to the point
where the state is locked, and still unlock the state from an outer
scope.

Provide a NoopLocker as well, so that callers can always call Unlock
without verifying the status of the lock.

Add the StateLocker field to the backend.Operation, so that the state
lock can be carried between the different function scopes of the backend
code. This will allow the backend context to lock the state before it's
read, while allowing the different operations to unlock the state when
they complete.
Use the new StateLocker field to provide a wrapper for locking the state
during terraform.Context creation in the commands that directly
manipulate the state.
// and LockInfo for the caller, while storing any related data required for
// Unlock.
type Locker interface {
// Lock the provided state, storing the reason string in the LockInfo.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment was a little confusing to me at first because "the LockInfo" seems like an implementation detail of this function, rather than something visible on this interface. However, reading the code below I see that it gets created and passed into the LockWithContext function; I think it could help to clarify a little what side-effects this function has for the given state, since the interactions between subsystems here aren't obvious.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see the confusion. It's because it used to be visible in the interface -- you have to pass a LockInfo to the state Lock method. I'll clarify this a little more

@jbardin jbardin merged commit dc80366 into master Feb 27, 2018
@jbardin jbardin deleted the jbardin/state-locking branch February 27, 2018 16:38
@ghost
Copy link

ghost commented Apr 4, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consul backend locking not working as expected
2 participants