It's interesting to see a piece of code in the Kite Project today.
//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, Privatekeystring) (string, error) {Tokencachemu.lock () defer tokencachemu.unlock () Uniqkey:= AUD + username + Issuer//neglect Privatekey, its always the sameSigned, OK: =Tokencache[uniqkey]ifOK {returnsigned, nil} Tknid, err:=UUID. NewV4 ()ifErr! =Nil {return "", errors. New ("Server Error:cannot generate a token") } //identifies the expiration time after which the JWT must wasn't be accepted//For processing.TTL: =Tokenttl//implementers provide for some small leeway, usually no more than//a few minutes for clock skew.Leeway: =tokenleeway tkn:= JWT. New (JWT. Getsigningmethod ("RS256") ) tkn. claims["ISS"] = Issuer//IssuerTkn. claims["Sub"] = Username//SubjectTkn. claims["AUD"] = AUD//AudienceTkn. claims["Exp"] = time. Now (). UTC (). Add (TTL). ADD (Leeway). Unix ()//Expiration TimeTkn. claims["NBF"] = time. Now (). UTC (). ADD (-leeway). Unix ()//Not beforeTkn. claims["IAT"] = time. Now (). UTC (). Unix ()//Issued atTkn. claims["JTI"] = tknid.string ()//JWT IDsigned, Err= Tkn. Signedstring ([]byte(Privatekey))ifErr! =Nil {return "", errors. New ("Server Error:cannot generate a token") } //Cache Our TokensTokencache[uniqkey] =signed//cache invalidation, because we cache the token in Tokencache we need to//invalidate it expiration time. This is handled usually within JWT, but//now we had to do it manually for our own cache. Time. Afterfunc (Tokenttl-tokenleeway, func () {Tokencachemu.lock () defer tokencachemu.unlock () Delete (token Cache, Uniqkey)})returnsigned, nil}
Here's time . Afterfunc to do token's timeout, which I didn't know before.
I had previously done myself to start a separate Goroutine, to all tokens do the traversal, to determine whether or not timeout,timout to delete the operation.
See this code, the first feeling is very good, the second is if used up, will not have any side effects.
Look at the Source: https://golang.org/src/time/sleep.go?h=AfterFunc#L116
//Afterfunc waits for the duration to elapse and then calls F the //In its own goroutine. It returns a Timer that can the //be used to cancel the call using its Stop method. theFunc Afterfunc (d Duration, F func ()) *Timer {117T: = &timer{118r:runtimetimer{119When:when (d), -F:gofunc,121Arg:f,122 }, 123 } 124 Starttimer (&T.R) the returnT126}
Here Starttimer is using the system's own timer implementation, but is golang here to do a layer compatible with each platform package, there should be no side effects.
- //Interface to timers implemented on package runtime. the //must is in sync with. /runtime/runtime.h:/^struct. timer$ -Type Runtimetimerstruct { -Iint -When Int64 +period Int64 -F func (Interface{}, UIntPtr)//Note:must not being closure +ArgInterface{} Aseq UIntPtr at } - - //When was a helper function for setting the ' when ' field of a runtimetimer. - //It returns what the time would be, in nanoseconds, and Duration D in the future. - //If D is negative, it is ignored. If The returned value would is less than - //Zero because of an overflow, MaxInt64 is returned. infunc when (d Duration) Int64 { - ifD <=0 { to returnRuntimenano () + } -T: = Runtimenano () +Int64 (d) the ifT <0 { *t =1<< the-1 //Math. MaxInt64 $ } Panax Notoginseng returnT - } the starttimer func (*runtimetimer), Stoptimer func (*runtimetimer) bool
Have to feel, the original library or there are a lot of good things, you need to slowly discover.
Golang Timer (timer), more skillfully handle timeout