Fix awg-ctrl hanging on the torrent flag; log out on an expired session
The torrent flag was read inside loops over users rows (users/stats, peers, metrics) and each read queried the config table. SQLite has a single connection here, so the nested query waited for it forever: the first stats request or Prometheus scrape locked awg-ctrl for good, and the panel showed no users and timed out. - the block setting is kept in memory (loaded at start, updated on save), so the flag never touches the database - the set of flagged IPs is taken once before the query, not per row - regression test: collectMetrics must finish with users in the table Panel: a 401 from the panel itself (its JWT not accepted) now returns to the login screen; a 401 relayed from a node's awg-ctrl does not.
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
package ctrl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/maeneko/forgetting/internal/logx"
|
||||
)
|
||||
|
||||
// SQLite открыт с одним соединением: любой запрос в базу изнутри цикла по строкам users ждал
|
||||
// бы его вечно и намертво вешал awg-ctrl (так было в 0.4.2 с меткой торрента). Скрейп метрик
|
||||
// идёт раз в 15 с, поэтому зависание проявлялось сразу.
|
||||
func TestCollectMetricsNoDeadlock(t *testing.T) {
|
||||
db, err := openDB(filepath.Join(t.TempDir(), "users.db"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i := 0; i < 5; i++ {
|
||||
db.Exec("INSERT INTO users (name, ip, pub_key, vpn_key) VALUES (?, ?, ?, 'vpn://x')", fmt.Sprintf("u%d", i), fmt.Sprintf("10.9.0.%d", i+2), fmt.Sprintf("pk%d", i))
|
||||
}
|
||||
s := &Server{db: db, iface: "awg1", log: logx.New(os.Stderr, t.TempDir())}
|
||||
s.shaping = newShaping(s)
|
||||
s.torrent = newTorrent(s)
|
||||
done := make(chan error, 1)
|
||||
go func() { _, err := s.collectMetrics(); done <- err }()
|
||||
select {
|
||||
case err := <-done:
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("collectMetrics завис: запрос в базу изнутри цикла по строкам")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user