latencytracker.go 1.6 KB
Newer Older
1 2 3 4 5 6 7 8 9
package sessionpeermanager

import (
	"time"

	"github.com/ipfs/go-cid"
)

type requestData struct {
10 11 12
	startedAt    time.Time
	wasCancelled bool
	timeoutFunc  *time.Timer
13 14 15 16 17 18 19 20 21 22 23 24
}

type latencyTracker struct {
	requests map[cid.Cid]*requestData
}

func newLatencyTracker() *latencyTracker {
	return &latencyTracker{requests: make(map[cid.Cid]*requestData)}
}

type afterTimeoutFunc func(cid.Cid)

25
func (lt *latencyTracker) SetupRequests(keys []cid.Cid, timeoutDuration time.Duration, afterTimeout afterTimeoutFunc) {
26 27 28
	startedAt := time.Now()
	for _, k := range keys {
		if _, ok := lt.requests[k]; !ok {
29 30 31 32 33
			lt.requests[k] = &requestData{
				startedAt,
				false,
				time.AfterFunc(timeoutDuration, makeAfterTimeout(afterTimeout, k)),
			}
34 35 36 37 38 39 40 41 42 43 44 45
		}
	}
}

func makeAfterTimeout(afterTimeout afterTimeoutFunc, k cid.Cid) func() {
	return func() { afterTimeout(k) }
}

func (lt *latencyTracker) CheckDuration(key cid.Cid) (time.Duration, bool) {
	request, ok := lt.requests[key]
	var latency time.Duration
	if ok {
Steven Allen's avatar
Steven Allen committed
46
		latency = time.Since(request.startedAt)
47 48 49 50
	}
	return latency, ok
}

51
func (lt *latencyTracker) RemoveRequest(key cid.Cid) {
52 53 54 55 56
	request, ok := lt.requests[key]
	if ok {
		request.timeoutFunc.Stop()
		delete(lt.requests, key)
	}
57 58
}

59 60 61 62 63 64
func (lt *latencyTracker) RecordCancel(keys []cid.Cid) {
	for _, key := range keys {
		request, ok := lt.requests[key]
		if ok {
			request.wasCancelled = true
		}
65 66 67 68 69 70
	}
}

func (lt *latencyTracker) WasCancelled(key cid.Cid) bool {
	request, ok := lt.requests[key]
	return ok && request.wasCancelled
71 72 73 74 75 76 77
}

func (lt *latencyTracker) Shutdown() {
	for _, request := range lt.requests {
		request.timeoutFunc.Stop()
	}
}