Maybe I'm just doing something wrong. I've created a small program based on the example provided that acquire a lock, but it does not close the client because I want to control a program that runs in two seconds every 5 minutes or so but needs to lock the execution in other nodes during more than 5 minutes.
My plan was to create a lock with a lease of 6 minutes and check for the lock before start the execution of the rest of the code.
But in my tests, unreleased locks are left there and never expire:
first execution:
[main] 14:35:38 Starting client
[main] 14:35:38 Acquiring lock
[dyna] 14:35:38 Call GetItem to see if the lock for lock = test exists in the table
[dyna] 14:35:38 starting heartbeats
[dyna] 14:35:39 Lock <nil>
[dyna] 14:35:39 Captured new Lock
[dyna] 14:35:39 Acquiring a new lock or an existing yet released lock on lock = test
[main] 14:35:39 lock content:
[main] 14:35:39 lock owner: test owner
[main] 14:35:39 expired? false
[main] 14:35:39 done
next execution, the lock is in the DynamoDB table but it is not released and the lease is for 1m
./main
[main] 14:35:46 Starting client
[main] 14:35:46 Acquiring lock
[dyna] 14:35:46 Call GetItem to see if the lock for lock = test exists in the table
[dyna] 14:35:46 starting heartbeats
[dyna] 14:35:46 Lock &{{0 0} 0xc000196d00 test [] test owner false false <nil> {13786376802911714670 247280565 0xcea6a0} ZGNHp7OU5dRRDsHGz05NbxQ6mNq2Rab4 60000000000 map[]}
[dyna] 14:35:46 Existing Lock Owner: test owner
[dyna] 14:35:46 New Lock Owner: test owner
[dyna] 14:35:46 Existing Lock isExpired: false
[dyna] 14:35:46 Existing Lock lookupTime: 2019-09-01 14:35:46.758971758 +0200 CEST m=+0.247280565
[main] 14:35:46 Error acquiring lock: Didn't acquire lock because it is locked and request is configured not to retry.
This was expected but, next time I execute it the lock remains in the table, and unreselased. This is normal because there's no code runing to release it. The lease was for 1m but the execution happens 10 minutes after the creation of the lock:
./main
[main] 14:46:51 Starting client
[main] 14:46:51 Acquiring lock
[dyna] 14:46:51 starting heartbeats
[dyna] 14:46:51 Call GetItem to see if the lock for lock = test exists in the table
[dyna] 14:46:52 Lock &{{0 0} 0xc000198820 test [] test owner false false <nil> {13786377517353580211 328045090 0xcea6a0} ZGNHp7OU5dRRDsHGz05NbxQ6mNq2Rab4 60000000000 map[]}
[dyna] 14:46:52 Existing Lock Owner: test owner
[dyna] 14:46:52 New Lock Owner: test owner
[dyna] 14:46:52 Existing Lock isExpired: false
[dyna] 14:46:52 Existing Lock lookupTime: 2019-09-01 14:46:52.088782515 +0200 CEST m=+0.328045090
[main] 14:46:52 Error acquiring lock: Didn't acquire lock because it is locked and request is configured not to retry.
Looks to me that the library would consider locked any existing lock that has not been properly released, regardless of the lease time.
But perhaps I'm missing something.
My code:
package main
import (
"log"
"os"
"time"
"cirello.io/dynamolock"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
)
func main() {
log.SetPrefix("[main] ")
log.SetFlags(log.Ltime)
svc := dynamodb.New(session.Must(session.NewSession(&aws.Config{
Region: aws.String("eu-west-1"),
})))
log.Println("Starting client")
c, err := dynamolock.New(svc,
"Locks",
dynamolock.WithLeaseDuration(1*time.Minute),
dynamolock.WithLogger(log.New(os.Stdout, "[dyna] ", log.Ltime)),
dynamolock.WithPartitionKeyName("lock"),
dynamolock.WithOwnerName("test owner"),
)
if err != nil {
log.Fatal(err)
}
log.Println("Acquiring lock")
lockedItem, err := c.AcquireLock("test",
dynamolock.ReplaceData(),
dynamolock.FailIfLocked(),
)
if err != nil {
log.Fatal("Error acquiring lock: ", err)
}
log.Println("lock content:", string(lockedItem.Data()))
log.Println("lock owner:", lockedItem.OwnerName())
log.Println("expired? ", lockedItem.IsExpired())
log.Println("done")
}