github.com/lulzWill/go-agent@v2.1.2+incompatible/internal/queuing.go (about) 1 package internal 2 3 import ( 4 "net/http" 5 "strconv" 6 "strings" 7 "time" 8 ) 9 10 const ( 11 xRequestStart = "X-Request-Start" 12 xQueueStart = "X-Queue-Start" 13 ) 14 15 var ( 16 earliestAcceptableSeconds = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix() 17 latestAcceptableSeconds = time.Date(2050, time.January, 1, 0, 0, 0, 0, time.UTC).Unix() 18 ) 19 20 func checkQueueTimeSeconds(secondsFloat float64) time.Time { 21 seconds := int64(secondsFloat) 22 nanos := int64((secondsFloat - float64(seconds)) * (1000.0 * 1000.0 * 1000.0)) 23 if seconds > earliestAcceptableSeconds && seconds < latestAcceptableSeconds { 24 return time.Unix(seconds, nanos) 25 } 26 return time.Time{} 27 } 28 29 func parseQueueTime(s string) time.Time { 30 f, err := strconv.ParseFloat(s, 64) 31 if nil != err { 32 return time.Time{} 33 } 34 if f <= 0 { 35 return time.Time{} 36 } 37 38 // try microseconds 39 if t := checkQueueTimeSeconds(f / (1000.0 * 1000.0)); !t.IsZero() { 40 return t 41 } 42 // try milliseconds 43 if t := checkQueueTimeSeconds(f / (1000.0)); !t.IsZero() { 44 return t 45 } 46 // try seconds 47 if t := checkQueueTimeSeconds(f); !t.IsZero() { 48 return t 49 } 50 return time.Time{} 51 } 52 53 // QueueDuration TODO 54 func QueueDuration(hdr http.Header, txnStart time.Time) time.Duration { 55 s := hdr.Get(xQueueStart) 56 if "" == s { 57 s = hdr.Get(xRequestStart) 58 } 59 if "" == s { 60 return 0 61 } 62 63 s = strings.TrimPrefix(s, "t=") 64 qt := parseQueueTime(s) 65 if qt.IsZero() { 66 return 0 67 } 68 if qt.After(txnStart) { 69 return 0 70 } 71 return txnStart.Sub(qt) 72 }