gointerlock

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2021 License: MIT Imports: 12 Imported by: 2

README

goInterLock

Go Interval Lock

known as: ⏰ Interval (Cron / Job / Task / Scheduler) Go Centralized Lock ⏱️

Go Interval job timer, with centralized Lock for Distributed Systems

goInterLock is go job/task scheduler with centralized locking mechanism. In distributed system locking is preventing task been executed in every instant that has the scheduler,

For example: if your application has a task of calling some external APIs or doing some DB querying every 10 minutes, the lock prevents the process been run in every instance of that application, and you ended up running that task multiple time every 10 minutes. (let say in kubernetes)

Quick Start

go get github.com/ehsaniara/gointerlock

Supported Lock

Local Scheduler (Single App)

(Interval every 2 seconds)

var job = gointerlock.GoInterval{
    Interval: 2 * time.Second,
    Arg:      myJob,
}
err := job.Run(ctx)
if err != nil {
        log.Fatalf("Error: %s", err)
}
Examples

Basic Local Task: Simple Task Interval (Single App).

Application Cache: An example of periodically cached value update on http server.


Distributed Mode (Scaled Up)

Existing Redis Connection

you should already configure your Redis connection and pass it into the GoInterLock. Also make sure you are giving the unique name per job

Step 1: configure redis connection redisConnection.Rdb from the existing application and pass it into the Job. for example:

var redisConnector = redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "myRedisPassword", 
    DB:       0,               
})

Step 2: Pass the redis connection into the GoInterval

var job = gointerlock.GoInterval{
    Interval: 2 * time.Second,
    Arg:      myJob,
    Name:     "MyTestJob",
    RedisConnector: redisConnector,
}
err := jobTicker.Run(ctx)
if err != nil {
    log.Fatalf("Error: %s", err)
}

in both examples myJob is your function, for example:

func myJob() {
	fmt.Println(time.Now(), " - called")
}

Note: currently GoInterLock does not support any argument for the job function

Built in Redis Connector

another way is to use an existing redis connection:

var job = gointerlock.GoInterval{
    Name:          "MyTestJob",
    Interval:      2 * time.Second,
    Arg:           myJob,
    RedisHost:     "localhost:6379",
    RedisPassword: "myRedisPassword", //if no pass leave it as ""
}
err := job.Run(context.Background())
if err != nil {
    log.Fatalf("Error: %s", err)
}
GoInterLock is using go-redis for Redis Connection.
Examples

Basic Distributed Task: Simple Task Interval with Redis Lock.


AWS DynamoDb

Basic Config (Local Environment)

This ia sample of local DynamoDb (Docker) for your local test.

var job = gointerlock.GoInterval{
    Name:                       "MyTestJob",
    Interval:                   2 * time.Second,
    Arg:                        myJob,
    LockVendor:                 gointerlock.AwsDynamoDbLock,
    AwsDynamoDbRegion:          "us-east-1",
    AwsDynamoDbEndpoint:        "http://127.0.0.1:8000",
    AwsDynamoDbSecretAccessKey: "dummy",
    AwsDynamoDbAccessKeyID:     "dummy",
}
err := job.Run(cnx)
if err != nil {
    log.Fatalf("Error: %s", err)
}

task:

func myJob() {
	fmt.Println(time.Now(), " - called")
}

Note: you can get the docker-compose file from AWS DynamoDB Docker compose or you can get it from: docker-compose.yml.

Using AWS Profile

goInterLock will get credentials from the AWS profile

var job = gointerlock.GoInterval{
    Name:                       "MyTestJob",
    Interval:                   2 * time.Second,
    Arg:                        myJob,
    LockVendor:                 gointerlock.AwsDynamoDbLock,
}
err := job.Run(cnx)
if err != nil {
    log.Fatalf("Error: %s", err)
}
Examples

Basic Distributed Task: Simple Task Interval with DynamoDb Lock.

Documentation

Index

Constants

View Source
const Prefix = "GoInterLock"

Variables

This section is empty.

Functions

func DynamoDbUnlockMarshal

func DynamoDbUnlockMarshal(key string) map[string]*dynamodb.AttributeValue

Types

type DynamoDbLocker added in v1.1.1

type DynamoDbLocker struct {

	//leave empty to get from ~/.aws/credentials, (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbRegion string

	//leave empty to get from ~/.aws/credentials
	AwsDynamoDbEndpoint string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbAccessKeyID string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbSecretAccessKey string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbSessionToken string
	// contains filtered or unexported fields
}

func (*DynamoDbLocker) Lock added in v1.1.1

func (d *DynamoDbLocker) Lock(ctx context.Context, key string, lockTtl time.Duration) (success bool, err error)

func (*DynamoDbLocker) SetClient added in v1.1.1

func (d *DynamoDbLocker) SetClient() error

func (*DynamoDbLocker) UnLock added in v1.1.1

func (d *DynamoDbLocker) UnLock(ctx context.Context, key string) error

type GoInterval

type GoInterval struct {

	//Name: is a unique job/task name, this is needed for distribution lock, this value enables the distribution mode. for local uses you don't need to set this value
	Name string

	// Arg: the func that need to be call in every period
	Arg func()

	// Interval: Timer Interval
	Interval time.Duration

	LockVendor LockVendor

	// RedisConnector : in case your app has redis connection configured already
	RedisConnector *redis.Client

	// RedisHost Redis Host the default value "localhost:6379"
	RedisHost string

	// RedisPassword: Redis Password (AUTH), It can be blank if Redis has no authentication req
	RedisPassword string

	// 0 , It's from 0 to 15 (Not for redis cluster)
	RedisDB string

	//leave empty to get from ~/.aws/credentials, (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbRegion string

	//leave empty to get from ~/.aws/credentials
	AwsDynamoDbEndpoint string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbAccessKeyID string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbSecretAccessKey string

	//leave empty to get from ~/.aws/credentials, StaticCredentials (if AwsDynamoDbEndpoint not provided)
	AwsDynamoDbSessionToken string
	// contains filtered or unexported fields
}

func (*GoInterval) Run

func (t *GoInterval) Run(ctx context.Context) error

Run to start the interval timer

func (*GoInterval) UnLock

func (t *GoInterval) UnLock(ctx context.Context)

type Lock added in v1.1.1

type Lock interface {
	Lock(ctx context.Context, key string, interval time.Duration) (success bool, err error)
	UnLock(ctx context.Context, key string) (err error)
	SetClient() error
}

type LockVendor

type LockVendor int32
const (
	SingleApp       LockVendor = 0 // no distributed lock
	RedisLock       LockVendor = 1
	AwsDynamoDbLock LockVendor = 2
)

type RedisLocker added in v1.1.1

type RedisLocker struct {

	// Name: is a unique job/task name, this is needed for distribution lock, this value enables the distribution mode. for local uses you don't need to set this value
	Name string

	// RedisHost Redis Host the default value "localhost:6379"
	RedisHost string

	// RedisPassword: Redis Password (AUTH), It can be blank if Redis has no authentication req
	RedisPassword string

	// 0 , It's from 0 to 15 (Not for redis cluster)
	RedisDB string
	// contains filtered or unexported fields
}

func (*RedisLocker) Lock added in v1.1.1

func (r *RedisLocker) Lock(ctx context.Context, key string, lockTtl time.Duration) (success bool, err error)

func (*RedisLocker) SetClient added in v1.1.1

func (r *RedisLocker) SetClient() error

func (*RedisLocker) UnLock added in v1.1.1

func (r *RedisLocker) UnLock(ctx context.Context, key string) error

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL