diff --git a/README.md b/README.md index df885d9..b848861 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,7 @@ var job = gointerlock.GoInterval{ Interval: 2 * time.Second, Arg: myJob, RedisHost: "localhost:6379", - RedisPassword: "myRedisPassword", + RedisPassword: "myRedisPassword", //if no pass leave it as "" } err := job.Run(context.Background()) if err != nil { diff --git a/cmd/main.go b/cmd/main.go deleted file mode 100644 index ae9194b..0000000 --- a/cmd/main.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "context" - "fmt" - "github.com/ehsaniara/gointerlock" - "log" - "time" -) - -func myJob() { - fmt.Println(time.Now(), " - called") -} - -func main() { - //test cron - var job = gointerlock.GoInterval{ - Name: "MyTestJob", - Interval: 2 * time.Second, - Arg: myJob, - RedisHost: "localhost:6379", - RedisPassword: "myRedisPassword", - } - err := job.Run(context.Background()) - if err != nil { - log.Fatalf("Error: %s", err) - } - -} diff --git a/example/main.go b/example/main.go new file mode 100644 index 0000000..93f85f2 --- /dev/null +++ b/example/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "context" + "fmt" + "github.com/ehsaniara/gointerlock" + "log" + "time" +) + +func myJob() { + fmt.Println(time.Now(), " - called") +} + +func main() { + cnx := context.Background() + + //test cron + go func() { + var job = gointerlock.GoInterval{ + Name: "MyTestJob", + Interval: 2 * time.Second, + Arg: myJob, + RedisHost: "localhost:6379", + RedisPassword: "MyRedisPassword", + } + err := job.Run(cnx) + if err != nil { + log.Fatalf("Error: %s", err) + } + }() + + time.Sleep(10 * time.Second) +} diff --git a/goInterval.go b/goInterval.go index 8934320..2298636 100644 --- a/goInterval.go +++ b/goInterval.go @@ -75,7 +75,7 @@ func (t *GoInterval) Run(ctx context.Context) error { <-t.timer.C //lock - locked, errLock := locker.Lock(ctx, t.Name) + locked, errLock := locker.Lock(ctx, t.Name, t.Interval) if errLock != nil { return errLock diff --git a/goIntervalLock.go b/goIntervalLock.go index 7571c4f..7980bab 100644 --- a/goIntervalLock.go +++ b/goIntervalLock.go @@ -11,7 +11,7 @@ type Locker struct { redisConnector *redis.Client } -func (s *Locker) Lock(ctx context.Context, key string) (success bool, err error) { +func (s *Locker) Lock(ctx context.Context, key string, lockTtl time.Duration) (success bool, err error) { if s.redisConnector != nil { @@ -19,12 +19,13 @@ func (s *Locker) Lock(ctx context.Context, key string) (success bool, err error) return false, errors.New("`Distributed Jobs should have a unique name!`") } - res, err := s.redisConnector.SetNX(ctx, key, time.Now().String(), time.Second*15).Result() + res, err := s.redisConnector.SetNX(ctx, key, time.Now().String(), lockTtl).Result() if err != nil { return false, err } return res, nil } + //true when lock is disabled return true, nil } diff --git a/goInterval_test.go b/goInterval_test.go index 84301c8..51c449c 100644 --- a/goInterval_test.go +++ b/goInterval_test.go @@ -2,20 +2,28 @@ package gointerlock_test import ( "context" + "flag" "fmt" "github.com/ehsaniara/gointerlock" "github.com/go-redis/redis/v8" "log" + "testing" "time" ) -const RedisHost string = "localhost:6379" -const RedisPass string = "password" - var ( ctx = context.Background() rdb *redis.Client ) +var ( + RedisHost string + RedisPass string +) + +func init() { + flag.StringVar(&RedisPass, "RedisPass", "", "Redis Password") + flag.StringVar(&RedisHost, "RedisHost", "localhost:6379", "Redis Host") +} func init() { rdb = redis.NewClient(&redis.Options{ @@ -29,6 +37,7 @@ func init() { } func ExampleNewClient() { + rdb := redis.NewClient(&redis.Options{ Addr: RedisHost, // use default Addr Password: RedisPass, // no password set @@ -40,19 +49,55 @@ func ExampleNewClient() { // Output: PONG } -func ExampleGoInterval_Run() { +func TestGoInterval_Run(t *testing.T) { + var counter = 0 + var job1 = gointerlock.GoInterval{ + Interval: 100 * time.Millisecond, + Arg: func() { + counter++ + }, + } + go func() { + _ = job1.Run(context.Background()) + }() + time.Sleep(2 * time.Second) + + log.Printf("counter %d", counter) + if counter != 19 { + t.Error("counter should be 19") + } + +} + +func TestGoInterval_LockCheck(t *testing.T) { + var counter = 0 + cnx := context.Background() + var job2 = gointerlock.GoInterval{ + Name: "job2", + RedisHost: RedisHost, + RedisPassword: RedisPass, + Interval: 1 * time.Second, + Arg: func() { + counter++ + }, + } + time.Sleep(1 * time.Second) + //instance 1 replication go func() { - var job = gointerlock.GoInterval{ - Interval: 1 * time.Second, - Arg: func() { - fmt.Print("called-") - }, - } - err := job.Run(context.Background()) - if err != nil { - log.Fatalf("Error: %s", err) - } + _ = job2.Run(cnx) }() - time.Sleep(4 * time.Second) - // Output: called-called-called- + //instance 2 replication + go func() { + _ = job2.Run(cnx) + }() + //instance 3 replication + go func() { + _ = job2.Run(cnx) + }() + time.Sleep(2 * time.Second) + + log.Printf("counter %d", counter) + if counter != 1 { + t.Error("counter should be 1") + } }