lockDatabase prevents multiple devlake instances from sharing the same lockDatabase check the models.LockingHistory for the detail
()
| 34 | // lockDatabase prevents multiple devlake instances from sharing the same lockDatabase |
| 35 | // check the models.LockingHistory for the detail |
| 36 | func lockDatabase() { |
| 37 | db := basicRes.GetDal() |
| 38 | // first, register the instance |
| 39 | errors.Must(db.AutoMigrate(&models.LockingHistory{})) |
| 40 | hostName := errors.Must1(os.Hostname()) |
| 41 | lockingHistory := &models.LockingHistory{ |
| 42 | HostName: hostName, |
| 43 | Version: version.Version, |
| 44 | } |
| 45 | errors.Must(db.Create(lockingHistory)) |
| 46 | // 2. obtain the lock: using a never released transaction |
| 47 | // This prevents multiple devlake instances from sharing the same database by locking the migration history table |
| 48 | // However, it would not work if any older devlake instances were already using the database. |
| 49 | lockingTx = db.Begin() |
| 50 | c := make(chan bool, 1) |
| 51 | go func() { |
| 52 | errors.Must(lockingTx.DropTables(models.LockingStub{}.TableName())) |
| 53 | errors.Must(lockingTx.AutoMigrate(&models.LockingStub{})) |
| 54 | errors.Must(lockingTx.LockTables(dal.LockTables{{Table: "_devlake_locking_stub", Exclusive: true}})) |
| 55 | lockingHistory.Succeeded = true |
| 56 | errors.Must(db.Update(lockingHistory)) |
| 57 | c <- true |
| 58 | }() |
| 59 | |
| 60 | // 3. update the record |
| 61 | select { |
| 62 | case <-c: |
| 63 | case <-time.After(10 * time.Second): |
| 64 | panic(fmt.Errorf("locking _devlake_locking_stub timeout, the database might be locked by another devlake instance")) |
| 65 | } |
| 66 | } |
no test coverage detected