func (t *GoInterval) Run(ctx context.Context) error {
	if ctx == nil {
		ctx = context.Background()
	}
	if t.Interval == 0 {
		return errors.New("`Time Interval is missing!`")
	}
	if t.Arg == nil {
		return errors.New("`What this timer should to run?`")
	}
	if t.Name != "" {
		if t.LockVendor == 0 {
			t.LockVendor = RedisLock
		}
	}
	switch t.LockVendor {
	case RedisLock:
		r := &RedisLocker{
			redisConnector: t.RedisConnector,
			Name:           t.Name,
			RedisHost:      t.RedisHost,
			RedisPassword:  t.RedisPassword,
			RedisDB:        t.RedisDB,
		}
		err := r.SetClient()
		if err != nil {
			return err
		}
		locker = r
	case AwsDynamoDbLock:
		d := &DynamoDbLocker{
			AwsDynamoDbRegion:          t.AwsDynamoDbRegion,
			AwsDynamoDbEndpoint:        t.AwsDynamoDbEndpoint,
			AwsDynamoDbAccessKeyID:     t.AwsDynamoDbAccessKeyID,
			AwsDynamoDbSecretAccessKey: t.AwsDynamoDbSecretAccessKey,
			AwsDynamoDbSessionToken:    t.AwsDynamoDbSessionToken,
		}
		err := d.SetClient()
		if err != nil {
			return err
		}
		locker = d
	}
	t.updateTimer()
	for {
		select {
		case <-ctx.Done():
			log.Printf("Job %s terminated!", t.Name)
			return nil
		default:
			<-t.timer.C
			lock, err := t.isNotLockThenLock(ctx)
			if err != nil {
				log.Fatalf("err: %v", err)
				return nil
			}
			if lock {
				t.Arg()
				t.UnLock(ctx)
			}
			t.updateTimer()
		}
	}
}
Run to start the interval timer
package gointerlock
import (
	"context"
	"errors"
	"log"
	"time"
	"github.com/go-redis/redis/v8"
)
var locker Lock
type LockVendor int32
const (
	SingleApp       LockVendor = 0  
	RedisLock       LockVendor = 1
	AwsDynamoDbLock LockVendor = 2
)
type GoInterval struct {
	Name string
	Arg func()
	Interval time.Duration
	LockVendor LockVendor
	RedisConnector *redis.Client
	RedisHost string
	RedisPassword string
	RedisDB string
	AwsDynamoDbRegion string
	AwsDynamoDbEndpoint string
	AwsDynamoDbAccessKeyID string
	AwsDynamoDbSecretAccessKey string
	AwsDynamoDbSessionToken string
	timer *time.Timer
}