github.com/99designs/gqlgen@v0.17.45/graphql/stats.go (about) 1 package graphql 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 ) 8 9 type Stats struct { 10 OperationStart time.Time 11 Read TraceTiming 12 Parsing TraceTiming 13 Validation TraceTiming 14 15 // Stats collected by handler extensions. Don't use directly, the extension should provide a type safe way to 16 // access this. 17 extension map[string]interface{} 18 } 19 20 type TraceTiming struct { 21 Start time.Time 22 End time.Time 23 } 24 25 var ctxTraceStart key = "trace_start" 26 27 // StartOperationTrace captures the current time and stores it in context. This will eventually be added to request 28 // context but we want to grab it as soon as possible. For transports that can only handle a single graphql query 29 // per http requests you don't need to call this at all, the server will do it for you. For transports that handle 30 // multiple (eg batching, subscriptions) this should be called before decoding each request. 31 func StartOperationTrace(ctx context.Context) context.Context { 32 return context.WithValue(ctx, ctxTraceStart, Now()) 33 } 34 35 // GetStartTime should only be called by the handler package, it will be set into request context 36 // as Stats.Start 37 func GetStartTime(ctx context.Context) time.Time { 38 t, ok := ctx.Value(ctxTraceStart).(time.Time) 39 if !ok { 40 panic(fmt.Sprintf("missing start time: %T", ctx.Value(ctxTraceStart))) 41 } 42 return t 43 } 44 45 func (c *Stats) SetExtension(name string, data interface{}) { 46 if c.extension == nil { 47 c.extension = map[string]interface{}{} 48 } 49 c.extension[name] = data 50 } 51 52 func (c *Stats) GetExtension(name string) interface{} { 53 if c.extension == nil { 54 return nil 55 } 56 return c.extension[name] 57 } 58 59 // Now is time.Now, except in tests. Then it can be whatever you want it to be. 60 var Now = time.Now