From dbdc3629c3293ca3180811f9e6a2154e8443de89 Mon Sep 17 00:00:00 2001 From: qydysky Date: Mon, 12 Apr 2021 14:54:39 +0800 Subject: [PATCH] limit --- Limit.go | 57 --------------------------------------------- limit/Limit.go | 45 +++++++++++++++++++++++++++++++++++ limit/Limit_test.go | 42 +++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 57 deletions(-) delete mode 100644 Limit.go create mode 100644 limit/Limit.go create mode 100644 limit/Limit_test.go diff --git a/Limit.go b/Limit.go deleted file mode 100644 index 23467e6..0000000 --- a/Limit.go +++ /dev/null @@ -1,57 +0,0 @@ -package part - -import ( - "time" -) - -type Limitl struct { - Stop bool - Max int - Millisecond int - MilliTimeOut int - Channl chan bool -} - -func Limit(Max,Millisecond,MilliTimeOut int) (*Limitl) { - - // Logf().NoShow(false) - - if Max < 1 { - Logf().E("Limit:Max < 1 is true.Set to 1") - Max = 1 - } - - returnVal := Limitl{ - Max:Max, - Channl:make(chan bool,Max), - } - - if Millisecond < 1 || MilliTimeOut < Millisecond{ - Logf().E("Limit:Millisecond < 1 || MilliTimeOut < Millisecond is true.Set Stop to true") - returnVal.Stop = true - return &returnVal - } - - returnVal.Millisecond=Millisecond - returnVal.MilliTimeOut=MilliTimeOut - - go func(returnVal *Limitl){ - for !returnVal.Stop { - for i:=1;i<=returnVal.Max;i++{ - returnVal.Channl <- true - } - time.Sleep(time.Duration(Millisecond)*time.Millisecond) - } - }(&returnVal) - - return &returnVal -} - -func (l *Limitl) TO() bool { - if l.Stop {return false} - select { - case <-l.Channl :; - case <-time.After(time.Duration(l.MilliTimeOut)*time.Millisecond):return true; - } - return false -} \ No newline at end of file diff --git a/limit/Limit.go b/limit/Limit.go new file mode 100644 index 0000000..2fe1004 --- /dev/null +++ b/limit/Limit.go @@ -0,0 +1,45 @@ +package part + +import ( + "time" +) + +type limit struct { + maxNum_in_period int + ms_in_period int + ms_to_timeout int + channl chan struct{} +} + +// create a Limit Object +// it will allow maxNum_in_period requests(call TO()) in ms_in_period. if the request(call TO()) is out of maxNum_in_period,it will wait ms_to_timeout +func New(maxNum_in_period,ms_in_period,ms_to_timeout int) (*limit) { + if maxNum_in_period < 1 {panic(`limit max < 1`)} + + returnVal := limit{ + maxNum_in_period:maxNum_in_period, + ms_in_period:ms_in_period, + ms_to_timeout:ms_to_timeout, + channl:make(chan struct{},maxNum_in_period), + } + + go func(returnVal *limit){ + for { + for i:=1;i<=returnVal.maxNum_in_period;i++{ + returnVal.channl <- struct{}{} + } + time.Sleep(time.Duration(ms_in_period)*time.Millisecond) + } + }(&returnVal) + + return &returnVal +} + +// the func will return true if the request(call TO()) is up to limit and return false if not +func (l *limit) TO() bool { + select { + case <-l.channl :; + case <-time.After(time.Duration(l.ms_to_timeout)*time.Millisecond):return true; + } + return false +} \ No newline at end of file diff --git a/limit/Limit_test.go b/limit/Limit_test.go new file mode 100644 index 0000000..76a0641 --- /dev/null +++ b/limit/Limit_test.go @@ -0,0 +1,42 @@ +package part + +import ( + "testing" + "time" +) + +func Test_1(t *testing.T){ + l := New(10,1000,0) + pass := 0 + for i:=0;i<1500;i+=1{ + go func(){ + if !l.TO() {pass += 1} + }() + time.Sleep(time.Millisecond) + } + if pass!=20 {t.Error(`pass != 20`)} +} + +func Test_2(t *testing.T){ + l := New(10,1000,1000) + pass := 0 + for i:=0;i<500;i+=1{ + go func(){ + if !l.TO() {pass += 1} + }() + time.Sleep(time.Millisecond) + } + if pass!=10 {t.Error(`pass != 10`,pass)} +} + +func Test_3(t *testing.T){ + l := New(10,0,0) + pass := 0 + for i:=0;i<500;i+=1{ + go func(){ + if !l.TO() {pass += 1} + }() + time.Sleep(time.Millisecond) + } + t.Log(pass) +} \ No newline at end of file -- 2.39.2