Context and Cancellation
Helper Context
Passing context into a helper lets the helper read request-scoped data.
pass context
Functions usually accept a context as their first parameter so callers can pass values and cancellation.
Helper Context
helper_context.go
Replay: real traced execution (multi-file project)
package main
import (
"context"
"fmt"
)
type requestKey string
func labelRequest(ctx context.Context, action string) string {
id := ctx.Value(requestKey("id"))
return fmt.Sprintf("%v:%s", id, action)
}
func main() {
var action = "save"
ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")
label := labelRequest(ctx, action)
fmt.Println("action=", action)
fmt.Println("label=", label)
}
package main
import (
"context"
"fmt"
)
type requestKey string
func labelRequest(ctx context.Context, action string) string {
id := ctx.Value(requestKey("id"))
return fmt.Sprintf("%v:%s", id, action)
}
func main() {
var action = "load"
ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")
label := labelRequest(ctx, action)
fmt.Println("action=", action)
fmt.Println("label=", label)
}
package main
import (
"context"
"fmt"
)
type requestKey string
func labelRequest(ctx context.Context, action string) string {
id := ctx.Value(requestKey("id"))
return fmt.Sprintf("%v:%s", id, action)
}
func main() {
var action = "delete"
ctx := context.WithValue(context.Background(), requestKey("id"), "req-7")
label := labelRequest(ctx, action)
fmt.Println("action=", action)
fmt.Println("label=", label)
}
action ← "save", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}
15func main() {16 var action→ "save" = "save" //@action="load", "delete"17 ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819 label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"save")20 fmt.Println("action=", action)id ← "req-7"
10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"save" string) string {11 id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12 return fmt.Sprintf("%v:%s", id"req-7", action"save")13}label ← "req-7:save"
19 label→ "req-7:save" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"save")20 fmt.Println("action=", action"save")21 fmt.Println("label=", label"req-7:save")22}outputaction= save label= req-7:save
action ← "load", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}
15func main() {16 var action→ "load" = "load"17 ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819 label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"load")20 fmt.Println("action=", action)id ← "req-7"
10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"load" string) string {11 id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12 return fmt.Sprintf("%v:%s", id"req-7", action"load")13}label ← "req-7:load"
19 label→ "req-7:load" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"load")20 fmt.Println("action=", action"load")21 fmt.Println("label=", label"req-7:load")22}outputaction= load label= req-7:load
action ← "delete", ctx ← &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}
15func main() {16 var action→ "delete" = "delete"17 ctx→ &context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} := context.WithValue(context.Background(), requestKey("id"), "req-7")1819 label := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"delete")20 fmt.Println("action=", action)id ← "req-7"
10func labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"} context.Context, action"delete" string) string {11 id→ "req-7" := ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}.Value(requestKey("id"))12 return fmt.Sprintf("%v:%s", id"req-7", action"delete")13}label ← "req-7:delete"
19 label→ "req-7:delete" := labelRequest(ctx&context.valueCtx{Context:context.backgroundCtx{emptyCtx:context.emptyCtx{}}, key:"id", val:"req-7"}, action"delete")20 fmt.Println("action=", action"delete")21 fmt.Println("label=", label"req-7:delete")22}outputaction= delete label= req-7:delete