jamulussoftware / jamulussoftware/jamulus
Directory re-registration resolves DNS on the thread that runs the mix
- 主要言語
- C
- スター
- 1.1k
- フォーク
- 248
- 平均マージ
- 2日 3時間
- マージ済み PR(30日)
- 9
説明
**🤖 AI:** Every 15 minutes a registered server re-resolves its directory address on the thread that runs the mix, and the mix waits for the resolver.
[`SetRegistered()`](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverlist.cpp#L1015) calls `NetworkUtil::ParseNetworkAddress()` inline, driven by [a `SERVLIST_REGIST_INTERV_MINUTES` = 15 timer](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverlist.cpp#L518). `CServer::OnTimer` is serviced by the same thread — `CHighPrecisionTimer` reaches it [through a queued connection](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/server.cpp#L268) — so no audio is mixed while the resolve is outstanding. [`QHostInfo::fromName`](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/util.cpp#L862) blocks with no timeout of its own and pumps no events. [The SRV attempt before it](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/util.cpp#L908) spins `processEvents` for up to `DNS_SRV_RESOLVE_TIMEOUT_MS` = 500 instead, and the last row below is that spin costing nothing: only `fromName` reaches the mix.
Two servers, one connected client each, registered to a directory answering `SRR_REGISTERED` through a stub resolver with a per-name latency. Each server's own maximum audio-timer lateness, in the record before its re-registration and the record covering it:
| build | resolver latency | that server | the other server, same run |
|---|---:|---|---|
| unpatched | 300 ms | 87.0 -> **303.5 ms** | 218.8 -> 218.8 ms |
| unpatched | 1500 ms | 192.5 -> **1506.5 ms** | 150.5 -> 150.5 ms |
| unpatched | 1500 ms | 115.9 -> **1538.6 ms** | 164.0 -> 164.0 ms |
| patched | 1500 ms | 131.2 -> **131.2 ms** | 144.9 -> 154.0 ms |
| unpatched | SRV timed out at 498 ms, A/AAAA instant | 94.6 -> **94.6 ms** | 145.9 -> 145.9 ms |
The patched build reuses the address resolved earlier for that directory string and refreshes it with an asynchronous `QHostInfo::lookupHost`. It still performed the lookup: the registration went out at 23:14:12.207Z and its answer arrived at 23:14:13.711Z. The first registration after startup still resolves inline, since nothing is cached yet.
In the third row the unstalled server was given `-e :` rather than a hostname, with every name the stub resolver did not recognise also delayed 1500 ms; it registered on its 15-minute schedule and issued no DNS query at all. An address literal is a workaround where the directory address is stable.
The last row used a port-less address, the only form that [reaches the SRV path](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/util.cpp#L889); its own A/AAAA lookup answered instantly, so the 498 ms spent waiting for a deliberately unanswerable SRV record is all that row measures.
The refresh timer is not the only entry to this resolve. On a live server, [`SetDirectoryAddress()`](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverlist.cpp#L364) and [`SetDirectoryType()`](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverlist.cpp#L395) each call `Unregister()` then `Register()` — the old address is resolved, then the new one — reachable mid-session from the server GUI and from [`jamulusserver/setDirectory`](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverrpc.cpp#L257). Measured on a `main` build at this commit (`3.12.5dev-c1ceb104`), reading the server's own outbound packet stream with a client connected, old name at 300 ms and new name at 1500 ms: outbound audio halts for 301.6 ms, the unregister message leaves for the directory, and audio halts again for 1502.5 ms — 1.8 s of mix outage for one settings change. On quit it resolves once more, and [the list manager's handler](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/serverlist.cpp#L330) runs before [the one that tells the clients](https://github.com/jamulussoftware/jamulus/blob/c1ceb1041d29d9dabde3a1ceb2bee4462a0b22ed/src/server.cpp#L317): with a player still connected and `--discononquit` set, SIGTERM stops the mix and the next packet of any kind leaves at +1.506 s on the delayed server against +0.005 s on the control — the directory's unregister and the player's own `CLDisconnection` both waiting behind the resolver. A packet that needs no resolver leaves at +0.002 s on both. A cached address cannot remove the change-path stall, because the new directory string has no cached answer by construction.
Fix: resolve asynchronously and register when the answer arrives. Reusing the last resolved address (the patched build above) removes the periodic stall but not the change-path one.
---
🤖 *This message was written by AI and reviewed by @mcfnord.*
コントリビューションガイド
評価
この issue はまだ評価されていません。