neo4j_benchmark.go raw
1 package main
2
3 import (
4 "context"
5 "fmt"
6 "log"
7 "os"
8 "time"
9
10 "next.orly.dev/pkg/database"
11 _ "next.orly.dev/pkg/neo4j" // Import to register neo4j factory
12 )
13
14 // Neo4jBenchmark wraps a Benchmark with Neo4j-specific setup
15 type Neo4jBenchmark struct {
16 config *BenchmarkConfig
17 docker *Neo4jDocker
18 database database.Database
19 bench *BenchmarkAdapter
20 }
21
22 // NewNeo4jBenchmark creates a new Neo4j benchmark instance
23 func NewNeo4jBenchmark(config *BenchmarkConfig) (*Neo4jBenchmark, error) {
24 // Create Docker manager
25 docker, err := NewNeo4jDocker()
26 if err != nil {
27 return nil, fmt.Errorf("failed to create Neo4j docker manager: %w", err)
28 }
29
30 // Start Neo4j container
31 if err := docker.Start(); err != nil {
32 return nil, fmt.Errorf("failed to start Neo4j: %w", err)
33 }
34
35 // Set environment variables for Neo4j connection
36 os.Setenv("ORLY_NEO4J_URI", "bolt://localhost:7687")
37 os.Setenv("ORLY_NEO4J_USER", "neo4j")
38 os.Setenv("ORLY_NEO4J_PASSWORD", "benchmark123")
39
40 // Create database instance using Neo4j backend
41 ctx := context.Background()
42 cancel := func() {}
43 db, err := database.NewDatabase(ctx, cancel, "neo4j", config.DataDir, "warn")
44 if err != nil {
45 docker.Stop()
46 return nil, fmt.Errorf("failed to create Neo4j database: %w", err)
47 }
48
49 // Wait for database to be ready
50 fmt.Println("Waiting for Neo4j database to be ready...")
51 select {
52 case <-db.Ready():
53 fmt.Println("Neo4j database is ready")
54 case <-time.After(30 * time.Second):
55 db.Close()
56 docker.Stop()
57 return nil, fmt.Errorf("Neo4j database failed to become ready")
58 }
59
60 // Create adapter to use Database interface with Benchmark
61 adapter := NewBenchmarkAdapter(config, db)
62
63 neo4jBench := &Neo4jBenchmark{
64 config: config,
65 docker: docker,
66 database: db,
67 bench: adapter,
68 }
69
70 return neo4jBench, nil
71 }
72
73 // Close closes the Neo4j benchmark and stops Docker container
74 func (ngb *Neo4jBenchmark) Close() {
75 fmt.Println("Closing Neo4j benchmark...")
76
77 if ngb.database != nil {
78 ngb.database.Close()
79 }
80
81 if ngb.docker != nil {
82 if err := ngb.docker.Stop(); err != nil {
83 log.Printf("Error stopping Neo4j Docker: %v", err)
84 }
85 }
86 }
87
88 // RunSuite runs the benchmark suite on Neo4j
89 func (ngb *Neo4jBenchmark) RunSuite() {
90 fmt.Println("\n╔════════════════════════════════════════════════════════╗")
91 fmt.Println("║ NEO4J BACKEND BENCHMARK SUITE ║")
92 fmt.Println("╚════════════════════════════════════════════════════════╝")
93
94 // Run benchmark tests
95 fmt.Printf("\n=== Starting Neo4j benchmark ===\n")
96
97 fmt.Printf("RunPeakThroughputTest (Neo4j)..\n")
98 ngb.bench.RunPeakThroughputTest()
99 fmt.Println("Wiping database between tests...")
100 ngb.database.Wipe()
101 time.Sleep(10 * time.Second)
102
103 fmt.Printf("RunBurstPatternTest (Neo4j)..\n")
104 ngb.bench.RunBurstPatternTest()
105 fmt.Println("Wiping database between tests...")
106 ngb.database.Wipe()
107 time.Sleep(10 * time.Second)
108
109 fmt.Printf("RunMixedReadWriteTest (Neo4j)..\n")
110 ngb.bench.RunMixedReadWriteTest()
111 fmt.Println("Wiping database between tests...")
112 ngb.database.Wipe()
113 time.Sleep(10 * time.Second)
114
115 fmt.Printf("RunQueryTest (Neo4j)..\n")
116 ngb.bench.RunQueryTest()
117 fmt.Println("Wiping database between tests...")
118 ngb.database.Wipe()
119 time.Sleep(10 * time.Second)
120
121 fmt.Printf("RunConcurrentQueryStoreTest (Neo4j)..\n")
122 ngb.bench.RunConcurrentQueryStoreTest()
123
124 fmt.Printf("\n=== Neo4j benchmark completed ===\n\n")
125 }
126
127 // GenerateReport generates the benchmark report
128 func (ngb *Neo4jBenchmark) GenerateReport() {
129 ngb.bench.GenerateReport()
130 }
131
132 // GenerateAsciidocReport generates asciidoc format report
133 func (ngb *Neo4jBenchmark) GenerateAsciidocReport() {
134 ngb.bench.GenerateAsciidocReport()
135 }
136