1
Go’s Context Library
By:
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 E
RPC 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
C
With
Cancel
B
With
Value
D
With
Timeout
E
With
Value
F
With
Value
G
With
Value
11
H
With
Value
I
With
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 node
Querying:
Remember…
25
Thank you!
For any queries:
Smita Vijayakumar smita@exotel.in

#Gophercon Talk by Smita Vijayakumar - Go's Context Library

  • 1.
  • 2.
    Agenda Introduction -Context Management in DistributedSystems Go’s Context Library Example Use case Points to Watch Out For 2 1 2 3 4
  • 3.
  • 4.
  • 5.
    Request Processing A BC 5 D E RPC RPC RPC RPC
  • 6.
    6 Go Context • Defines*Context* type • Carries request-scoped values: - Deadlines - Cancellation signals - Others • Works across API boundaries - Also between processes
  • 7.
    7 Details type Context interface{ Done() <-chan struct{}
 Err() error
 Deadline() (deadline time.Time, ok bool)
 Value(key interface{}) interface{}
 }
  • 8.
    8 1. Distributed Tracing 2.Request Cancellation 3. Context value Primary Use Cases
  • 9.
    9 struct ContextValue { requestIDstring } Example 1 - Distributed Tracing
  • 10.
    10 Types of Context Nodes 1.Background Node 2. Value Node 3. Cancellable Node 4. TODO() Node
  • 11.
    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 C With Cancel B With Value D With Timeout E With Value F With Value G With Value 11 H With Value I With Value J Types - A Context Tree
  • 12.
    12 package userid const ctxKeystring = “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.
    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.
    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.
    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.
    16 package processor func Server(ctxcontext.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.
    17 package processor func Server(ctxcontext.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.
    18 //continued select { case <-ctx.Done(): //… returnctx.Err() case err := <-p return err } } Example 2 - Cancellable Request – Get and Handle Context
  • 19.
    19 1. Ease ofhandling 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.
  • 21.
    21 Remember… For largersystems, complexity is the downside Code Complexity:
  • 22.
    22 Difficult to actuallyimplement passing cancellable signals downstream Inter-Process Boundaries: Remember…
  • 23.
    23 Don’t store contextvariables inside structures Garbage Collection: Remember…
  • 24.
    24 Holding the rightcontext node Querying: Remember…
  • 25.
    25 Thank you! For anyqueries: Smita Vijayakumar [email protected]