golang 中的定時器(timer),更巧妙的處理timeout

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

今天看到kite項目中的一段代碼,發現挺有意思的。

 

// generateToken returns a JWT token string. Please see the URL for details:// http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1func generateToken(aud, username, issuer, privateKey string) (string, error) {    tokenCacheMu.Lock()    defer tokenCacheMu.Unlock()    uniqKey := aud + username + issuer // neglect privateKey, its always the same    signed, ok := tokenCache[uniqKey]    if ok {        return signed, nil    }    tknID, err := uuid.NewV4()    if err != nil {        return "", errors.New("Server error: Cannot generate a token")    }    // Identifies the expiration time after which the JWT MUST NOT be accepted    // for processing.    ttl := TokenTTL    // Implementers MAY provide for some small leeway, usually no more than    // a few minutes, to account for clock skew.    leeway := TokenLeeway    tkn := jwt.New(jwt.GetSigningMethod("RS256"))    tkn.Claims["iss"] = issuer                                       // Issuer    tkn.Claims["sub"] = username                                     // Subject    tkn.Claims["aud"] = aud                                          // Audience    tkn.Claims["exp"] = time.Now().UTC().Add(ttl).Add(leeway).Unix() // Expiration Time    tkn.Claims["nbf"] = time.Now().UTC().Add(-leeway).Unix()         // Not Before    tkn.Claims["iat"] = time.Now().UTC().Unix()                      // Issued At    tkn.Claims["jti"] = tknID.String()                               // JWT ID    signed, err = tkn.SignedString([]byte(privateKey))    if err != nil {        return "", errors.New("Server error: Cannot generate a token")    }    // cache our token    tokenCache[uniqKey] = signed    // cache invalidation, because we cache the token in tokenCache we need to    // invalidate it expiration time. This was handled usually within JWT, but    // now we have to do it manually for our own cache.    time.AfterFunc(TokenTTL-TokenLeeway, func() {        tokenCacheMu.Lock()        defer tokenCacheMu.Unlock()        delete(tokenCache, uniqKey)    })    return signed, nil}

這裡的  time.AfterFunc 來做token的timeout處理,是我之前都不知道的。

我之前的做法,自己啟動一個 單獨的 goroutine,對所有的token做遍曆,判斷是否timeout,timout了就進行刪除操作。

看到了這段代碼,第一個感覺是很妙,第二個是如果用起來,會不會有啥副作用。

翻看源碼:https://golang.org/src/time/sleep.go?h=AfterFunc#L116

// AfterFunc waits for the duration to elapse and then calls f   114    // in its own goroutine. It returns a Timer that can   115    // be used to cancel the call using its Stop method.   116    func AfterFunc(d Duration, f func()) *Timer {   117        t := &Timer{   118            r: runtimeTimer{   119                when: when(d),   120                f:    goFunc,   121                arg:  f,   122            },   123        }   124        startTimer(&t.r)   125        return t   126    }

這裡的startTimer 是用了系統自身的timer實現,只不過是golang在這裡做了一層相容各個平台的封裝,應該是沒有什麼副作用啦。

14    // Interface to timers implemented in package runtime.    15    // Must be in sync with ../runtime/runtime.h:/^struct.Timer$    16    type runtimeTimer struct {    17        i      int    18        when   int64    19        period int64    20        f      func(interface{}, uintptr) // NOTE: must not be closure    21        arg    interface{}    22        seq    uintptr    23    }    24        25    // when is a helper function for setting the 'when' field of a runtimeTimer.    26    // It returns what the time will be, in nanoseconds, Duration d in the future.    27    // If d is negative, it is ignored.  If the returned value would be less than    28    // zero because of an overflow, MaxInt64 is returned.    29    func when(d Duration) int64 {    30        if d <= 0 {    31            return runtimeNano()    32        }    33        t := runtimeNano() + int64(d)    34        if t < 0 {    35            t = 1<<63 - 1 // math.MaxInt64    36        }    37        return t    38    }    39        40    func startTimer(*runtimeTimer)    41    func stopTimer(*runtimeTimer) bool

 

不得不感慨,原生庫還是有很多好東東的,需要自己慢慢發覺。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.