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

Pipeline not getting unlocked upon a successful run - stale cache during race condition #3497

Merged
merged 2 commits into from
May 12, 2017

Conversation

jyotisingh
Copy link
Contributor

@jyotisingh jyotisingh commented May 12, 2017

The PipelineState maintains the pipeline lock status of a pipeline. A significantly high number of queries are made to the PipelineStateDAO to check the pipeline lock status. To avoid frequent queries to database the DAO maintains a cache of the PipelineState and was cleared upon a lock or unlock, which was done as part of a synchronised block. We came across a scenario where the cache got out of sync with the db, below is the scenario.

When an unlock thread exits the synchronized block but hasn't executed a transaction.commit, immediately followed by a read thread ie. pipelineStateFor, the (eh)cache would have been updated with a stale entry from the query-cache (since cacheable was set to true). This cache entry is not cleared thereafter, ie. even after the transaction.commit of unlock happens. This used to lead to a bug wherein some of the pipelines would show up as locked on dashboard even when they were unlocked.

Now, we clear off the ehcache entry only after a transaction commit. This means some of the reads could potentially get seemingly stale data even after the unlock thread exits the synchronized block and before the transaction.commit happens, but that should be ok.

While trying to lock/unlock a pipeline, we used to clear the cache and update the db entry within a synchronized block.
When an unlock thread exits the synchronized block but hasn't executed a transaction.commit, immediately followed by a read thread ie. pipelineStateFor, the (eh)cache would have been updated with a stale entry from the query-cache (since cacheable was set to true). This cache entry is not cleared thereafter, ie. even after the transaction.commit of unlock happens. This used to lead to a bug wherein some of the pipelines would show up as locked on dashboard even when they were unlocked.
Now, we clear off the ehcache entry only after a transaction commit. This means some of the reads could potentially get seemingly stale data even after the unlock thread exits the synchronized block and before the transaction.commit happens, but that should be ok.
@jyotisingh jyotisingh added this to the Release 17.5 milestone May 12, 2017
@jyotisingh jyotisingh requested a review from maheshp May 12, 2017 08:30
Copy link
Contributor

@maheshp maheshp left a comment

Choose a reason for hiding this comment

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

LGTM

@maheshp maheshp merged commit 2b06534 into gocd:master May 12, 2017
@zabil zabil removed the in progress label May 12, 2017
@jyotisingh jyotisingh changed the title Fixing an issue with pipeline state read/save order Pipeline not getting unlocked upon a successful run - stale cache issue Jun 2, 2017
@jyotisingh jyotisingh changed the title Pipeline not getting unlocked upon a successful run - stale cache issue Pipeline not getting unlocked upon a successful run - stale cache during race condition Jun 2, 2017
bhimsenpadalkar pushed a commit to bhimsenpadalkar/gocd that referenced this pull request Jun 14, 2017
* Fixing an issue with pipeline state read/save order

While trying to lock/unlock a pipeline, we used to clear the cache and update the db entry within a synchronized block.
When an unlock thread exits the synchronized block but hasn't executed a transaction.commit, immediately followed by a read thread ie. pipelineStateFor, the (eh)cache would have been updated with a stale entry from the query-cache (since cacheable was set to true). This cache entry is not cleared thereafter, ie. even after the transaction.commit of unlock happens. This used to lead to a bug wherein some of the pipelines would show up as locked on dashboard even when they were unlocked.
Now, we clear off the ehcache entry only after a transaction commit. This means some of the reads could potentially get seemingly stale data even after the unlock thread exits the synchronized block and before the transaction.commit happens, but that should be ok.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants