|
مهلت زمانی (timeout) برای برنامههایی که به منابع
خارجی وصل میشوند یا به هر دلیلی باید زمان اجرا را
محدود کنند اهمیت دارد. پیادهسازی timeout در Go به لطف
کانالها و select ساده و زیباست.
|
|
|
|

package main
|
|
|
import (
"fmt"
"time"
)
|
|
|
func main() {
|
|
در این مثال فرض کنید یک فراخوانی خارجی انجام میدهیم
که نتیجهاش را پس از ۲ ثانیه روی کانال c1
برمیگرداند. توجه کنید که کانال بافردار است، پس
ارسال در گوروتین مسدود نمیشود. این الگویی رایج برای
جلوگیری از نشت گوروتین (goroutine leak) است، در
صورتی که هیچوقت از کانال خوانده نشود.
|
c1 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c1 <- "result 1"
}()
|
|
این select مهلت زمانی را پیادهسازی میکند.
res := <-c1 منتظر نتیجه میماند و <-time.After
منتظر مقداری میماند که پس از مهلت ۱ ثانیه فرستاده
میشود. چون select با اولین دریافتی که آماده شود
جلو میرود، اگر عملیات بیشتر از ۱ ثانیهٔ مجاز طول
بکشد، حالت timeout انتخاب میشود.
|
select {
case res := <-c1:
fmt.Println(res)
case <-time.After(1 * time.Second):
fmt.Println("timeout 1")
}
|
|
اگر مهلت طولانیتری مثل ۳ ثانیه بدهیم، دریافت از
c2 موفق میشود و نتیجه را چاپ میکنیم.
|
c2 := make(chan string, 1)
go func() {
time.Sleep(2 * time.Second)
c2 <- "result 2"
}()
select {
case res := <-c2:
fmt.Println(res)
case <-time.After(3 * time.Second):
fmt.Println("timeout 2")
}
}
|