github.com/searKing/golang/go@v1.2.74/time/rate/example_test.go (about) 1 package rate_test 2 3 import ( 4 "context" 5 "fmt" 6 "math/rand" 7 "runtime" 8 "sync" 9 "time" 10 11 "github.com/searKing/golang/go/time/rate" 12 ) 13 14 func ExampleNewFullBurstLimiter() { 15 const ( 16 burst = 3 17 ) 18 limiter := rate.NewFullBurstLimiter(burst) 19 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 20 defer cancel() 21 22 // expect dropped, as limiter is initialized with full tokens(3) 23 limiter.PutToken() 24 25 for i := 0; ; i++ { 26 //fmt.Printf("%03d %s\n", i, time.Now().Format(time.RFC3339)) 27 fmt.Printf("Wait %03d, tokens left: %d\n", i, limiter.Tokens()) 28 err := limiter.Wait(ctx) 29 if err != nil { 30 fmt.Printf("err: %s\n", err.Error()) 31 return 32 } 33 fmt.Printf("Got %03d, tokens left: %d\n", i, limiter.Tokens()) 34 35 // actor mocked by gc 36 runtime.GC() 37 38 if i == 0 { 39 // refill one token 40 limiter.PutToken() 41 } 42 } 43 // Output: 44 // Wait 000, tokens left: 3 45 // Got 000, tokens left: 2 46 // Wait 001, tokens left: 3 47 // Got 001, tokens left: 2 48 // Wait 002, tokens left: 2 49 // Got 002, tokens left: 1 50 // Wait 003, tokens left: 1 51 // Got 003, tokens left: 0 52 // Wait 004, tokens left: 0 53 // err: context deadline exceeded 54 } 55 56 func ExampleNewEmptyBurstLimiter() { 57 const ( 58 burst = 3 59 concurrency = 2 60 ) 61 limiter := rate.NewEmptyBurstLimiter(burst) 62 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 63 defer cancel() 64 65 fmt.Printf("tokens left: %d\n", limiter.Tokens()) 66 67 // expect not allowed, as limiter is initialized with empty tokens(0) 68 if limiter.Allow() { 69 fmt.Printf("allow passed\n") 70 } else { 71 fmt.Printf("allow refused\n") 72 } 73 // fill one token 74 limiter.PutToken() 75 fmt.Printf("tokens left: %d\n", limiter.Tokens()) 76 77 // expect allowed, as limiter is filled with one token(1) 78 if limiter.Allow() { 79 fmt.Printf("allow passed\n") 80 } else { 81 fmt.Printf("allow refused\n") 82 } 83 fmt.Printf("tokens left: %d\n", limiter.Tokens()) 84 85 var mu sync.Mutex 86 var wg sync.WaitGroup 87 for i := 0; i < concurrency; i++ { 88 wg.Add(1) 89 go func() { 90 defer wg.Done() 91 //fmt.Printf("%03d %s\n", i, time.Now().Format(time.RFC3339)) 92 mu.Lock() 93 fmt.Printf("Wait 1 Token, tokens left: %d\n", limiter.Tokens()) 94 mu.Unlock() 95 err := limiter.Wait(ctx) 96 if err != nil { 97 mu.Lock() 98 fmt.Printf("err: %s\n", err.Error()) 99 mu.Unlock() 100 return 101 } 102 103 mu.Lock() 104 fmt.Printf("Got 1 Token, tokens left: %d\n", limiter.Tokens()) 105 mu.Unlock() 106 }() 107 } 108 109 time.Sleep(10 * time.Millisecond) 110 for i := 0; i < concurrency; i++ { 111 time.Sleep(10 * time.Millisecond) 112 mu.Lock() 113 fmt.Printf("PutToken #%d: before tokens left: %d\n", i, limiter.Tokens()) 114 // fill one token 115 limiter.PutToken() 116 fmt.Printf("PutToken #%d: after tokens left: %d\n", i, limiter.Tokens()) 117 mu.Unlock() 118 } 119 wg.Wait() 120 fmt.Printf("tokens left: %d\n", limiter.Tokens()) 121 122 // expect allowed, as limiter is filled with one token(1) 123 if limiter.Allow() { 124 fmt.Printf("allow passed\n") 125 } else { 126 fmt.Printf("allow refused\n") 127 } 128 fmt.Printf("tokens left: %d\n", limiter.Tokens()) 129 130 // expect not allowed, as limiter is initialized with empty tokens(0) 131 if limiter.Allow() { 132 fmt.Printf("allow passed\n") 133 } else { 134 fmt.Printf("allow refused\n") 135 } 136 // Output: 137 // tokens left: 0 138 // allow refused 139 // tokens left: 1 140 // allow passed 141 // tokens left: 0 142 // Wait 1 Token, tokens left: 0 143 // Wait 1 Token, tokens left: 0 144 // PutToken #0: before tokens left: 0 145 // PutToken #0: after tokens left: 0 146 // Got 1 Token, tokens left: 0 147 // PutToken #1: before tokens left: 0 148 // PutToken #1: after tokens left: 0 149 // Got 1 Token, tokens left: 0 150 // tokens left: 0 151 // allow refused 152 // tokens left: 0 153 // allow refused 154 } 155 156 func ExampleBurstLimiter_Reserve() { 157 const ( 158 burst = 1 159 n = 10 160 ) 161 limiter := rate.NewFullBurstLimiter(burst) 162 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 163 defer cancel() 164 165 // expect dropped, as limiter is initialized with full tokens(3) 166 limiter.PutToken() 167 168 type Reservation struct { 169 index int 170 r *rate.Reservation 171 } 172 173 var mu sync.Mutex 174 var wg sync.WaitGroup 175 var rs []*Reservation 176 177 for i := 0; i < n; i++ { 178 //fmt.Printf("%03d %s\n", i, time.Now().Format(time.RFC3339)) 179 fmt.Printf("Reserve %03d\n", i) 180 r := &Reservation{ 181 index: i, 182 r: limiter.Reserve(ctx), 183 } 184 if i%2 == rand.Intn(2)%2 { 185 rs = append(rs, r) 186 continue 187 } 188 wg.Add(1) 189 go func() { 190 defer wg.Done() 191 //fmt.Printf("%03d %s\n", r.index, time.Now().Format(time.RFC3339)) 192 //fmt.Printf("Wait %03d\n", r.index) 193 err := r.r.Wait(ctx) 194 if err != nil { 195 mu.Lock() 196 fmt.Printf("err: %s\n", err.Error()) 197 mu.Unlock() 198 } 199 200 mu.Lock() 201 fmt.Printf("%03d Got 1 Token, tokens left: %d\n", r.index, limiter.Tokens()) 202 mu.Unlock() 203 r.r.PutToken() 204 }() 205 } 206 207 for i := 0; i < len(rs); i++ { 208 r := rs[i] 209 wg.Add(1) 210 go func() { 211 defer wg.Done() 212 //fmt.Printf("%03d %s\n", r.index, time.Now().Format(time.RFC3339)) 213 //fmt.Printf("Wait %03d\n", r.index) 214 err := r.r.Wait(ctx) 215 if err != nil { 216 mu.Lock() 217 fmt.Printf("err: %s\n", err.Error()) 218 mu.Unlock() 219 } 220 221 mu.Lock() 222 fmt.Printf("%03d Got 1 Token, tokens left: %d\n", r.index, limiter.Tokens()) 223 mu.Unlock() 224 r.r.PutToken() 225 }() 226 } 227 wg.Wait() 228 // Output: 229 // Reserve 000 230 // Reserve 001 231 // Reserve 002 232 // Reserve 003 233 // Reserve 004 234 // Reserve 005 235 // Reserve 006 236 // Reserve 007 237 // Reserve 008 238 // Reserve 009 239 // 000 Got 1 Token, tokens left: 0 240 // 001 Got 1 Token, tokens left: 0 241 // 002 Got 1 Token, tokens left: 0 242 // 003 Got 1 Token, tokens left: 0 243 // 004 Got 1 Token, tokens left: 0 244 // 005 Got 1 Token, tokens left: 0 245 // 006 Got 1 Token, tokens left: 0 246 // 007 Got 1 Token, tokens left: 0 247 // 008 Got 1 Token, tokens left: 0 248 // 009 Got 1 Token, tokens left: 0 249 250 }