mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-10 18:34:18 +08:00
124 lines
3.2 KiB
Diff
124 lines
3.2 KiB
Diff
From f178e9542a7effb74e8feb8b535197b3131ff05a Mon Sep 17 00:00:00 2001
|
|
From: sbwml <admin@cooluc.com>
|
|
Date: Thu, 3 Sep 2026 22:42:53 +0800
|
|
Subject: [PATCH 3/3] fix(fallback): preserve upstream and query context
|
|
metadata from winning branch
|
|
|
|
Signed-off-by: sbwml <admin@cooluc.com>
|
|
---
|
|
pkg/query_context/context.go | 41 +++++++++++++++++++
|
|
.../executable/sequence/fallback/fallback.go | 22 +++++++---
|
|
2 files changed, 57 insertions(+), 6 deletions(-)
|
|
|
|
--- a/pkg/query_context/context.go
|
|
+++ b/pkg/query_context/context.go
|
|
@@ -253,6 +253,15 @@ func (ctx *Context) CopyTo(d *Context) *
|
|
}
|
|
d.upstreamOpt = ctx.upstreamOpt
|
|
|
|
+ if ctx.UpstreamSelected != nil {
|
|
+ u := *ctx.UpstreamSelected
|
|
+ d.UpstreamSelected = &u
|
|
+ }
|
|
+ if len(ctx.RuleHits) > 0 {
|
|
+ d.RuleHits = make([]RuleHit, len(ctx.RuleHits))
|
|
+ copy(d.RuleHits, ctx.RuleHits)
|
|
+ }
|
|
+ d.CacheState = ctx.CacheState
|
|
d.FromHosts = ctx.FromHosts
|
|
d.FromArbitrary = ctx.FromArbitrary
|
|
|
|
@@ -261,6 +270,38 @@ func (ctx *Context) CopyTo(d *Context) *
|
|
return d
|
|
}
|
|
|
|
+// CopyMetadataFrom copies execution metadata and log details from src Context.
|
|
+func (ctx *Context) CopyMetadataFrom(src *Context) {
|
|
+ if src == nil {
|
|
+ return
|
|
+ }
|
|
+ ctx.upstreamOpt = src.upstreamOpt
|
|
+ ctx.UpstreamSelected = src.UpstreamSelected
|
|
+ if len(src.RuleHits) > 0 {
|
|
+ ctx.RuleHits = src.RuleHits
|
|
+ }
|
|
+ ctx.CacheState = src.CacheState
|
|
+ ctx.FromHosts = src.FromHosts
|
|
+ ctx.FromArbitrary = src.FromArbitrary
|
|
+
|
|
+ if src.marks != nil {
|
|
+ if ctx.marks == nil {
|
|
+ ctx.marks = make(map[uint32]struct{})
|
|
+ }
|
|
+ for k, v := range src.marks {
|
|
+ ctx.marks[k] = v
|
|
+ }
|
|
+ }
|
|
+ if src.kv != nil {
|
|
+ if ctx.kv == nil {
|
|
+ ctx.kv = make(map[uint32]any)
|
|
+ }
|
|
+ for k, v := range src.kv {
|
|
+ ctx.kv[k] = v
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
// StoreValue stores any v in to this Context
|
|
// k MUST from RegKey.
|
|
func (ctx *Context) StoreValue(k uint32, v any) {
|
|
--- a/plugin/executable/sequence/fallback/fallback.go
|
|
+++ b/plugin/executable/sequence/fallback/fallback.go
|
|
@@ -107,8 +107,13 @@ func (f *fallback) Exec(ctx context.Cont
|
|
return f.doFallback(ctx, qCtx)
|
|
}
|
|
|
|
+type fallbackResult struct {
|
|
+ r *dns.Msg
|
|
+ qCtx *query_context.Context
|
|
+}
|
|
+
|
|
func (f *fallback) doFallback(ctx context.Context, qCtx *query_context.Context) error {
|
|
- respChan := make(chan *dns.Msg, 2) // resp could be nil.
|
|
+ respChan := make(chan *fallbackResult, 2) // resp could be nil.
|
|
primFailed := make(chan struct{})
|
|
primDone := make(chan struct{})
|
|
|
|
@@ -129,7 +134,7 @@ func (f *fallback) doFallback(ctx contex
|
|
respChan <- nil
|
|
} else {
|
|
close(primDone)
|
|
- respChan <- r
|
|
+ respChan <- &fallbackResult{r: r, qCtx: qCtx}
|
|
}
|
|
}()
|
|
|
|
@@ -167,18 +172,23 @@ func (f *fallback) doFallback(ctx contex
|
|
case <-timer.C: // or timed out.
|
|
}
|
|
}
|
|
- respChan <- r
|
|
+ if r == nil {
|
|
+ respChan <- nil
|
|
+ } else {
|
|
+ respChan <- &fallbackResult{r: r, qCtx: qCtx}
|
|
+ }
|
|
}()
|
|
|
|
for i := 0; i < 2; i++ {
|
|
select {
|
|
case <-ctx.Done():
|
|
return context.Cause(ctx)
|
|
- case r := <-respChan:
|
|
- if r == nil { // One of goroutines finished but failed.
|
|
+ case res := <-respChan:
|
|
+ if res == nil || res.r == nil { // One of goroutines finished but failed.
|
|
continue
|
|
}
|
|
- qCtx.SetResponse(r)
|
|
+ qCtx.SetResponse(res.r)
|
|
+ qCtx.CopyMetadataFrom(res.qCtx)
|
|
return nil
|
|
}
|
|
}
|