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