Esempio n. 1
0
func ExampleMutex() {
	m, err := redsync.NewMutexWithGenericPool("FlyingSquirrels", pools)
	if err != nil {
		panic(err)
	}

	err = m.Lock()
	if err != nil {
		panic(err)
	}
	defer m.Unlock()

	// Output:
}
Esempio n. 2
0
func TestMutex(t *testing.T) {
	done := make(chan bool)
	chErr := make(chan error)

	for i := 0; i < 4; i++ {
		go func() {
			m, err := redsync.NewMutexWithGenericPool("RedsyncMutex", pools)
			if err != nil {
				chErr <- err
				return
			}

			f := 0
			for j := 0; j < 32; j++ {
				err := m.Lock()
				if err == redsync.ErrFailed {
					f++
					if f > 2 {
						chErr <- err
						return
					}
					continue
				}
				if err != nil {
					chErr <- err
					return
				}

				time.Sleep(1 * time.Millisecond)

				m.Unlock()

				time.Sleep(time.Duration(rand.Int31n(128)) * time.Millisecond)
			}
			done <- true
		}()
	}
	for i := 0; i < 4; i++ {
		select {
		case <-done:
		case err := <-chErr:
			t.Fatal(err)
		}
	}
}
Esempio n. 3
0
// redMutexForTask vendors a configured redlock w/ randomness builtin for the expiration
// of the lock
func (r *RateLimiter) redMutexForTask(factor float64, delay int64) *redsync.Mutex {
	// Grab the pool
	redisPool := r.pool
	nodes := []redsync.Pool{redisPool}

	// Generate the mutex w/ token
	redSyncToken := r.redlockToken()
	redMutex, err := redsync.NewMutexWithGenericPool(redSyncToken, nodes)
	if err != nil {
		meshLog.Fatalf("Error creating RedMutex in limiter: %+v", err)
		return nil
	}

	// Configure the mutex to have add sleep time randomness to its waiting. It was
	// found in testing that w/ out this, the system locks in step w/ itself when not using
	// a local pmutex. This is a danger for dist systems
	redMutex.Tries = 10000
	sleepTime := (rand.Float64() * factor * float64(delay)) + float64(delay)
	redMutex.Delay = time.Duration(sleepTime) * time.Millisecond
	redMutex.Expiry = 15 * time.Second
	return redMutex
}