summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--constants/constants.go9
-rw-r--r--lgc/lgc.go269
-rw-r--r--networkQuality.go69
-rw-r--r--timeoutat/timeoutat.go9
-rw-r--r--traceable/traceable.go56
-rw-r--r--utilities/utilities.go23
6 files changed, 243 insertions, 192 deletions
diff --git a/constants/constants.go b/constants/constants.go
index 02038a3..1a060dd 100644
--- a/constants/constants.go
+++ b/constants/constants.go
@@ -31,12 +31,3 @@ var (
// The default URL for the config host.
DefaultConfigHost string = "networkquality.example.com"
)
-
-type DebugLevel int8
-
-const (
- NoDebug DebugLevel = iota
- Debug
- Warn
- Error
-)
diff --git a/lgc/lgc.go b/lgc/lgc.go
index 5cf6078..76cf61e 100644
--- a/lgc/lgc.go
+++ b/lgc/lgc.go
@@ -25,7 +25,8 @@ import (
"sync/atomic"
"time"
- "github.com/network-quality/goresponsiveness/constants"
+ "github.com/network-quality/goresponsiveness/debug"
+ "github.com/network-quality/goresponsiveness/traceable"
"github.com/network-quality/goresponsiveness/utilities"
"golang.org/x/net/http2"
)
@@ -38,7 +39,7 @@ var GenerateConnectionId func() uint64 = func() func() uint64 {
}()
type LoadGeneratingConnection interface {
- Start(context.Context, constants.DebugLevel) bool
+ Start(context.Context, debug.DebugLevel) bool
Transferred() uint64
Client() *http.Client
IsValid() bool
@@ -51,12 +52,13 @@ type LoadGeneratingConnectionStats struct {
connInfo httptrace.GotConnInfo
httpInfo httptrace.WroteRequestInfo
tlsConnInfo tls.ConnectionState
+ connectDoneError error
dnsStartTime time.Time
- dnsCompleteTime time.Time
+ dnsDoneTime time.Time
tlsStartTime time.Time
tlsCompleteTime time.Time
connectStartTime time.Time
- connectCompleteTime time.Time
+ connectDoneTime time.Time
getConnectionStartTime time.Time
getConnectionCompleteTime time.Time
}
@@ -65,7 +67,7 @@ type LoadGeneratingConnectionDownload struct {
Path string
downloaded uint64
client *http.Client
- debug constants.DebugLevel
+ debug debug.DebugLevel
valid bool
KeyLogger io.Writer
clientId uint64
@@ -73,110 +75,135 @@ type LoadGeneratingConnectionDownload struct {
stats LoadGeneratingConnectionStats
}
-func generateHttpTimingTracer(
- lgd *LoadGeneratingConnectionDownload,
-) *httptrace.ClientTrace {
- newTracer := httptrace.ClientTrace{
- DNSStart: func(dnsStartInfo httptrace.DNSStartInfo) {
- lgd.stats.dnsStartTime = time.Now()
- lgd.stats.dnsStart = dnsStartInfo
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "DNS Start for %v: %v\n",
- lgd.ClientId(),
- dnsStartInfo,
- )
- }
- },
- DNSDone: func(dnsDoneInfo httptrace.DNSDoneInfo) {
- lgd.stats.dnsCompleteTime = time.Now()
- lgd.stats.dnsDone = dnsDoneInfo
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf("DNS Done for %v: %v\n", lgd.ClientId(), dnsDoneInfo)
- }
- },
- ConnectStart: func(network, address string) {
- lgd.stats.connectStartTime = time.Now()
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "TCP Start of %v: %v: %v\n",
- lgd.ClientId(),
- network,
- address,
- )
- }
- },
- ConnectDone: func(network, address string, err error) {
- lgd.stats.connectCompleteTime = time.Now()
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "TCP Done for %v: %v: %v (%v)\n",
- lgd.ClientId(),
- network,
- address,
- err,
- )
- }
- },
- GetConn: func(hostPort string) {
- lgd.stats.getConnectionStartTime = time.Now()
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "GetConn host port for %v: %v\n",
- lgd.ClientId(),
- hostPort,
- )
- }
- },
- GotConn: func(connInfo httptrace.GotConnInfo) {
- if connInfo.Reused {
- panic(!connInfo.Reused)
- }
- lgd.stats.connInfo = connInfo
- lgd.stats.getConnectionCompleteTime = time.Now()
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "GetConn host port for %v: %v\n",
- lgd.ClientId(),
- connInfo,
- )
- }
- },
- TLSHandshakeStart: func() {
- lgd.stats.tlsStartTime = time.Now()
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf("TLSHandshakeStart for %v\n", lgd.ClientId())
- }
- },
- TLSHandshakeDone: func(tlsConnState tls.ConnectionState, err error) {
- lgd.stats.tlsCompleteTime = time.Now()
- lgd.stats.tlsConnInfo = tlsConnState
- if utilities.IsDebug(lgd.debug) {
- fmt.Printf(
- "TLSHandshakeDone for %v: %v\n",
- lgd.ClientId(),
- tlsConnState,
- )
- }
- },
+func (lgd *LoadGeneratingConnectionDownload) SetDnsStartTimeInfo(
+ now time.Time,
+ dnsStartInfo httptrace.DNSStartInfo,
+) {
+ lgd.stats.dnsStartTime = now
+ lgd.stats.dnsStart = dnsStartInfo
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "DNS Start for %v: %v\n",
+ lgd.ClientId(),
+ dnsStartInfo,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetDnsDoneTimeInfo(
+ now time.Time,
+ dnsDoneInfo httptrace.DNSDoneInfo,
+) {
+ lgd.stats.dnsDoneTime = now
+ lgd.stats.dnsDone = dnsDoneInfo
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "DNS Done for %v: %v\n",
+ lgd.ClientId(),
+ lgd.stats.dnsDone,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetConnectStartTime(
+ now time.Time,
+) {
+ lgd.stats.connectStartTime = now
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "TCP Start for %v at %v\n",
+ lgd.ClientId(),
+ lgd.stats.connectStartTime,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetConnectDoneTimeError(
+ now time.Time,
+ err error,
+) {
+ lgd.stats.connectDoneTime = now
+ lgd.stats.connectDoneError = err
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "TCP Done for %v (with error %v) @ %v\n",
+ lgd.ClientId(),
+ lgd.stats.connectDoneError,
+ lgd.stats.connectDoneTime,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetGetConnTime(now time.Time) {
+ lgd.stats.getConnectionStartTime = now
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "Started getting connection for %v @ %v\n",
+ lgd.ClientId(),
+ lgd.stats.getConnectionStartTime,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetGotConnTimeInfo(
+ now time.Time,
+ gotConnInfo httptrace.GotConnInfo,
+) {
+ lgd.stats.getConnectionCompleteTime = now
+ lgd.stats.connInfo = gotConnInfo
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "Got connection for %v at %v with info %v\n",
+ lgd.ClientId(),
+ lgd.stats.getConnectionCompleteTime,
+ lgd.stats.connInfo,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetTLSHandshakeStartTime(
+ now time.Time,
+) {
+ lgd.stats.tlsStartTime = now
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "Started TLS Handshake for %v @ %v\n",
+ lgd.ClientId(),
+ lgd.stats.tlsStartTime,
+ )
+ }
+}
+
+func (lgd *LoadGeneratingConnectionDownload) SetTLSHandshakeDoneTimeState(
+ now time.Time,
+ connectionState tls.ConnectionState,
+) {
+ lgd.stats.tlsCompleteTime = now
+ lgd.stats.tlsConnInfo = connectionState
+ if debug.IsDebug(lgd.debug) {
+ fmt.Printf(
+ "Completed TLS handshake for %v at %v with info %v\n",
+ lgd.ClientId(),
+ lgd.stats.tlsCompleteTime,
+ lgd.stats.tlsConnInfo,
+ )
}
- return &newTracer
}
-func (lbd *LoadGeneratingConnectionDownload) ClientId() uint64 {
- return lbd.clientId
+func (lgd *LoadGeneratingConnectionDownload) ClientId() uint64 {
+ return lgd.clientId
}
-func (lbd *LoadGeneratingConnectionDownload) Transferred() uint64 {
- transferred := atomic.LoadUint64(&lbd.downloaded)
- if utilities.IsDebug(lbd.debug) {
+func (lgd *LoadGeneratingConnectionDownload) Transferred() uint64 {
+ transferred := atomic.LoadUint64(&lgd.downloaded)
+ if debug.IsDebug(lgd.debug) {
fmt.Printf("download: Transferred: %v\n", transferred)
}
return transferred
}
-func (lbd *LoadGeneratingConnectionDownload) Client() *http.Client {
- return lbd.client
+func (lgd *LoadGeneratingConnectionDownload) Client() *http.Client {
+ return lgd.client
}
type countingReader struct {
@@ -194,17 +221,17 @@ func (cr *countingReader) Read(p []byte) (n int, err error) {
return
}
-func (lbd *LoadGeneratingConnectionDownload) Start(
+func (lgd *LoadGeneratingConnectionDownload) Start(
ctx context.Context,
- debug constants.DebugLevel,
+ debugLevel debug.DebugLevel,
) bool {
- lbd.downloaded = 0
- lbd.clientId = GenerateConnectionId()
+ lgd.downloaded = 0
+ lgd.clientId = GenerateConnectionId()
transport := http2.Transport{}
transport.TLSClientConfig = &tls.Config{}
- if !utilities.IsInterfaceNil(lbd.KeyLogger) {
- if utilities.IsDebug(lbd.debug) {
+ if !utilities.IsInterfaceNil(lgd.KeyLogger) {
+ if debug.IsDebug(lgd.debug) {
fmt.Printf(
"Using an SSL Key Logger for this load-generating download.\n",
)
@@ -217,22 +244,22 @@ func (lbd *LoadGeneratingConnectionDownload) Start(
// depend on whether the url contains
// https:// or http://:
// https://github.com/golang/go/blob/7ca6902c171b336d98adbb103d701a013229c806/src/net/http/transport.go#L74
- transport.TLSClientConfig.KeyLogWriter = lbd.KeyLogger
+ transport.TLSClientConfig.KeyLogWriter = lgd.KeyLogger
}
transport.TLSClientConfig.InsecureSkipVerify = true
- lbd.client = &http.Client{Transport: &transport}
- lbd.debug = debug
- lbd.valid = true
- lbd.tracer = generateHttpTimingTracer(lbd)
+ lgd.client = &http.Client{Transport: &transport}
+ lgd.debug = debugLevel
+ lgd.valid = true
+ lgd.tracer = traceable.GenerateHttpTimingTracer(lgd, lgd.debug)
- if utilities.IsDebug(debug) {
+ if debug.IsDebug(lgd.debug) {
fmt.Printf(
"Started a load-generating download (id: %v).\n",
- lbd.clientId,
+ lgd.clientId,
)
}
- go lbd.doDownload(ctx)
+ go lgd.doDownload(ctx)
return true
}
func (lbd *LoadGeneratingConnectionDownload) IsValid() bool {
@@ -261,7 +288,7 @@ func (lbd *LoadGeneratingConnectionDownload) doDownload(ctx context.Context) {
cr := &countingReader{n: &lbd.downloaded, ctx: ctx, readable: get.Body}
_, _ = io.Copy(ioutil.Discard, cr)
get.Body.Close()
- if utilities.IsDebug(lbd.debug) {
+ if debug.IsDebug(lbd.debug) {
fmt.Printf("Ending a load-generating download.\n")
}
}
@@ -270,7 +297,7 @@ type LoadGeneratingConnectionUpload struct {
Path string
uploaded uint64
client *http.Client
- debug constants.DebugLevel
+ debug debug.DebugLevel
valid bool
KeyLogger io.Writer
clientId uint64
@@ -282,7 +309,7 @@ func (lbu *LoadGeneratingConnectionUpload) ClientId() uint64 {
func (lbu *LoadGeneratingConnectionUpload) Transferred() uint64 {
transferred := atomic.LoadUint64(&lbu.uploaded)
- if utilities.IsDebug(lbu.debug) {
+ if debug.IsDebug(lbu.debug) {
fmt.Printf("upload: Transferred: %v\n", transferred)
}
return transferred
@@ -323,7 +350,7 @@ func (lbu *LoadGeneratingConnectionUpload) doUpload(ctx context.Context) bool {
return false
}
resp.Body.Close()
- if utilities.IsDebug(lbu.debug) {
+ if debug.IsDebug(lbu.debug) {
fmt.Printf("Ending a load-generating upload.\n")
}
return true
@@ -331,10 +358,11 @@ func (lbu *LoadGeneratingConnectionUpload) doUpload(ctx context.Context) bool {
func (lbu *LoadGeneratingConnectionUpload) Start(
ctx context.Context,
- debug constants.DebugLevel,
+ debugLevel debug.DebugLevel,
) bool {
lbu.uploaded = 0
lbu.clientId = GenerateConnectionId()
+ lbu.debug = debugLevel
// See above for the rationale of doing http2.Transport{} here
// to ensure that we are using h2.
@@ -342,7 +370,7 @@ func (lbu *LoadGeneratingConnectionUpload) Start(
transport.TLSClientConfig = &tls.Config{}
if !utilities.IsInterfaceNil(lbu.KeyLogger) {
- if utilities.IsDebug(lbu.debug) {
+ if debug.IsDebug(lbu.debug) {
fmt.Printf(
"Using an SSL Key Logger for this load-generating upload.\n",
)
@@ -352,10 +380,9 @@ func (lbu *LoadGeneratingConnectionUpload) Start(
transport.TLSClientConfig.InsecureSkipVerify = true
lbu.client = &http.Client{Transport: &transport}
- lbu.debug = debug
lbu.valid = true
- if utilities.IsDebug(lbu.debug) {
+ if debug.IsDebug(lbu.debug) {
fmt.Printf("Started a load-generating upload (id: %v).\n", lbu.clientId)
}
go lbu.doUpload(ctx)
diff --git a/networkQuality.go b/networkQuality.go
index a7c7756..986ed36 100644
--- a/networkQuality.go
+++ b/networkQuality.go
@@ -33,6 +33,7 @@ import (
"github.com/network-quality/goresponsiveness/ccw"
"github.com/network-quality/goresponsiveness/constants"
+ "github.com/network-quality/goresponsiveness/debug"
"github.com/network-quality/goresponsiveness/lgc"
"github.com/network-quality/goresponsiveness/ma"
"github.com/network-quality/goresponsiveness/timeoutat"
@@ -205,7 +206,7 @@ func addFlows(
lgcs *[]lgc.LoadGeneratingConnection,
lgcsPreviousTransferred *[]uint64,
lgcGenerator func() lgc.LoadGeneratingConnection,
- debug constants.DebugLevel,
+ debug debug.DebugLevel,
) {
for i := uint64(0); i < toAdd; i++ {
*lgcs = append(*lgcs, lgcGenerator())
@@ -226,11 +227,11 @@ type SaturationResult struct {
}
type Debugging struct {
- Level constants.DebugLevel
+ Level debug.DebugLevel
Prefix string
}
-func NewDebugging(level constants.DebugLevel, prefix string) *Debugging {
+func NewDebugging(level debug.DebugLevel, prefix string) *Debugging {
return &Debugging{Level: level, Prefix: prefix}
}
@@ -242,7 +243,7 @@ func saturate(
saturationCtx context.Context,
operatingCtx context.Context,
lgcGenerator func() lgc.LoadGeneratingConnection,
- debug *Debugging,
+ debugging *Debugging,
) (saturated chan SaturationResult) {
saturated = make(chan SaturationResult)
go func() {
@@ -256,7 +257,7 @@ func saturate(
&lgcs,
&lgcsPreviousTransferred,
lgcGenerator,
- debug.Level,
+ debugging.Level,
)
previousFlowIncreaseIteration := uint64(0)
@@ -286,10 +287,10 @@ func saturate(
now := time.Now()
// At each 1-second interval
if nextSampleStartTime.Sub(now) > 0 {
- if utilities.IsDebug(debug.Level) {
+ if debug.IsDebug(debugging.Level) {
fmt.Printf(
"%v: Sleeping until %v\n",
- debug,
+ debugging,
nextSampleStartTime,
)
}
@@ -305,10 +306,10 @@ func saturate(
allInvalid := true
for i := range lgcs {
if !lgcs[i].IsValid() {
- if utilities.IsDebug(debug.Level) {
+ if debug.IsDebug(debugging.Level) {
fmt.Printf(
"%v: Load-generating connection with id %d is invalid ... skipping.\n",
- debug,
+ debugging,
lgcs[i].ClientId(),
)
}
@@ -324,10 +325,10 @@ func saturate(
// For some reason, all the lgcs are invalid. This likely means that
// the network/server went away.
if allInvalid {
- if utilities.IsDebug(debug.Level) {
+ if debug.IsDebug(debugging.Level) {
fmt.Printf(
"%v: All lgcs were invalid. Assuming that network/server went away.\n",
- debug,
+ debugging,
)
}
break
@@ -344,25 +345,25 @@ func saturate(
previousMovingAverage,
)
- if utilities.IsDebug(debug.Level) {
+ if debug.IsDebug(debugging.Level) {
fmt.Printf(
"%v: Instantaneous goodput: %f MB.\n",
- debug,
+ debugging,
utilities.ToMBps(float64(totalTransfer)),
)
fmt.Printf(
"%v: Previous moving average: %f MB.\n",
- debug,
+ debugging,
utilities.ToMBps(previousMovingAverage),
)
fmt.Printf(
"%v: Current moving average: %f MB.\n",
- debug,
+ debugging,
utilities.ToMBps(currentMovingAverage),
)
fmt.Printf(
"%v: Moving average delta: %f.\n",
- debug,
+ debugging,
movingAverageDelta,
)
}
@@ -382,10 +383,10 @@ func saturate(
if (currentIteration - previousFlowIncreaseIteration) > uint64(
constants.MovingAverageStabilitySpan,
) {
- if utilities.IsDebug(debug.Level) {
+ if debug.IsDebug(debugging.Level) {
fmt.Printf(
"%v: Adding flows because we are unsaturated and waited a while.\n",
- debug,
+ debugging,
)
}
addFlows(
@@ -394,31 +395,31 @@ func saturate(
&lgcs,
&lgcsPreviousTransferred,
lgcGenerator,
- debug.Level,
+ debugging.Level,
)
previousFlowIncreaseIteration = currentIteration
} else {
- if utilities.IsDebug(debug.Level) {
- fmt.Printf("%v: We are unsaturated, but it still too early to add anything.\n", debug)
+ if debug.IsDebug(debugging.Level) {
+ fmt.Printf("%v: We are unsaturated, but it still too early to add anything.\n", debugging)
}
}
} else { // Else, network reached saturation for the current flow count.
- if utilities.IsDebug(debug.Level) {
- fmt.Printf("%v: Network reached saturation with current flow count.\n", debug)
+ if debug.IsDebug(debugging.Level) {
+ fmt.Printf("%v: Network reached saturation with current flow count.\n", debugging)
}
// If new flows added and for 4 seconds the moving average
// throughput did not change: network reached stable saturation
if (currentIteration-previousFlowIncreaseIteration) < uint64(constants.MovingAverageStabilitySpan) && movingAverageAverage.AllSequentialIncreasesLessThan(float64(5)) {
- if utilities.IsDebug(debug.Level) {
- fmt.Printf("%v: New flows added within the last four seconds and the moving-average average is consistent!\n", debug)
+ if debug.IsDebug(debugging.Level) {
+ fmt.Printf("%v: New flows added within the last four seconds and the moving-average average is consistent!\n", debugging)
}
break
} else {
// Else, add four more flows
- if utilities.IsDebug(debug.Level) {
- fmt.Printf("%v: New flows to add to try to increase our saturation!\n", debug)
+ if debug.IsDebug(debugging.Level) {
+ fmt.Printf("%v: New flows to add to try to increase our saturation!\n", debugging)
}
- addFlows(saturationCtx, constants.AdditiveNumberOfLoadGeneratingConnections, &lgcs, &lgcsPreviousTransferred, lgcGenerator, debug.Level)
+ addFlows(saturationCtx, constants.AdditiveNumberOfLoadGeneratingConnections, &lgcs, &lgcsPreviousTransferred, lgcGenerator, debugging.Level)
previousFlowIncreaseIteration = currentIteration
}
}
@@ -440,10 +441,10 @@ func main() {
context.Background(),
)
config := &Config{}
- var debugLevel constants.DebugLevel = constants.Error
+ var debugLevel debug.DebugLevel = debug.Error
if *debugCliFlag {
- debugLevel = constants.Debug
+ debugLevel = debug.Debug
}
if err := config.Get(configHostPort, *configPath); err != nil {
@@ -459,7 +460,7 @@ func main() {
)
return
}
- if utilities.IsDebug(debugLevel) {
+ if debug.IsDebug(debugLevel) {
fmt.Printf("Configuration: %s\n", config)
}
@@ -468,7 +469,7 @@ func main() {
timeoutAbsoluteTime,
debugLevel,
)
- if utilities.IsDebug(debugLevel) {
+ if debug.IsDebug(debugLevel) {
fmt.Printf("Test will end earlier than %v\n", timeoutAbsoluteTime)
}
@@ -505,7 +506,7 @@ func main() {
fmt.Printf("Could not seek to the end of the key file: %v!\n", err)
sslKeyFileConcurrentWriter = nil
} else {
- if utilities.IsDebug(debugLevel) {
+ if debug.IsDebug(debugLevel) {
fmt.Printf("Doing SSL key logging through file %v\n", *sslKeyFileName)
}
sslKeyFileConcurrentWriter = ccw.NewConcurrentFileWriter(sslKeyFileHandle)
@@ -529,7 +530,7 @@ func main() {
var downloadDebugging *Debugging = nil
var uploadDebugging *Debugging = nil
- if utilities.IsDebug(debugLevel) {
+ if debug.IsDebug(debugLevel) {
downloadDebugging = &Debugging{Prefix: "download"}
uploadDebugging = &Debugging{Prefix: "upload"}
}
diff --git a/timeoutat/timeoutat.go b/timeoutat/timeoutat.go
index eac57f2..673ca38 100644
--- a/timeoutat/timeoutat.go
+++ b/timeoutat/timeoutat.go
@@ -19,19 +19,18 @@ import (
"fmt"
"time"
- "github.com/network-quality/goresponsiveness/constants"
- "github.com/network-quality/goresponsiveness/utilities"
+ "github.com/network-quality/goresponsiveness/debug"
)
func TimeoutAt(
ctx context.Context,
when time.Time,
- debug constants.DebugLevel,
+ debugLevel debug.DebugLevel,
) (response chan interface{}) {
response = make(chan interface{})
go func(ctx context.Context) {
go func() {
- if utilities.IsDebug(debug) {
+ if debug.IsDebug(debugLevel) {
fmt.Printf("Timeout expected to end at %v\n", when)
}
select {
@@ -39,7 +38,7 @@ func TimeoutAt(
case <-ctx.Done():
}
response <- struct{}{}
- if utilities.IsDebug(debug) {
+ if debug.IsDebug(debugLevel) {
fmt.Printf("Timeout ended at %v\n", time.Now())
}
}()
diff --git a/traceable/traceable.go b/traceable/traceable.go
new file mode 100644
index 0000000..e3f81d5
--- /dev/null
+++ b/traceable/traceable.go
@@ -0,0 +1,56 @@
+package traceable
+
+import (
+ "crypto/tls"
+ "net/http/httptrace"
+ "time"
+
+ "github.com/network-quality/goresponsiveness/debug"
+)
+
+type Traceable interface {
+ SetDnsStartTimeInfo(time.Time, httptrace.DNSStartInfo)
+ SetDnsDoneTimeInfo(time.Time, httptrace.DNSDoneInfo)
+ SetConnectStartTime(time.Time)
+ SetConnectDoneTimeError(time.Time, error)
+ SetGetConnTime(time.Time)
+ SetGotConnTimeInfo(time.Time, httptrace.GotConnInfo)
+ SetTLSHandshakeStartTime(time.Time)
+ SetTLSHandshakeDoneTimeState(time.Time, tls.ConnectionState)
+}
+
+func GenerateHttpTimingTracer(
+ traceable Traceable,
+ debug debug.DebugLevel,
+) *httptrace.ClientTrace {
+ tracer := httptrace.ClientTrace{
+ DNSStart: func(dnsStartInfo httptrace.DNSStartInfo) {
+ traceable.SetDnsStartTimeInfo(time.Now(), dnsStartInfo)
+ },
+ DNSDone: func(dnsDoneInfo httptrace.DNSDoneInfo) {
+ traceable.SetDnsDoneTimeInfo(time.Now(), dnsDoneInfo)
+ },
+ ConnectStart: func(network, address string) {
+ traceable.SetConnectStartTime(time.Now())
+ },
+ ConnectDone: func(network, address string, err error) {
+ traceable.SetConnectDoneTimeError(time.Now(), err)
+ },
+ GetConn: func(hostPort string) {
+ traceable.SetGetConnTime(time.Now())
+ },
+ GotConn: func(connInfo httptrace.GotConnInfo) {
+ if connInfo.Reused {
+ panic(!connInfo.Reused)
+ }
+ traceable.SetGotConnTimeInfo(time.Now(), connInfo)
+ },
+ TLSHandshakeStart: func() {
+ traceable.SetTLSHandshakeStartTime(time.Now())
+ },
+ TLSHandshakeDone: func(tlsConnState tls.ConnectionState, err error) {
+ traceable.SetTLSHandshakeDoneTimeState(time.Now(), tlsConnState)
+ },
+ }
+ return &tracer
+}
diff --git a/utilities/utilities.go b/utilities/utilities.go
index b8e416c..46d5766 100644
--- a/utilities/utilities.go
+++ b/utilities/utilities.go
@@ -22,8 +22,6 @@ import (
"os"
"reflect"
"time"
-
- "github.com/network-quality/goresponsiveness/constants"
)
func IsInterfaceNil(ifc interface{}) bool {
@@ -123,24 +121,3 @@ func SeekForAppend(file *os.File) (err error) {
_, err = file.Seek(0, 2)
return
}
-
-func IsDebug(level constants.DebugLevel) bool {
- if level <= constants.Debug {
- return true
- }
- return false
-}
-
-func IsWarn(level constants.DebugLevel) bool {
- if level <= constants.Warn {
- return true
- }
- return false
-}
-
-func IsError(level constants.DebugLevel) bool {
- if level <= constants.Error {
- return true
- }
- return false
-}