dns: switch to active upstream pool and wave fallback behavior
This commit is contained in:
@@ -20,7 +20,7 @@ from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from api_client import DNSBenchmarkUpstream, DnsUpstreams
|
||||
from api_client import DNSBenchmarkUpstream
|
||||
from dashboard_controller import DashboardController
|
||||
|
||||
|
||||
@@ -61,24 +61,22 @@ class DNSBenchmarkDialog(QDialog):
|
||||
self.ctrl = ctrl
|
||||
self.settings = settings
|
||||
self.refresh_cb = refresh_cb
|
||||
self._last_recommended_default: List[str] = []
|
||||
self._last_recommended_meta: List[str] = []
|
||||
|
||||
self.setWindowTitle("DNS benchmark")
|
||||
self.resize(980, 650)
|
||||
self.resize(980, 660)
|
||||
|
||||
root = QVBoxLayout(self)
|
||||
|
||||
hint = QLabel(
|
||||
"List format: one DNS per row. Toggle checkbox to include in test. "
|
||||
"Then run benchmark and apply best DNS to resolver."
|
||||
"One DNS per row. Checkbox means ACTIVE for resolver wave mode. "
|
||||
"Benchmark checks all rows and shows health."
|
||||
)
|
||||
hint.setWordWrap(True)
|
||||
hint.setStyleSheet("color: gray;")
|
||||
root.addWidget(hint)
|
||||
|
||||
self.tbl_sources = QTableWidget(0, 2)
|
||||
self.tbl_sources.setHorizontalHeaderLabels(["Use", "DNS upstream"])
|
||||
self.tbl_sources.setHorizontalHeaderLabels(["Active", "DNS upstream"])
|
||||
self.tbl_sources.horizontalHeader().setStretchLastSection(True)
|
||||
self.tbl_sources.setSelectionBehavior(QTableWidget.SelectRows)
|
||||
self.tbl_sources.setSelectionMode(QTableWidget.SingleSelection)
|
||||
@@ -95,6 +93,12 @@ class DNSBenchmarkDialog(QDialog):
|
||||
self.btn_reset = QPushButton("Reset defaults")
|
||||
self.btn_reset.clicked.connect(self.on_reset_defaults)
|
||||
row_btns.addWidget(self.btn_reset)
|
||||
self.btn_reload = QPushButton("Reload active set")
|
||||
self.btn_reload.clicked.connect(self.on_reload_pool)
|
||||
row_btns.addWidget(self.btn_reload)
|
||||
self.btn_save_pool = QPushButton("Save active set")
|
||||
self.btn_save_pool.clicked.connect(self.on_save_pool)
|
||||
row_btns.addWidget(self.btn_save_pool)
|
||||
row_btns.addStretch(1)
|
||||
root.addLayout(row_btns)
|
||||
|
||||
@@ -150,18 +154,12 @@ class DNSBenchmarkDialog(QDialog):
|
||||
self.tbl_results.setSelectionMode(QTableWidget.SingleSelection)
|
||||
root.addWidget(self.tbl_results, stretch=3)
|
||||
|
||||
apply_row = QHBoxLayout()
|
||||
self.btn_apply_default = QPushButton("Apply top-2 to Default")
|
||||
self.btn_apply_default.clicked.connect(self.on_apply_default)
|
||||
apply_row.addWidget(self.btn_apply_default)
|
||||
self.btn_apply_meta = QPushButton("Apply top-2 to Meta")
|
||||
self.btn_apply_meta.clicked.connect(self.on_apply_meta)
|
||||
apply_row.addWidget(self.btn_apply_meta)
|
||||
apply_row.addStretch(1)
|
||||
close_row = QHBoxLayout()
|
||||
close_row.addStretch(1)
|
||||
self.btn_close = QPushButton("Close")
|
||||
self.btn_close.clicked.connect(self.accept)
|
||||
apply_row.addWidget(self.btn_close)
|
||||
root.addLayout(apply_row)
|
||||
close_row.addWidget(self.btn_close)
|
||||
root.addLayout(close_row)
|
||||
|
||||
self._load_sources()
|
||||
self._load_domains()
|
||||
@@ -173,33 +171,51 @@ class DNSBenchmarkDialog(QDialog):
|
||||
QMessageBox.critical(self, title, str(e))
|
||||
|
||||
def _load_sources(self) -> None:
|
||||
raw = str(self.settings.value("dns_benchmark/upstreams", "") or "").strip()
|
||||
rows: List[tuple[bool, str]] = []
|
||||
if raw:
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
if isinstance(data, list):
|
||||
for item in data:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
addr = str(item.get("addr") or "").strip()
|
||||
if not addr:
|
||||
continue
|
||||
rows.append((bool(item.get("enabled", True)), addr))
|
||||
except Exception:
|
||||
rows = []
|
||||
|
||||
try:
|
||||
st = self.ctrl.dns_upstream_pool_view()
|
||||
for item in st.items:
|
||||
addr = str(item.addr or "").strip()
|
||||
if not addr:
|
||||
continue
|
||||
rows.append((bool(item.enabled), addr))
|
||||
except Exception:
|
||||
rows = []
|
||||
|
||||
if not rows:
|
||||
raw = str(self.settings.value("dns_benchmark/upstreams", "") or "").strip()
|
||||
if raw:
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
if isinstance(data, list):
|
||||
for item in data:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
addr = str(item.get("addr") or "").strip()
|
||||
if not addr:
|
||||
continue
|
||||
rows.append((bool(item.get("enabled", True)), addr))
|
||||
except Exception:
|
||||
rows = []
|
||||
|
||||
if not rows:
|
||||
rows = [(True, item) for item in DEFAULT_UPSTREAMS]
|
||||
|
||||
self.tbl_sources.blockSignals(True)
|
||||
self.tbl_sources.setRowCount(0)
|
||||
for enabled, addr in rows:
|
||||
self._append_source_row(enabled, addr)
|
||||
self.tbl_sources.blockSignals(False)
|
||||
self._save_settings()
|
||||
|
||||
def _load_domains(self) -> None:
|
||||
raw = str(self.settings.value("dns_benchmark/domains", "") or "").strip()
|
||||
if not raw:
|
||||
raw = "\n".join(DEFAULT_DOMAINS)
|
||||
self.txt_domains.blockSignals(True)
|
||||
self.txt_domains.setPlainText(raw)
|
||||
self.txt_domains.blockSignals(False)
|
||||
|
||||
def _save_settings(self) -> None:
|
||||
items = []
|
||||
@@ -264,14 +280,33 @@ class DNSBenchmarkDialog(QDialog):
|
||||
row = self.tbl_sources.currentRow()
|
||||
if row >= 0:
|
||||
self.tbl_sources.removeRow(row)
|
||||
self._save_settings()
|
||||
self._save_settings()
|
||||
|
||||
def on_reset_defaults(self) -> None:
|
||||
self.tbl_sources.blockSignals(True)
|
||||
self.tbl_sources.setRowCount(0)
|
||||
for item in DEFAULT_UPSTREAMS:
|
||||
self._append_source_row(True, item)
|
||||
self.tbl_sources.blockSignals(False)
|
||||
self._save_settings()
|
||||
|
||||
def on_reload_pool(self) -> None:
|
||||
self._safe(self._load_sources, "Reload DNS active set error")
|
||||
|
||||
def on_save_pool(self) -> None:
|
||||
def work() -> None:
|
||||
payload = self._source_payload()
|
||||
st = self.ctrl.dns_upstream_pool_save(payload)
|
||||
active = sum(1 for x in st.items if x.enabled)
|
||||
total = len(st.items)
|
||||
self._save_settings()
|
||||
self.lbl_summary.setText(f"Saved active DNS set: active={active}/{total}")
|
||||
self.lbl_summary.setStyleSheet("color: green;")
|
||||
if self.refresh_cb:
|
||||
self.refresh_cb()
|
||||
|
||||
self._safe(work, "Save DNS active set error")
|
||||
|
||||
def on_run_benchmark(self) -> None:
|
||||
def work() -> None:
|
||||
self._save_settings()
|
||||
@@ -284,8 +319,6 @@ class DNSBenchmarkDialog(QDialog):
|
||||
attempts=int(self.spin_attempts.value()),
|
||||
concurrency=int(self.spin_concurrency.value()),
|
||||
)
|
||||
self._last_recommended_default = list(resp.recommended_default or [])
|
||||
self._last_recommended_meta = list(resp.recommended_meta or [])
|
||||
self._render_results(resp)
|
||||
if self.refresh_cb:
|
||||
self.refresh_cb()
|
||||
@@ -320,11 +353,9 @@ class DNSBenchmarkDialog(QDialog):
|
||||
st_item.setForeground(QColor("red"))
|
||||
self.tbl_results.setItem(row, 6, st_item)
|
||||
|
||||
dflt = ", ".join(resp.recommended_default or []) or "—"
|
||||
meta = ", ".join(resp.recommended_meta or []) or "—"
|
||||
self.lbl_summary.setText(
|
||||
f"Checked: {len(resp.results)} DNS | domains={len(resp.domains_used)} "
|
||||
f"| timeout={resp.timeout_ms}ms | rec default: {dflt} | rec meta: {meta}"
|
||||
f"| timeout={resp.timeout_ms}ms"
|
||||
)
|
||||
self.lbl_summary.setStyleSheet("color: gray;")
|
||||
|
||||
@@ -334,43 +365,3 @@ class DNSBenchmarkDialog(QDialog):
|
||||
self.settings.setValue("dns_benchmark/last_ok", ok_total)
|
||||
self.settings.setValue("dns_benchmark/last_fail", fail_total)
|
||||
self.settings.setValue("dns_benchmark/last_timeout", timeout_total)
|
||||
|
||||
def on_apply_default(self) -> None:
|
||||
def work() -> None:
|
||||
picks = list(self._last_recommended_default or [])
|
||||
if len(picks) < 2:
|
||||
raise ValueError("run benchmark first (need at least 2 recommended DNS)")
|
||||
cur = self.ctrl.dns_upstreams_view()
|
||||
cfg = DnsUpstreams(
|
||||
default1=picks[0],
|
||||
default2=picks[1],
|
||||
meta1=cur.meta1,
|
||||
meta2=cur.meta2,
|
||||
)
|
||||
self.ctrl.dns_upstreams_save(cfg)
|
||||
if self.refresh_cb:
|
||||
self.refresh_cb()
|
||||
self.lbl_summary.setText(f"Applied default DNS: {picks[0]}, {picks[1]}")
|
||||
self.lbl_summary.setStyleSheet("color: green;")
|
||||
|
||||
self._safe(work, "Apply default DNS error")
|
||||
|
||||
def on_apply_meta(self) -> None:
|
||||
def work() -> None:
|
||||
picks = list(self._last_recommended_meta or [])
|
||||
if len(picks) < 2:
|
||||
raise ValueError("run benchmark first (need at least 2 recommended DNS)")
|
||||
cur = self.ctrl.dns_upstreams_view()
|
||||
cfg = DnsUpstreams(
|
||||
default1=cur.default1,
|
||||
default2=cur.default2,
|
||||
meta1=picks[0],
|
||||
meta2=picks[1],
|
||||
)
|
||||
self.ctrl.dns_upstreams_save(cfg)
|
||||
if self.refresh_cb:
|
||||
self.refresh_cb()
|
||||
self.lbl_summary.setText(f"Applied meta DNS: {picks[0]}, {picks[1]}")
|
||||
self.lbl_summary.setStyleSheet("color: green;")
|
||||
|
||||
self._safe(work, "Apply meta DNS error")
|
||||
|
||||
Reference in New Issue
Block a user