返回 DeepSeek-Reasonix
session_concurrency_test.go
根目录 / internal / agent / session_concurrency_test.go
1 package agent
2
3 import (
4 "sync"
5 "testing"
6
7 "reasonix/internal/provider"
8 )
9
10 // TestSessionConcurrentAddAndRead models the real hazard: the run loop appends
11 // messages while a frontend (serve /history, autosave) reads the log from another
12 // goroutine. Snapshot must copy under the lock; before it, an append racing the
13 // copy could tear the slice header and crash.
14 func TestSessionConcurrentAddAndRead(t *testing.T) {
15 s := NewSession("sys")
16
17 var wg sync.WaitGroup
18 // One writer mimicking the turn goroutine.
19 wg.Add(1)
20 go func() {
21 defer wg.Done()
22 for i := 0; i < 5000; i++ {
23 s.Add(provider.Message{Role: provider.RoleUser, Content: "msg"})
24 }
25 }()
26 // Many readers mimicking frontends polling history.
27 for r := 0; r < 16; r++ {
28 wg.Add(1)
29 go func() {
30 defer wg.Done()
31 for i := 0; i < 5000; i++ {
32 snap := s.Snapshot()
33 for _, m := range snap { // iterate the copy: must never tear
34 _ = m.Content
35 }
36 _ = s.HasContent()
37 }
38 }()
39 }
40 wg.Wait()
41
42 if got := len(s.Snapshot()); got != 5001 { // 5000 + the system prompt
43 t.Fatalf("final message count = %d, want 5001", got)
44 }
45 }
46
46 lines GO