Document is a work-in-progress
Go-gentle

Talk to external services like a gentleman.
Intro
Package gentle defines Stream and Handler interfaces and provides composable resilient implementations of them.
Example
Error handling is omitted for brevity.
// GameScore implements gentle.Message interface
type GameScore struct {
id string // better to be unique for tracing its log
score int
}
func (s GameScore) ID() string {
return s.id
}
func parseGameScore(bs []byte) *GameScore {
// ...
}
// query a restful api to get game score
var query gentle.SimpleStream = func(_ context.Context) (gentle.Message, error) {
resp, _ := http.Get("https://get_game_score_api")
defer resp.Body.Close()
score := parseGameScore(resp.Body)
return score, nil
}
// save game score
var writeDb gentle.SimpleHandler = func(_ context.Context, msg gentle.Message) (gentle.Message, error) {
score := strconv.Itoa(msg.(*GameScore).score)
db, _ := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/hello")
defer db.Close()
stmt, _ := db.Prepare("UPDATE games SET score = $1 WHERE name = mygame")
stmt.Exec(score)
return msg, nil
}
// rate-limit the queries while allowing burst
gentleQuery := gentle.NewRateLimitedStream(
gentle.NewRateLimitedStreamOpts("", "myApp",
gentle.NewTokenBucketRateLimit(300*time.Millisecond, 5)),
gentleQuery)
// limit concurrent writeDb
gentleWriteDb := gentle.NewBulkheadHandler(
gentle.NewBulkheadHandlerOpts("", "myApp", 16),
writeDb)
stream := gentle.AppendHandlersStream(gentleQuery, gentleWriteDb)
http.Handle("/refresh", func(w http.ResponseWriter, r *http.Request) {
...
msg, err := stream.Get(r.context)
...
})
http.ListenAndServe(":12345", nil)
Install
The master branch is considered unstable. Always depend on semantic versioning and verdor this library.
If you're using glide, simply run:
glide get gopkg.in/cfchou/go-gentle.v3/gentle
glide update
If you're not using package management tools, then
go get http://gopkg.in/cfchou/go-gentle.v3/gentle