2019-01-24 20:15:10 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-10-24 13:35:59 +01:00
|
|
|
// See LICENSE for copying information
|
|
|
|
|
2018-12-20 14:51:39 +00:00
|
|
|
package sync2_test
|
2018-10-24 13:35:59 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"sync/atomic"
|
|
|
|
"testing"
|
|
|
|
"time"
|
2018-12-20 14:51:39 +00:00
|
|
|
|
2019-11-14 19:46:15 +00:00
|
|
|
"storj.io/storj/private/sync2"
|
2018-10-24 13:35:59 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestLimiterLimiting(t *testing.T) {
|
2019-02-20 09:22:53 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2018-10-24 13:35:59 +01:00
|
|
|
const N, Limit = 1000, 10
|
|
|
|
ctx := context.Background()
|
2018-12-20 14:51:39 +00:00
|
|
|
limiter := sync2.NewLimiter(Limit)
|
2018-10-24 13:35:59 +01:00
|
|
|
counter := int32(0)
|
|
|
|
for i := 0; i < N; i++ {
|
|
|
|
limiter.Go(ctx, func() {
|
|
|
|
if atomic.AddInt32(&counter, 1) > Limit {
|
|
|
|
panic("limit exceeded")
|
|
|
|
}
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
atomic.AddInt32(&counter, -1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
limiter.Wait()
|
|
|
|
}
|
|
|
|
|
2019-04-17 11:09:44 +01:00
|
|
|
func TestLimiterCanceling(t *testing.T) {
|
2019-02-20 09:22:53 +00:00
|
|
|
t.Parallel()
|
|
|
|
|
2018-10-24 13:35:59 +01:00
|
|
|
const N, Limit = 1000, 10
|
2018-12-20 14:51:39 +00:00
|
|
|
limiter := sync2.NewLimiter(Limit)
|
2018-10-24 13:35:59 +01:00
|
|
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
|
|
|
counter := int32(0)
|
|
|
|
|
|
|
|
waitForCancel := make(chan struct{}, N)
|
|
|
|
block := make(chan struct{})
|
|
|
|
allreturned := make(chan struct{})
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for i := 0; i < N; i++ {
|
|
|
|
limiter.Go(ctx, func() {
|
|
|
|
if atomic.AddInt32(&counter, 1) > Limit {
|
|
|
|
panic("limit exceeded")
|
|
|
|
}
|
|
|
|
|
|
|
|
waitForCancel <- struct{}{}
|
|
|
|
<-block
|
|
|
|
})
|
|
|
|
}
|
|
|
|
close(allreturned)
|
|
|
|
}()
|
|
|
|
|
|
|
|
for i := 0; i < Limit; i++ {
|
|
|
|
<-waitForCancel
|
|
|
|
}
|
|
|
|
cancel()
|
|
|
|
<-allreturned
|
|
|
|
close(block)
|
|
|
|
|
|
|
|
limiter.Wait()
|
|
|
|
if counter > Limit {
|
|
|
|
t.Fatal("too many times run")
|
|
|
|
}
|
|
|
|
}
|