Skip to content

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

Merged
dhui merged 14 commits into
golang-migrate:masterfrom
prinkov:master
Jun 23, 2021
Merged

dhui merged 14 commits into
golang-migrate:masterfrom
prinkov:master

Conversation

@prinkov

@prinkov prinkov commented Jun 12, 2021

Copy link
Copy Markdown
Contributor

No description provided.

@coveralls

coveralls commented Jun 12, 2021 •

Copy link
Copy Markdown

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

@dhui dhui left a comment

Copy link
Copy Markdown
Member

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.

func (ch *ClickHouse) Unlock() error {
if !ch.isLocked.CAS(true, false) {
return database.ErrLocked
return database.ErrNotLocked

Copy link
Copy Markdown
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
Copy Markdown
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))

Comment thread database/pgx/pgx.go Outdated
// 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
Copy Markdown
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
Copy Markdown
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

Comment thread database/postgres/postgres.go Outdated
// 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
Copy Markdown
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
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

fixed it

Comment thread database/sqlserver/sqlserver.go Outdated
// 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
Copy Markdown
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
Copy Markdown
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

Comment thread database/sqlserver/sqlserver.go Outdated
// Unlock froms the migration lock from the database
func (ss *SQLServer) Unlock() error {
if !ss.isLocked {
if !ss.isLocked.Load() {

Copy link
Copy Markdown
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
Copy Markdown
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

Comment thread database/mysql/mysql.go Outdated
}
return nil
if !success {
m.isLocked.Store(false)

Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

@dhui dhui left a comment

Copy link
Copy Markdown
Member

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!

Comment thread database/util_test.go
Comment thread database/util_test.go Outdated
Comment thread database/util_test.go Outdated
Comment thread database/util_test.go

@dhui dhui left a comment

Copy link
Copy Markdown
Member

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...

Comment thread database/mongodb/mongodb.go Outdated
}

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

Copy link
Copy Markdown
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
Copy Markdown
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

@dhui dhui left a comment

Copy link
Copy Markdown
Member

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