Last active
February 27, 2021 17:52
-
-
Save podanypepa/192889594733a43dad9d5fbbea740fb2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "fmt" | |
| "log" | |
| "time" | |
| "go.mongodb.org/mongo-driver/mongo" | |
| "go.mongodb.org/mongo-driver/mongo/options" | |
| "gopkg.in/mgo.v2/bson" | |
| ) | |
| type LockObject struct { | |
| InTransaction bool `json:"inTransaction" bson:"inTransaction"` | |
| Name string `json:"name" bson:"name"` | |
| } | |
| var ( | |
| url = "mongodb+srv://mongodb:CONNECTION_STRING..." | |
| dbiName = "locker" | |
| colname = "locker" | |
| MongoClient *mongo.Client | |
| coll *mongo.Collection | |
| ) | |
| func main() { | |
| // you can specify lock name for more then one lock in collection | |
| lockName := "globalLock" | |
| fmt.Println("start") | |
| // blocked until getting lock | |
| if Lock(lockName) { | |
| // after getting lock | |
| fmt.Println("heja! locked by me!") | |
| } | |
| fmt.Println("and continue...") | |
| // uncomment for unlock | |
| // if you run with commented Unlock() will be blocked next app run | |
| // Unlock(lockName) | |
| _ = MongoClient.Disconnect(context.TODO()) | |
| } | |
| func Lock(lockName string) (locked bool) { | |
| var ( | |
| filter = bson.M{ | |
| "inTransaction": bson.M{ | |
| "$exists": true, | |
| }, | |
| "name": lockName, | |
| } | |
| locker = bson.M{ | |
| "$set": LockObject{ | |
| InTransaction: true, | |
| Name: lockName, | |
| }, | |
| } | |
| upsert = true | |
| opt = options.UpdateOptions{ | |
| Upsert: &upsert, | |
| } | |
| ) | |
| if MongoClient == nil { | |
| var err error | |
| if MongoClient, err = mongo.Connect(context.TODO(),options.Client().ApplyURI(url)); err != nil { | |
| log.Fatal(err) | |
| } | |
| coll = MongoClient.Database(dbiName).Collection(colname) | |
| fmt.Println("mongo connected") | |
| } | |
| for !locked { | |
| res, err := coll.UpdateOne(context.TODO(), filter, locker, &opt) | |
| if err != nil { | |
| return false | |
| } | |
| locked = res.UpsertedCount == 1 | |
| if !locked { | |
| fmt.Println("locked by someone else") | |
| time.Sleep(1 * time.Second) | |
| } | |
| } | |
| return locked | |
| } | |
| func Unlock(lockName string) error { | |
| var ( | |
| filter = bson.M{ | |
| "inTransaction": bson.M{ | |
| "$exists": true, | |
| }, | |
| "name": lockName, | |
| } | |
| ) | |
| res, err := coll.DeleteOne(context.TODO(), filter) | |
| if err != nil { | |
| return err | |
| } | |
| if res.DeletedCount != 1 { | |
| return fmt.Errorf("unlcck error") | |
| } | |
| return nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment