#gophercon talk by smita vijayakumar - go's context library
TRANSCRIPT
1
Go’s Context LibraryBy:
Smita Vijayakumar
Agenda
Introduction -Context Management in Distributed Systems
Go’s Context Library
Example Use case
Points to Watch Out For
2
1
2
3
4
3
Introduction
4
Distributed Data Flow
Request Processing
A B C
5
D ERPC RPC RPC RPC
6
Go Context
• Defines *Context* type • Carries request-scoped
values: - Deadlines - Cancellation signals - Others • Works across API
boundaries - Also between processes
7
Details
type Context interface { Done() <-chan struct{} Err() error Deadline() (deadline time.Time, ok bool) Value(key interface{}) interface{} }
8
1. Distributed Tracing 2. Request Cancellation 3. Context value
Primary Use Cases
9
struct ContextValue { requestID string}
Example 1 - Distributed Tracing
10
Types of Context Nodes
1. Background Node 2. Value Node 3. Cancellable Node 4. TODO() Node
Example -
A = context.Background()
B, cancelB = context.WithCancel(A)
C = context.WithValue(A, “C Key”, “C”)
D = context.WithValue(A, “D Key”, “D”)
E, cancelE = context.WithTimeout(B, timeout)
..
Background Context
A
With Value
CWith
Cancel
BWith Value
D
With Timeout
EWith Value
FWith Value
GWith Value
11
HWith Value
IWith Value
J
Types - A Context Tree
12
package userid
const ctxKey string = “UserID”
func SetContextValue(ctx context.Context, id int) context.Context { return context.WithValue(ctx, ctxKey, id)}
func GetContextValue(ctx context.Context) (int, bool) { id, ok := ctx.Value(ctxKey).(int) return id, ok}
Example 2 - UTIL Package
13
package request
func startRequest(event *event.Event, timeout time.Duration) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()
//…
ctx = util.SetContextValue(ctx, id) status, err := processor.Server(ctx, event) //…}
Example 2 - Cancellable Request - Set the Context
14
package request
func startRequest(event *event.Event, timeout time.Duration) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()
//…
ctx = util.SetContextValue(ctx, id) status, err := processor.Server(ctx, event) //…}
Example 2 - Cancellable Request - Set the Context
15
package request
func startRequest(event *event.Event, timeout time.Duration) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()
//…
ctx = util.SetContextValue(ctx, id) status, err := processor.Server(ctx, event) //…}
Example 2 - Cancellable Request - Set the Context
16
package processor
func Server(ctx context.Context, event *event.Event) error { if id, ok := util.FromContext(ctx); !ok { return errors.New(“Not a valid ID to process”) } p := make(chan error, 1) go func(ctx context.Context, id int, event *event.Event) { p <- processEvent(ctx, id, event) }()
Example 2 - Cancellable Request – Get and Handle Context
17
package processor
func Server(ctx context.Context, event *event.Event) error { if id, ok := util.FromContext(ctx); !ok { return errors.New(“Not a valid ID to process”) } p := make(chan error, 1) go func(ctx context.Context, id int, event *event.Event) { p <- processEvent(ctx, id, event) }()
Example 2 - Cancellable Request – Get and Handle Context
18
//continued select { case <-ctx.Done(): //… return ctx.Err() case err := <-p return err }}
Example 2 - Cancellable Request – Get and Handle Context
19
1. Ease of handling multiple, concurrent requests
Summary -
Use Cases In Distributed
System
2. Flow Traceability and Fingerprinting
3. Time Sensitive and Cancellable Request Processing
4. Ease of sending context information
20
Remember!
21
Remember… For larger systems, complexity is the downside
Code Complexity:
22
Difficult to actually implement passing cancellable signals downstream
Inter-Process Boundaries: Remember…
23
Don’t store context variables inside structures
Garbage Collection: Remember…
24
Holding the right context nodeQuerying:
Remember…