Context Package As Data Bag
- Context Package can used to transport request-scoped data down the call graph.
- context.WithValue() provides a way to associate request-scoped values with Context.
context.WithValue() and context.Value()
- context.WithValue() - is used to associate request-scoped data with context.
- context.Value - is used to extract the value given a key from the context.
Parent Goroutine
type userIDType string
ctx := context.WithValue(context.Background(),userIDType("userIDKey"),"Kimi")
Child Goroutine
userId := context.Value(userIDType("userIDKey")).(userIDType)
exercise
witvalue() https://go.dev/play/p/kGdlPUgbTxL
package main
import (
"context"
"fmt"
)
type database map[string]bool
type userIDKey string
var db database = database{
"Kimi": true,
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
processRequest(ctx, "Kimi")
}
func processRequest(ctx context.Context, userid string) {
// send userID information to checkMemberShip through context for
// map lookup.
vctx := context.WithValue(ctx, userIDKey("userIDKey"), userid)
ch := checkMemberShip(vctx)
status := <-ch
fmt.Printf("membership status of userid : %s : %v\n", userid, status)
}
// checkMemberShip - takes context as input.
// extracts the user id information from context.
// spins a goroutine to do map lookup
// sends the result on the returned channel.
func checkMemberShip(ctx context.Context) <-chan bool {
ch := make(chan bool)
go func() {
defer close(ch)
// do some database lookup
userid := ctx.Value(userIDKey("userIDKey")).(string)
status := db[userid]
ch <- status
}()
return ch
}