Change: proxy gruop strategy improvement

This commit is contained in:
Dreamacro
2019-12-10 15:04:22 +08:00
parent bd4302e096
commit 2334bafe68
7 changed files with 198 additions and 63 deletions

View File

@ -0,0 +1,54 @@
package singledo
import (
"sync"
"time"
)
type call struct {
wg sync.WaitGroup
val interface{}
err error
}
type Single struct {
mux sync.Mutex
last int64
wait int64
call *call
result *Result
}
type Result struct {
Val interface{}
Err error
}
func (s *Single) Do(fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
s.mux.Lock()
now := time.Now().Unix()
if now < s.last+s.wait {
s.mux.Unlock()
return s.result.Val, s.result.Err, true
}
if call := s.call; call != nil {
s.mux.Unlock()
call.wg.Wait()
return call.val, call.err, true
}
call := &call{}
call.wg.Add(1)
s.call = call
s.mux.Unlock()
call.val, call.err = fn()
s.call = nil
s.result = &Result{call.val, call.err}
s.last = now
return call.val, call.err, false
}
func NewSingle(wait time.Duration) *Single {
return &Single{wait: int64(wait)}
}

View File

@ -0,0 +1,52 @@
package singledo
import (
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
func TestBasic(t *testing.T) {
single := NewSingle(time.Millisecond * 30)
foo := 0
shardCount := 0
call := func() (interface{}, error) {
foo++
return nil, nil
}
var wg sync.WaitGroup
const n = 10
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
_, _, shard := single.Do(call)
if shard {
shardCount++
}
wg.Done()
}()
}
wg.Wait()
assert.Equal(t, 1, foo)
assert.Equal(t, 9, shardCount)
}
func TestTimer(t *testing.T) {
single := NewSingle(time.Millisecond * 30)
foo := 0
call := func() (interface{}, error) {
foo++
return nil, nil
}
single.Do(call)
time.Sleep(10 * time.Millisecond)
_, _, shard := single.Do(call)
assert.Equal(t, 1, foo)
assert.True(t, shard)
}