MCPcopy
hub / github.com/keploy/keploy / GetMockErrors

Method GetMockErrors

pkg/agent/proxy/proxy.go:2921–3033  ·  view source on GitHub ↗

GetMockErrors drains all mock-not-found errors and returns them. When StartErrorDrain is active, it reads from the test accumulator instead of the channel (which is drained by the background goroutine).

(_ context.Context)

Source from the content-addressed store, hash-verified

2919// When StartErrorDrain is active, it reads from the test accumulator instead
2920// of the channel (which is drained by the background goroutine).
2921func (p *Proxy) GetMockErrors(_ context.Context) ([]models.UnmatchedCall, error) {
2922 // Rendezvous with the drain goroutine BEFORE taking captureMu: push a flush
2923 // marker and wait until the goroutine pulls it. FIFO ordering then
2924 // guarantees every error the goroutine had already received from errChannel
2925 // has been routed into the window — so closing the window below cannot
2926 // strand an in-flight miss (the remaining race the previous fix left open).
2927 // The app has already responded by now, so this test's pushes precede the
2928 // marker. A bounded wait keeps a stalled drain from blocking replay.
2929 rendezvousOK := false
2930 drainActive := p.errDrainActive.Load()
2931 if drainActive && p.errChannel != nil {
2932 marker := &flushMarker{done: make(chan struct{})}
2933 select {
2934 case p.errChannel <- marker:
2935 select {
2936 case <-marker.done:
2937 rendezvousOK = true
2938 case <-time.After(2 * time.Second):
2939 // drain stalled — DON'T close the window below (see end).
2940 }
2941 default:
2942 // errChannel full (drain is behind) — marker not enqueued; DON'T
2943 // close the window below.
2944 }
2945 }
2946
2947 p.captureMu.Lock()
2948
2949 // Pre-window stragglers (retained before the first capture window — e.g.
2950 // startup traffic). Oldest first.
2951 rawErrs := p.pendingMockErrors.drain()
2952
2953 // Legacy path only (no drain goroutine): errors sit unrouted in errChannel,
2954 // so sweep them here. With the drain goroutine active, the rendezvous above
2955 // has already routed everything into the window, so sweeping is unnecessary
2956 // and would only risk pulling a NEXT test's stray error into this one.
2957 if !drainActive {
2958 drainLoop:
2959 for {
2960 select {
2961 case err, ok := <-p.errChannel:
2962 if !ok {
2963 break drainLoop
2964 }
2965 if m, isMarker := err.(*flushMarker); isMarker {
2966 close(m.done)
2967 continue
2968 }
2969 rawErrs = append(rawErrs, err)
2970 default:
2971 break drainLoop
2972 }
2973 }
2974 }
2975
2976 if rendezvousOK || !drainActive {
2977 // Safe to END the window: the rendezvous confirmed every received error
2978 // is routed (or there's no drain goroutine). Swap to nil so the drain

Implementers 1

Proxypkg/agent/proxy/proxy.go

Calls 4

SwapMethod · 0.80
LoadMethod · 0.65
drainMethod · 0.45
ErrorMethod · 0.45