ãã®è¨äºã¯Qiitaã§å ¬éããã¦ãã¾ãã
ä¾ãã°ãAPIã®çµæã使ã£ãå¦çãè¡ãå ´åãã¦ã¼ã¶ã¨ãã¦ã¯ãªãã¹ãæ©ãå¦çãããããã©ãæ©ãããã¨ãµã¼ãã®å¦çã追ãã¤ããªãã±ã¼ã¹ã¯ããããã¨æãã¾ãã
ããããæãAPIãå®è¡ããå¾ã§time.After
çã使ã£ã¦å°ãå¾
ã£ã¦ãããå¿
è¦ãªçµæãæãã¾ã§ç¹°ãè¿ãã¨ããã®ãç°¡åãªè§£æ±ºæ¹æ³ã§ãããAPIã®å®è¡æéã¨time.After
ã§å¾
ã¤æéã®ä¸¡æ¹ãå®è¡æéã«æãã£ã¦ãã¾ãããã1ç§éã«100åã¾ã§ãã¨ããã±ã¼ã¹ã¯ãªããªã対å¿ãé£ããã®ã§ãx/time/rate
ã使ã£ã¦ã¿ã¾ããã
å¶éããªãå®è£
æ¯è¼ã®ããã«ãä½ãå¶éãããªãå®è£ ãç¨æãã¾ããã10ä¸ä»¶ã®ãã¼ã¿ããã£ãã«ã«éãç¶ããã ãã®ã³ã¼ãã§ãã
package main import ( "fmt" ) const N = 100000 func main() { c := make(chan int, 1000) go func() { for i := 0; i < N; i++ { c <- i } close(c) }() for n := range c { fmt.Println(n) } }
ãã®ãã¼ã¸ã§ã³ã¯ãæå ã®ãã·ã³ã§ã¯0.5ç§ç¨åº¦ã§çµããã¾ãã
å¶éãå ¥ããå®è£
次ã«ãå¶éãå
¥ãããã¼ã¸ã§ã³ã§ããx/time/rate
ã使ã£ã¦ã1ç§éã«1ä¸ä»¶ã¾ã§ãä¸éã¨ãã¾ããã
package main import ( "fmt" "log" "time" "golang.org/x/net/context" "golang.org/x/time/rate" ) const ( N = 100000 // å ¨ä½æ° M = 10000 // 1ç§ãããã®å¦çå¶é ) func main() { log.SetFlags(0) c := make(chan int, 1000) go func() { ctx := context.Background() n := rate.Every(time.Second/M) l := rate.NewLimiter(n, M) for i := 0; i < N; i++ { if err := l.Wait(ctx); err != nil { log.Fatalln(err) } c <- i } close(c) }() for n := range c { fmt.Println(n) } }
ãã®ãã¼ã¸ã§ã³ã¯æå ã§ã¯9ç§ç¨åº¦ãå¿ è¦ã§ãã1ç§ã«1ä¸ä»¶ã®é度ã§10ä¸ä»¶ã®ãã¼ã¿ãå¦çããã®ã§å½ç¶ã§ããã
説æ
x/time/rate
ããã±ã¼ã¸ã¯ãæéã®çµéã«å¾ã£ã¦å¦çã許å¯ããåæ°åã®ãã¼ã¯ã³ãæºã¾ã£ã¦ãããå¦çãè¡ãåã«ãã¼ã¯ã³ãæ¶è²»ãã¦å®è¡å¯è½ããå¤æãã¾ãã1ç§ã«1ä¸ä»¶å¦çã§ãããã¼ã¯ã³ãçºè¡ããããã«ã¯ã100ãã¤ã¯ãç§ãã¨ã«1ã¤ãã¼ã¯ã³ãçºè¡ãããå¿
è¦ãããã¾ãã
ã³ã¼ãã«è½ã¨ãã¨ãåºæ¬ã¨ãªãã®ã¯3è¡ã§ã
n := rate.Every(time.Second/M) l := rate.NewLimiter(n, M) err := l.Wait(ctx)
1ç§éã«1ä¸ä»¶ã¾ã§ãå¶éã¨ããã®ã§ãã¾ãrate.Every(time.Second/M)
ã§100ãã¤ã¯ãç§ãã¨ã«1ã¤ãã¼ã¯ã³ãçæãããããã«ãã¦ãã¾ãã次ã«n
ã使ã£ã¦ãã¼ã¯ã³ãçºè¡ããrate.Limiter
ãçæãã¾ãããrate.NewLimiter(n, M)
ã®M
ã¯ä½ãã¨ããã¨ããã¼ã¯ã³ãæ¶è²»ãããªãå ´åã§ã貯ã¾ãç¶ããªãããã«ä¸éãè¨å®ãã¦ãã¾ããééãªãæºã¾ã£ã¦ãããã¼ã¯ã³ã¾ã¨ãã¦å¦çãããã¨å¶éãããæå³ããªãã§ããããæå¾ã«l.Wait(ctx)
ã§1ã¤ãã¼ã¯ã³ãæ¶è²»ãã¾ãããã®æç¹ã§ãã¼ã¯ã³ã1ã¤ã貯ã¾ã£ã¦ããªããã°è²¯ã¾ãã¾ã§ãããã¯ãã¾ãã
ãã®ä¾ã§ã¯ä½¿ã£ã¦ãã¾ããããWait
ãå¿
è¦ä»¥ä¸ã«å¾
æ©ããªãããã«ãctx
ã使ã£ã¦ã¿ã¤ã ã¢ã¦ãããã£ã³ã»ã«ãã§ãã¾ãã
ãã®ä»
rate.Limiter
ã«ã¯Wait
ã®ä»ã«ãWaitN
, Allow
, AllowN
ãªã©ã®ã¡ã½ãããç¨æããã¦ãã¾ããWaitN
ã¯ãã¼ã¯ã³ãè¤æ°å貯ã¾ãã¾ã§ãããã¯ããã¡ã½ããã§ã1ã¤ãã¤å¦çãããã¨ãåããªãå ´åã«ä¾¿å©ã§ãã
ã¾ããAllow
ãAllowN
ã¯ãã®æç¹ã§ãã¼ã¯ã³ã貯ã¾ã£ã¦ãããã©ãããè¿ãã¾ããtrue
ãè¿ã£ãå ´åã¯ãã¼ã¯ã³ãæ¶è²»ããã¦ãã¾ããReserve
ã¯ã©ãã ãå¾
ã¦ã°å¿
è¦ãªã ããã¼ã¯ã³ã貯ã¾ãã®ããæ±ãã¾ãã