scheduler_test.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package nebula
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. )
  7. func TestScheduler_PooledReuse(t *testing.T) {
  8. ctx, cancel := context.WithCancel(context.Background())
  9. defer cancel()
  10. s := NewScheduler[int](16)
  11. delivered := make(chan int, 256)
  12. go s.Run(ctx, func(item int) { delivered <- item })
  13. const N = 100
  14. for i := 0; i < N; i++ {
  15. s.Schedule(ctx, i, time.Millisecond)
  16. }
  17. deadline := time.After(2 * time.Second)
  18. got := 0
  19. for got < N {
  20. select {
  21. case <-delivered:
  22. got++
  23. case <-deadline:
  24. t.Fatalf("only %d/%d items delivered", got, N)
  25. }
  26. }
  27. }
  28. // BenchmarkScheduler_Schedule reports allocations per Schedule call.
  29. // In steady state the Scheduler's sync.Pool means we should see zero allocs per op once the pool warms up.
  30. func BenchmarkScheduler_Schedule(b *testing.B) {
  31. ctx, cancel := context.WithCancel(context.Background())
  32. defer cancel()
  33. s := NewScheduler[int](b.N)
  34. go s.Run(ctx, func(int) {})
  35. b.ReportAllocs()
  36. b.ResetTimer()
  37. for i := 0; i < b.N; i++ {
  38. s.Schedule(ctx, i, time.Microsecond)
  39. }
  40. }
  41. // BenchmarkBareAfterFunc is the comparison baseline.
  42. // What we'd pay per Schedule if Punchy called time.AfterFunc directly without the pooled Scheduler.
  43. // Allocates a *time.Timer plus a closure each call.
  44. func BenchmarkBareAfterFunc(b *testing.B) {
  45. ctx, cancel := context.WithCancel(context.Background())
  46. defer cancel()
  47. queue := make(chan int, b.N)
  48. go func() {
  49. for {
  50. select {
  51. case <-ctx.Done():
  52. return
  53. case <-queue:
  54. }
  55. }
  56. }()
  57. b.ReportAllocs()
  58. b.ResetTimer()
  59. for i := 0; i < b.N; i++ {
  60. i := i
  61. time.AfterFunc(time.Microsecond, func() {
  62. select {
  63. case queue <- i:
  64. case <-ctx.Done():
  65. }
  66. })
  67. }
  68. }