func TestLockContestDuo(t *testing.T) { assert := assert.New(t) // Instantiation c := cluster.NewRedisCluster(rConfig) assert.NotEmpty(c) defer c.Close() // Create 2 locks on the same key key := RandomKey() locks := []*lock.Lock{ lock.CreateLock(c, key), lock.CreateLock(c, key), } // Unlease dogs of war result := make(chan int, 2) acquired := 0 for _, l := range locks { func(l *lock.Lock) { go func() { success, err := l.Get(false) assert.Empty(err) if success { acquired++ } result <- 1 }() }(l) } // Wait for them to finish <-result <-result assert.Equal(acquired, 1) }
func TestLockAutoExpire(t *testing.T) { assert := assert.New(t) // Instantiation c := cluster.NewRedisCluster(rConfig) assert.NotEmpty(c) defer c.Close() // Create lock key := RandomKey() l1 := lock.CreateLock(c, key) duration := 3 * time.Second l1.Duration = duration l2 := lock.CreateLock(c, key) // Acquire lock success, err := l1.Get(false) assert.Empty(err) assert.True(success) // Acquire lock on the same key, should fail success, err = l2.Get(false) assert.Empty(err) assert.False(success) // Sleep past the expiration time time.Sleep(duration) // Acquire lock, should succeed this time success, err = l2.Get(false) assert.Empty(err) assert.True(success) }
func TestLockRelease(t *testing.T) { assert := assert.New(t) // Instantiation c := cluster.NewRedisCluster(rConfig) assert.NotEmpty(c) defer c.Close() // Create lock key := RandomKey() l1 := lock.CreateLock(c, key) l1.Duration = 16 * time.Second l2 := lock.CreateLock(c, key) // Acquire lock success, err := l1.Get(false) assert.Empty(err) assert.True(success) assert.True(l1.IsActive()) // Acquire lock on the same key, should fail success, err = l2.Get(false) assert.Empty(err) assert.False(success) assert.False(l2.IsActive()) // Release original lock success, err = l1.Release() assert.Empty(err) assert.True(success) assert.False(l1.IsActive()) // Acquire lock, should succeed this time success, err = l2.Get(false) assert.Empty(err) assert.True(success) assert.True(l2.IsActive()) }
func TestLockContestTrio(t *testing.T) { assert := assert.New(t) // Instantiation clusters := []*cluster.RedisCluster{ cluster.NewRedisCluster(rConfig), cluster.NewRedisCluster(rConfig), cluster.NewRedisCluster(rConfig), } defer func() { for _, c := range clusters { c.Close() } }() // Create 3 locks on the same key key := RandomKey() locks := []*lock.Lock{} for _, c := range clusters { l := lock.CreateLock(c, key) locks = append(locks, l) } // Unlease dogs of war result := make(chan int, 3) acquired := 0 for _, l := range locks { func(l *lock.Lock) { go func() { success, err := l.Get(false) assert.Empty(err) if success { acquired++ } result <- 1 }() }(l) } // Wait for them to finish for i := 0; i < 3; i++ { <-result } assert.True(acquired <= 1) }
// Consumer creates a Magi instance that acts as a consumer func Consumer(dqConfig *cluster.DisqueClusterConfig, rConfig *cluster.RedisClusterConfig) (*Magi, error) { dqCluster, err := cluster.NewDisqueCluster(dqConfig) if err != nil { return nil, err } rCluster := cluster.NewRedisCluster(rConfig) consumer := &Magi{ APIVersion: MagiAPIVersion, dqCluster: dqCluster, rCluster: rCluster, isProcessing: false, processors: make(map[string]*Processor), processControl: make(chan string, 1), } return consumer, nil }
func TestLockAcquisition(t *testing.T) { assert := assert.New(t) // Instantiation c := cluster.NewRedisCluster(rConfig) assert.NotEmpty(c) defer c.Close() // Create lock key := RandomKey() l := lock.CreateLock(c, key) l.Duration = 3 * time.Second // Acquire lock success, err := l.Get(false) assert.Empty(err) assert.True(success) assert.True(l.IsActive()) }
func TestLockMutualExclusion(t *testing.T) { assert := assert.New(t) // Instantiation c := cluster.NewRedisCluster(rConfig) assert.NotEmpty(c) defer c.Close() // Create locks key := RandomKey() l1 := lock.CreateLock(c, key) l2 := lock.CreateLock(c, key) l1.Duration = 3 * time.Second l2.Duration = 3 * time.Second // Acquire lock on l1 success, err := l1.Get(false) assert.Empty(err) assert.True(success) assert.True(l1.IsActive()) // Acquire lock on l2, should fail success, err = l2.Get(false) assert.Empty(err) assert.False(success) assert.False(l2.IsActive()) }