Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
rbarazzutti committed Aug 20, 2023
1 parent 9abac08 commit 2f7e7e1
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 112 deletions.
128 changes: 128 additions & 0 deletions app/measurecontext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright 2022 Raphaël P. Barazzutti
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

package app

import (
"context"
"crypto/tls"
"fever.ch/http-ping/net/sockettrace"
"fever.ch/http-ping/stats"
"net/http/httptrace"
)

type measureContext struct {
timerRegistry *stats.TimerRegistry
webClientImpl *webClientImpl
remoteAddr string
reused bool
}

func newMeasureContext(impl *webClientImpl) *measureContext {
return &measureContext{
timerRegistry: stats.NewTimersCollection(),
webClientImpl: impl,
}
}

func (measureContext *measureContext) getMeasures() *stats.MeasuresCollection {
return measureContext.timerRegistry.Measure()
}

func (measureContext *measureContext) getClientTrace() *httptrace.ClientTrace {

return &httptrace.ClientTrace{
TLSHandshakeStart: func() {
measureContext.timerRegistry.Get(stats.TLS).Start()
},

TLSHandshakeDone: func(state tls.ConnectionState, err error) {
measureContext.timerRegistry.Get(stats.TLS).Stop()
},
DNSStart: func(info httptrace.DNSStartInfo) {
measureContext.timerRegistry.Get(stats.DNS).Start()
},

DNSDone: func(info httptrace.DNSDoneInfo) {
measureContext.timerRegistry.Get(stats.DNS).Stop()
},

GetConn: func(hostPort string) {
measureContext.timerRegistry.Get(stats.Conn).Start()
},

GotConn: func(info httptrace.GotConnInfo) {
measureContext.remoteAddr = info.Conn.RemoteAddr().String()
measureContext.timerRegistry.Get(stats.Conn).Stop()
measureContext.timerRegistry.Get(stats.Req).Start()
measureContext.timerRegistry.Get(stats.ReqAndWait).StartForce()
measureContext.reused = info.Reused
},

WroteRequest: func(info httptrace.WroteRequestInfo) {
measureContext.timerRegistry.Get(stats.Req).Stop()
measureContext.timerRegistry.Get(stats.Wait).Start()
},

GotFirstResponseByte: func() {
measureContext.timerRegistry.Get(stats.Wait).Stop()
measureContext.timerRegistry.Get(stats.ReqAndWait).Stop()

measureContext.timerRegistry.Get(stats.Resp).Start()
},
}

}

func (measureContext *measureContext) getConnTrace() *sockettrace.ConnTrace {
return &sockettrace.ConnTrace{
Read: func(i int) {
measureContext.webClientImpl.reads += int64(i)
},
Write: func(i int) {
measureContext.webClientImpl.writes += int64(i)
},
TCPStart: func() {
measureContext.timerRegistry.Get(stats.TCP).Start()
},
TCPEstablished: func() {
measureContext.timerRegistry.Get(stats.TCP).Stop()
},
}
}

func (measureContext *measureContext) ctx() context.Context {
return httptrace.WithClientTrace(
sockettrace.WithTrace(
context.Background(),
measureContext.getConnTrace()),
measureContext.getClientTrace())
}

func (measureContext *measureContext) start() {
measureContext.timerRegistry.Get(stats.Total).Start()
measureContext.timerRegistry.Get(stats.ReqAndWait).Start() // for HTTP/3 with keep-alive
}

func (measureContext *measureContext) startIngestion() {
measureContext.timerRegistry.Get(stats.ReqAndWait).Stop()
measureContext.timerRegistry.Get(stats.Resp).Start()
}

func (measureContext *measureContext) globalStop() {
measureContext.timerRegistry.Get(stats.Resp).Stop()
measureContext.timerRegistry.Get(stats.Total).Stop()
}
127 changes: 15 additions & 112 deletions app/webclientimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,109 +233,6 @@ func (webClient *webClientImpl) prepareReq(req *http.Request) {

}

type measureContext struct {
timerRegistry *stats.TimerRegistry
webClientImpl *webClientImpl
remoteAddr string
reused bool
}

func newMeasureContext(impl *webClientImpl) *measureContext {
return &measureContext{
timerRegistry: stats.NewTimersCollection(),
webClientImpl: impl,
}
}

func (mc *measureContext) getMeasures() *stats.MeasuresCollection {
return mc.timerRegistry.Measure()
}

