博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang 中的定时器(timer),更巧妙的处理timeout
阅读量:4318 次
发布时间:2019-06-06

本文共 4031 字,大约阅读时间需要 13 分钟。

今天看到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

 

不得不感慨,原生库还是有很多好东东的,需要自己慢慢发觉。

 

转载于:https://www.cnblogs.com/zhangqingping/p/4683390.html

你可能感兴趣的文章
Android的View和ViewGroup分析
查看>>
淘宝爆款详情页制作的几个方法(理论)
查看>>
c语言单链表实现
查看>>
php无限极分类
查看>>
08——别让常逃离析构函数
查看>>
echarts.js中的图表大小自适应
查看>>
Linux总结
查看>>
llg的农场(farm)
查看>>
Delphi的FIFO实现
查看>>
mybatis入门相关笔记
查看>>
油猴 greasemonkey 背景音乐 火狐 chrome 背景音乐
查看>>
springMVC运行流程
查看>>
JavaScript 类
查看>>
COM笔记-动态链接
查看>>
如何使用vs2012单步调试uGUI(unity3d 5.3f4)
查看>>
跟我一起读postgresql源码(十一)——Executor(查询执行模块之——Materialization节点(上))...
查看>>
CSS画水平分割线
查看>>
node.js安装后出现环境变量错误找不到node
查看>>
alg: 首尾相连的珠子
查看>>
lua 5.3最简单plugin编写
查看>>