File: queuing.go

package info (click to toggle)
golang-github-newrelic-go-agent 3.15.2-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 8,356 kB
  • sloc: sh: 65; makefile: 6
file content (75 lines) | stat: -rw-r--r-- 1,568 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package internal

import (
	"net/http"
	"strconv"
	"strings"
	"time"
)

const (
	xRequestStart = "X-Request-Start"
	xQueueStart   = "X-Queue-Start"
)

var (
	earliestAcceptableSeconds = time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()
	latestAcceptableSeconds   = time.Date(2050, time.January, 1, 0, 0, 0, 0, time.UTC).Unix()
)

func checkQueueTimeSeconds(secondsFloat float64) time.Time {
	seconds := int64(secondsFloat)
	nanos := int64((secondsFloat - float64(seconds)) * (1000.0 * 1000.0 * 1000.0))
	if seconds > earliestAcceptableSeconds && seconds < latestAcceptableSeconds {
		return time.Unix(seconds, nanos)
	}
	return time.Time{}
}

func parseQueueTime(s string) time.Time {
	f, err := strconv.ParseFloat(s, 64)
	if nil != err {
		return time.Time{}
	}
	if f <= 0 {
		return time.Time{}
	}

	// try microseconds
	if t := checkQueueTimeSeconds(f / (1000.0 * 1000.0)); !t.IsZero() {
		return t
	}
	// try milliseconds
	if t := checkQueueTimeSeconds(f / (1000.0)); !t.IsZero() {
		return t
	}
	// try seconds
	if t := checkQueueTimeSeconds(f); !t.IsZero() {
		return t
	}
	return time.Time{}
}

// QueueDuration TODO
func QueueDuration(hdr http.Header, txnStart time.Time) time.Duration {
	s := hdr.Get(xQueueStart)
	if "" == s {
		s = hdr.Get(xRequestStart)
	}
	if "" == s {
		return 0
	}

	s = strings.TrimPrefix(s, "t=")
	qt := parseQueueTime(s)
	if qt.IsZero() {
		return 0
	}
	if qt.After(txnStart) {
		return 0
	}
	return txnStart.Sub(qt)
}