github.com/spread-ai/gqlgen@v0.0.0-20221124102857-a6c8ef538a1d/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. Dont 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 dont 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