Skip to content

Instantly share code, notes, and snippets.

@npat-efault
Last active August 29, 2015 14:09
Show Gist options
  • Save npat-efault/139583b66c745332a8b0 to your computer and use it in GitHub Desktop.
Save npat-efault/139583b66c745332a8b0 to your computer and use it in GitHub Desktop.
Token server example, see http://goo.gl/QVCgcL
package main
import (
"fmt"
"time"
)
type Token struct {
token string
expires time.Time
}
type TokenServer struct {
getToken chan Token
newToken chan Token
token Token
timer *time.Timer
}
func NewTokenServer() *TokenServer {
s := &TokenServer{}
s.getToken = make(chan Token)
s.newToken = make(chan Token)
go s.run()
return s
}
func (s *TokenServer) run() {
fmt.Println("TokenServer, starting...")
// Initially, we have no token. Wait for one.
go s.getNewToken()
s.token = <-s.newToken
fmt.Println("TokenServer, acquired token:", s.token.token)
s.timer = time.NewTimer(s.token.expires.Sub(time.Now()))
// We have a token, we can start serving clients.
for {
select {
case s.getToken <- s.token:
// Send token to client
case s.token = <-s.newToken:
// New token arrived. Schedule next refresh.
fmt.Println("TokenServer, new token:", s.token.token)
s.timer.Reset(s.token.expires.Sub(time.Now()))
case <-s.timer.C:
// Acquire new token (will send results on
// s.newtoken)
fmt.Println("TokenServer, getNewToken...")
go s.getNewToken()
}
}
}
func (s *TokenServer) getNewToken() {
// Simulate operation that takes long to complete
time.Sleep(2 * time.Second)
// Send result
s.newToken <- Token{
token: "1234",
expires: time.Now().Add(2 * time.Second),
}
}
func (s *TokenServer) Get() Token {
return <-s.getToken
}
func main() {
s := NewTokenServer()
fmt.Println(s.Get().token)
time.Sleep(3 * time.Second)
fmt.Println(s.Get().token)
time.Sleep(8 * time.Second)
fmt.Println(s.Get().token)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment