fix(inbound): defer a local MTProto inbound edit's sidecar push until after commit

UpdateInbound applied a local MTProto inbound change by calling the runtime
UpdateInbound (which stops/starts the mtg sidecar or talks to it) from inside
runSerializedTx. That runs process and network I/O on the single traffic-writer
goroutine while a DB transaction is open, so a slow sidecar stalls traffic
accounting and every concurrent client mutation, and a later step failing the
transaction leaves the sidecar ahead of the rolled-back row. Move the push into
the post-commit hook, matching the xray branch. Adds a SetLocalRuntimeOverride
test seam mirroring the existing node override so the deferral is regression
tested.
This commit is contained in:
MHSanaei
2026-07-15 00:06:53 +02:00
parent 0bbcd2a8f2
commit 781458d878
3 changed files with 79 additions and 6 deletions
+17
View File
@@ -18,6 +18,7 @@ type Manager struct {
mu sync.RWMutex
remotes map[int]*Remote
overrides map[int]Runtime // test-only: forces RuntimeFor to return a stub
localOverride Runtime // test-only: forces RuntimeFor(nil) to return a stub
egressResolver NodeEgressResolver
}
@@ -44,6 +45,15 @@ func (m *Manager) SetRuntimeOverride(nodeID int, rt Runtime) {
m.overrides[nodeID] = rt
}
// SetLocalRuntimeOverride makes RuntimeFor(nil) return rt instead of the real
// local runtime. Test seam for exercising the local dispatch path (MTProto
// sidecar, local Xray) without a running child process; pass nil rt to clear.
func (m *Manager) SetLocalRuntimeOverride(rt Runtime) {
m.mu.Lock()
defer m.mu.Unlock()
m.localOverride = rt
}
func (m *Manager) SetNodeEgressResolver(r NodeEgressResolver) {
m.mu.Lock()
defer m.mu.Unlock()
@@ -61,6 +71,13 @@ func (m *Manager) NodeEgressProxyURL(nodeID int) string {
func (m *Manager) RuntimeFor(nodeID *int) (Runtime, error) {
if nodeID == nil {
m.mu.RLock()
if m.localOverride != nil {
rt := m.localOverride
m.mu.RUnlock()
return rt, nil
}
m.mu.RUnlock()
return m.local, nil
}
m.mu.RLock()