func (mc *measureContext) getClientTrace() *httptrace.ClientTrace {

return &httptrace.ClientTrace{
TLSHandshakeStart: func() {
mc.timerRegistry.Get(stats.TLS).Start()
},

TLSHandshakeDone: func(state tls.ConnectionState, err error) {
mc.timerRegistry.Get(stats.TLS).Stop()
},
DNSStart: func(info httptrace.DNSStartInfo) {
mc.timerRegistry.Get(stats.DNS).Start()
},

DNSDone: func(info httptrace.DNSDoneInfo) {
mc.timerRegistry.Get(stats.DNS).Stop()
},

GetConn: func(hostPort string) {
mc.timerRegistry.Get(stats.Conn).Start()
},

GotConn: func(info httptrace.GotConnInfo) {
mc.remoteAddr = info.Conn.RemoteAddr().String()
mc.timerRegistry.Get(stats.Conn).Stop()
mc.timerRegistry.Get(stats.Req).Start()
mc.timerRegistry.Get(stats.ReqAndWait).StartForce()
mc.reused = info.Reused
},

WroteRequest: func(info httptrace.WroteRequestInfo) {
mc.timerRegistry.Get(stats.Req).Stop()
mc.timerRegistry.Get(stats.Wait).Start()
},

GotFirstResponseByte: func() {
mc.timerRegistry.Get(stats.Wait).Stop()
mc.timerRegistry.Get(stats.ReqAndWait).Stop()

mc.timerRegistry.Get(stats.Resp).Start()
},
}

}

func (mc *measureContext) getConnTrace() *sockettrace.ConnTrace {
return &sockettrace.ConnTrace{
Read: func(i int) {
mc.webClientImpl.reads += int64(i)
},
Write: func(i int) {
mc.webClientImpl.writes += int64(i)
},
TCPStart: func() {
mc.timerRegistry.Get(stats.TCP).Start()
},
TCPEstablished: func() {
mc.timerRegistry.Get(stats.TCP).Stop()
},
}
}

func (mc *measureContext) ctx() context.Context {
return httptrace.WithClientTrace(
sockettrace.WithTrace(
context.Background(),
mc.getConnTrace()),
mc.getClientTrace())
}

func (mc *measureContext) start() {
mc.timerRegistry.Get(stats.Total).Start()
mc.timerRegistry.Get(stats.ReqAndWait).Start() // for HTTP/3 with keep-alive
}

func (mc *measureContext) startIngestion() {
mc.timerRegistry.Get(stats.ReqAndWait).Stop()
mc.timerRegistry.Get(stats.Resp).Start()
}

func (mc *measureContext) globalStop() {
mc.timerRegistry.Get(stats.Resp).Stop()
mc.timerRegistry.Get(stats.Total).Stop()
}

// DoMeasure evaluates the latency to a specific HTTP/S server
func (webClient *webClientImpl) DoMeasure(followRedirect bool) *HTTPMeasure {
measureContext := newMeasureContext(webClient)
Expand Down Expand Up @@ -419,15 +316,7 @@ func (webClient *webClientImpl) DoMeasure(followRedirect bool) *HTTPMeasure {
i := atomic.SwapInt64(&webClient.reads, 0)
o := atomic.SwapInt64(&webClient.writes, 0)

var tlsVersion string
if res.TLS != nil {
code := int(res.TLS.Version) - 0x0301
if code >= 0 {
tlsVersion = fmt.Sprintf("TLS-1.%d", code)
} else {
tlsVersion = "SSL-3"
}
}
tlsVersion := extractTlsVersion(res)

var remoteAddr = measureContext.remoteAddr
if remoteAddr == "" {
Expand Down Expand Up @@ -457,6 +346,20 @@ func (webClient *webClientImpl) DoMeasure(followRedirect bool) *HTTPMeasure {

}

func extractTlsVersion(res *http.Response) string {

if res.TLS != nil {
code := int(res.TLS.Version) - 0x0301
if code >= 0 {
return fmt.Sprintf("TLS-1.%d", code)
} else {
return "SSL-3"
}
} else {
return "N/A"
}
}

func (webClient *webClientImpl) moveToHttp3(altSvcH3 string, timerRegistry *stats.TimerRegistry, followRedirect bool) *HTTPMeasure {

if altSvcH3 == ":443" {
Expand Down

0 comments on commit 2f7e7e1

Please sign in to comment.