Skip to content

flowerinthenight/spindle-cb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

main Go Reference

Important

This library is still using the main-2.0 branch of the ClockBound daemon.

spindle-cb

A distributed locking library (port of spindle) built on aws/clock-bound, and PostgreSQL (storage).

Using this library requires the ClockBound daemon (making it AWS-only), and CGO, due to its dependency on the clockbound-ffi-go library.

One use case for this library is leader election. If you want one host/node/pod to be the leader within a cluster/group, you can achieve that with this library. When the leader fails, it will fail over to another host/node/pod within a specific timeout. That said, you might want to check out hedge-cb, which is a memberlist tracking library built on top of this library.

Usage

At the moment, the table needs to be created beforehand (spindle and locktable are just examples):

-- create the database:
CREATE DATABASE spindle;

-- create the table:
CREATE TABLE locktable (
    name TEXT PRIMARY KEY,
    heartbeat TIMESTAMP,
    token TIMESTAMP,
    writer TEXT
);

After creating the lock object, you will call the Run(...) function which will attempt to acquire a named lock at a regular interval (lease duration) until cancelled. A HasLock() function is provided which returns true (along with the lock token) if the lock is successfully acquired. Something like:

import (
    ...
    "github.com/flowerinthenight/spindle-cb"
    _ "github.com/jackc/pgx/v5/stdlib"
)

func main() {
    // error checks redacted
    db, _ := sql.Open("pgx", *dbstr)
    defer db.Close()

    done := make(chan error, 1) // notify me when done (optional)
    quit, cancel := context.WithCancel(context.Background()) // for cancel

    // Create the lock object using a 5s lease duration using 'locktable' above.
    lock := spindle.New(db, "locktable", "mylock", spindle.WithDuration(5000))

    lock.Run(quit, done) // start the main loop, async

    time.Sleep(time.Second * 20)
    locked, token := lock.HasLock()
    log.Println("HasLock:", locked, token)
    time.Sleep(time.Second * 20)

    cancel()
    <-done
}

Running the sample

A sample cloud-init startup script is provided for spinning up an Auto Scaling Group with the ClockBound daemon already setup and running.

# Create a launch template. ImageId here is Amazon Linux, default VPC.
# You can remove the "KeyName" line if SSH access is not needed.
# (Added newlines for readability. Might not run when copied as is.)
$ aws ec2 create-launch-template \
  --launch-template-name spindle-lt \
  --version-description version1 \
  --launch-template-data '
  {
    "UserData":"'"$(cat startup-aws-asg.sh | base64 -w 0)"'",
    "ImageId":"ami-0fe289b44779ce58a",
    "InstanceType":"t3.medium",
    "KeyName":"keyName"
  }'

# Create the ASG; update {target-zone} with actual value:
$ aws autoscaling create-auto-scaling-group \
  --auto-scaling-group-name spindle-asg \
  --launch-template LaunchTemplateName=spindle-lt,Version='1' \
  --min-size 1 \
  --max-size 1 \
  --tags Key=Name,Value=spindle-asg \
  --availability-zones {target-zone}

# You can now SSH to the instance. Note that it might take some time before
# ClockBound is running due to the need to build it in Rust. You can wait
# for the `clockbound` process, or tail the startup script output, like so:
$ tail -f /var/log/cloud-init-output.log

# Run the sample code:
# Download the latest release sample from GitHub.
$ tar xvzf spindle-{version}-x86_64-linux.tar.gz

# Run multiple instances of `example` to see locking taking place:
$ ./example -db postgres://postgres:pass@loc.rds.amazonaws.com:5432/spindle

License

This library is licensed under the Apache 2.0 License.

About

A distributed locking library built on aws/clock-bound and PostgreSQL.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published