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

used uber atomic bool instead standard in lock/unlock db #580

Merged
merged 14 commits into from
Jun 23, 2021

Conversation

prinkov
Copy link
Contributor

@prinkov prinkov commented Jun 12, 2021

No description provided.

@coveralls
Copy link

coveralls commented Jun 12, 2021

Pull Request Test Coverage Report for Build 466

  • 151 of 218 (69.27%) changed or added relevant lines in 16 files are covered.
  • 5 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-0.3%) to 57.141%

Changes Missing Coverage Covered Lines Changed/Added Lines %
database/clickhouse/clickhouse.go 0 1 0.0%
database/ql/ql.go 2 3 66.67%
database/sqlcipher/sqlcipher.go 2 3 66.67%
database/sqlite/sqlite.go 2 3 66.67%
database/sqlite3/sqlite3.go 2 3 66.67%
database/cassandra/cassandra.go 2 4 50.0%
database/firebird/firebird.go 2 4 50.0%
database/redshift/redshift.go 2 4 50.0%
database/stub/stub.go 2 4 50.0%
database/mongodb/mongodb.go 38 44 86.36%
Files with Coverage Reduction New Missed Lines %
database/cockroachdb/cockroachdb.go 1 61.57%
database/ql/ql.go 1 62.2%
database/sqlcipher/sqlcipher.go 1 66.1%
database/sqlite3/sqlite3.go 1 66.1%
database/sqlite/sqlite.go 1 66.1%
Totals Coverage Status
Change from base Build 420: -0.3%
Covered Lines: 3577
Relevant Lines: 6260

💛 - Coveralls

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

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

Thanks for the PR! 🙏
I've been meaning to make this change for a while but haven't gotten around to it.

@@ -285,7 +285,7 @@ func (ch *ClickHouse) Lock() error {
}
func (ch *ClickHouse) Unlock() error {
if !ch.isLocked.CAS(true, false) {
return database.ErrLocked
return database.ErrNotLocked
Copy link
Member

Choose a reason for hiding this comment

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

Good catch!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, this is my bug))

@@ -220,7 +221,7 @@ func (p *Postgres) Close() error {

// https://www.postgresql.org/docs/9.6/static/explicit-locking.html#ADVISORY-LOCKS
func (p *Postgres) Lock() error {
if p.isLocked {
if p.isLocked.Load() {
Copy link
Member

Choose a reason for hiding this comment

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

We should replace this with CAS, release the local if the postgres lock fails, and remove the CAS call below for a proper local lock implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of thanks for review. fixed it

@@ -214,7 +215,7 @@ func (p *Postgres) Close() error {

// https://www.postgresql.org/docs/9.6/static/explicit-locking.html#ADVISORY-LOCKS
func (p *Postgres) Lock() error {
if p.isLocked {
if p.isLocked.Load() {
Copy link
Member

Choose a reason for hiding this comment

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

Same here about fixing the local lock optimization implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed it

@@ -154,7 +155,7 @@ func (ss *SQLServer) Close() error {

// Lock creates an advisory local on the database to prevent multiple migrations from running at the same time.
func (ss *SQLServer) Lock() error {
if ss.isLocked {
if ss.isLocked.Load() {
Copy link
Member

Choose a reason for hiding this comment

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

Same here about fixing the local lock optimization implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thnx,fixed it

@@ -181,7 +184,7 @@ func (ss *SQLServer) Lock() error {

// Unlock froms the migration lock from the database
func (ss *SQLServer) Unlock() error {
if !ss.isLocked {
if !ss.isLocked.Load() {
Copy link
Member

Choose a reason for hiding this comment

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

Same here about fixing the local lock optimization implementation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thnx,fixed it

}
return nil
if !success {
m.isLocked.Store(false)
Copy link
Member

Choose a reason for hiding this comment

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

Add a comment here about how removing the local lock in this situation is desired since the local lock is an optimization and it's not trying to reflect the state of the db lock.

Actually, let's add our own CAS wrapper to automatically restore the lock state on error (in database/util.go) so we don't need to remember to do it:

func casRestoreOnErr(lock *atomic.Bool, o, n bool, f func() error) error {
    if !lock.CAS(o, n) {
        return ErrLocked
    }
    if err := f(); err != nil {
        // Automatically unlock
        lock.Store(o)
        return err
    }
    return nil
}

Also, can you add tests for this wrapper?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you. Of course I will do it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, review pls

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

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

Thanks again for addressing my feedback! Just a few minor fixes left!

database/util_test.go Show resolved Hide resolved
database/util_test.go Outdated Show resolved Hide resolved
database/util_test.go Outdated Show resolved Hide resolved
database/util_test.go Show resolved Hide resolved
Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

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

Thanks for addressing my feedback!
Sorry for the delay, I must have missed a notification that there were more commits to review...

return database.CasRestoreOnErr(&m.isLocked, false, true, database.ErrLocked, func() error {
if !m.config.Locking.Enabled {
Copy link
Member

Choose a reason for hiding this comment

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

I think we can always try to acquire the local lock before acquiring the db lock even if locking is disabled. IIRC, the locking enabled config was added for backwards compatibility and to avoid an extra network hop for existing clients

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, thanks. Done

Copy link
Member

@dhui dhui left a comment

Choose a reason for hiding this comment

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

Thanks again for the PR and addressing all of the feedback!

@dhui dhui merged commit 3dfb0ff into golang-migrate:master Jun 23, 2021
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