itsi 0.2.16 → 0.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/Cargo.lock +4 -2
  4. data/crates/itsi_acme/Cargo.toml +1 -1
  5. data/crates/itsi_scheduler/Cargo.toml +1 -1
  6. data/crates/itsi_server/Cargo.toml +3 -1
  7. data/crates/itsi_server/src/lib.rs +6 -1
  8. data/crates/itsi_server/src/ruby_types/itsi_body_proxy/mod.rs +2 -0
  9. data/crates/itsi_server/src/ruby_types/itsi_grpc_call.rs +4 -4
  10. data/crates/itsi_server/src/ruby_types/itsi_grpc_response_stream/mod.rs +14 -13
  11. data/crates/itsi_server/src/ruby_types/itsi_http_request.rs +64 -33
  12. data/crates/itsi_server/src/ruby_types/itsi_http_response.rs +151 -152
  13. data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +6 -15
  14. data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +26 -5
  15. data/crates/itsi_server/src/ruby_types/itsi_server.rs +1 -1
  16. data/crates/itsi_server/src/server/binds/listener.rs +45 -7
  17. data/crates/itsi_server/src/server/frame_stream.rs +142 -0
  18. data/crates/itsi_server/src/server/http_message_types.rs +142 -9
  19. data/crates/itsi_server/src/server/io_stream.rs +28 -5
  20. data/crates/itsi_server/src/server/lifecycle_event.rs +1 -1
  21. data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +2 -3
  22. data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +8 -10
  23. data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +2 -3
  24. data/crates/itsi_server/src/server/middleware_stack/middlewares/csp.rs +3 -3
  25. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response/default_responses.rs +54 -56
  26. data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +5 -7
  27. data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +5 -5
  28. data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +7 -10
  29. data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +2 -3
  30. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +1 -2
  31. data/crates/itsi_server/src/server/middleware_stack/middlewares/static_response.rs +4 -6
  32. data/crates/itsi_server/src/server/mod.rs +1 -0
  33. data/crates/itsi_server/src/server/process_worker.rs +3 -4
  34. data/crates/itsi_server/src/server/serve_strategy/acceptor.rs +16 -12
  35. data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +87 -31
  36. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +158 -142
  37. data/crates/itsi_server/src/server/signal.rs +37 -9
  38. data/crates/itsi_server/src/server/thread_worker.rs +84 -69
  39. data/crates/itsi_server/src/services/itsi_http_service.rs +43 -43
  40. data/crates/itsi_server/src/services/static_file_server.rs +28 -47
  41. data/docs/benchmark-dashboard/.gitignore +27 -0
  42. data/docs/benchmark-dashboard/app/api/benchmarks/route.ts +22 -0
  43. data/docs/benchmark-dashboard/app/globals.css +94 -0
  44. data/docs/benchmark-dashboard/app/layout.tsx +20 -0
  45. data/docs/benchmark-dashboard/app/page.tsx +252 -0
  46. data/docs/benchmark-dashboard/components/benchmark-dashboard.tsx +1663 -0
  47. data/docs/benchmark-dashboard/components/theme-provider.tsx +11 -0
  48. data/docs/benchmark-dashboard/components/ui/accordion.tsx +58 -0
  49. data/docs/benchmark-dashboard/components/ui/alert-dialog.tsx +141 -0
  50. data/docs/benchmark-dashboard/components/ui/alert.tsx +59 -0
  51. data/docs/benchmark-dashboard/components/ui/aspect-ratio.tsx +7 -0
  52. data/docs/benchmark-dashboard/components/ui/avatar.tsx +50 -0
  53. data/docs/benchmark-dashboard/components/ui/badge.tsx +36 -0
  54. data/docs/benchmark-dashboard/components/ui/breadcrumb.tsx +115 -0
  55. data/docs/benchmark-dashboard/components/ui/button.tsx +56 -0
  56. data/docs/benchmark-dashboard/components/ui/calendar.tsx +66 -0
  57. data/docs/benchmark-dashboard/components/ui/card.tsx +79 -0
  58. data/docs/benchmark-dashboard/components/ui/carousel.tsx +262 -0
  59. data/docs/benchmark-dashboard/components/ui/chart.tsx +365 -0
  60. data/docs/benchmark-dashboard/components/ui/checkbox.tsx +30 -0
  61. data/docs/benchmark-dashboard/components/ui/collapsible.tsx +11 -0
  62. data/docs/benchmark-dashboard/components/ui/command.tsx +153 -0
  63. data/docs/benchmark-dashboard/components/ui/context-menu.tsx +200 -0
  64. data/docs/benchmark-dashboard/components/ui/dialog.tsx +122 -0
  65. data/docs/benchmark-dashboard/components/ui/drawer.tsx +118 -0
  66. data/docs/benchmark-dashboard/components/ui/dropdown-menu.tsx +200 -0
  67. data/docs/benchmark-dashboard/components/ui/form.tsx +178 -0
  68. data/docs/benchmark-dashboard/components/ui/hover-card.tsx +29 -0
  69. data/docs/benchmark-dashboard/components/ui/input-otp.tsx +71 -0
  70. data/docs/benchmark-dashboard/components/ui/input.tsx +22 -0
  71. data/docs/benchmark-dashboard/components/ui/label.tsx +26 -0
  72. data/docs/benchmark-dashboard/components/ui/loading-spinner.tsx +12 -0
  73. data/docs/benchmark-dashboard/components/ui/menubar.tsx +236 -0
  74. data/docs/benchmark-dashboard/components/ui/navigation-menu.tsx +128 -0
  75. data/docs/benchmark-dashboard/components/ui/pagination.tsx +117 -0
  76. data/docs/benchmark-dashboard/components/ui/popover.tsx +31 -0
  77. data/docs/benchmark-dashboard/components/ui/progress.tsx +28 -0
  78. data/docs/benchmark-dashboard/components/ui/radio-group.tsx +44 -0
  79. data/docs/benchmark-dashboard/components/ui/resizable.tsx +45 -0
  80. data/docs/benchmark-dashboard/components/ui/scroll-area.tsx +48 -0
  81. data/docs/benchmark-dashboard/components/ui/select.tsx +160 -0
  82. data/docs/benchmark-dashboard/components/ui/separator.tsx +31 -0
  83. data/docs/benchmark-dashboard/components/ui/sheet.tsx +140 -0
  84. data/docs/benchmark-dashboard/components/ui/sidebar.tsx +763 -0
  85. data/docs/benchmark-dashboard/components/ui/skeleton.tsx +15 -0
  86. data/docs/benchmark-dashboard/components/ui/slider.tsx +28 -0
  87. data/docs/benchmark-dashboard/components/ui/sonner.tsx +31 -0
  88. data/docs/benchmark-dashboard/components/ui/switch.tsx +29 -0
  89. data/docs/benchmark-dashboard/components/ui/table.tsx +117 -0
  90. data/docs/benchmark-dashboard/components/ui/tabs.tsx +55 -0
  91. data/docs/benchmark-dashboard/components/ui/textarea.tsx +22 -0
  92. data/docs/benchmark-dashboard/components/ui/toast.tsx +129 -0
  93. data/docs/benchmark-dashboard/components/ui/toaster.tsx +35 -0
  94. data/docs/benchmark-dashboard/components/ui/toggle-group.tsx +61 -0
  95. data/docs/benchmark-dashboard/components/ui/toggle.tsx +45 -0
  96. data/docs/benchmark-dashboard/components/ui/tooltip.tsx +30 -0
  97. data/docs/benchmark-dashboard/components/ui/use-mobile.tsx +19 -0
  98. data/docs/benchmark-dashboard/components/ui/use-toast.ts +194 -0
  99. data/docs/benchmark-dashboard/components.json +21 -0
  100. data/docs/benchmark-dashboard/dist/benchmark-dashboard.css +1 -0
  101. data/docs/benchmark-dashboard/dist/benchmark-dashboard.iife.js +211 -0
  102. data/docs/benchmark-dashboard/dist/placeholder-logo.png +0 -0
  103. data/docs/benchmark-dashboard/dist/placeholder-logo.svg +1 -0
  104. data/docs/benchmark-dashboard/dist/placeholder-user.jpg +0 -0
  105. data/docs/benchmark-dashboard/dist/placeholder.jpg +0 -0
  106. data/docs/benchmark-dashboard/dist/placeholder.svg +1 -0
  107. data/docs/benchmark-dashboard/embed.tsx +13 -0
  108. data/docs/benchmark-dashboard/hooks/use-mobile.tsx +19 -0
  109. data/docs/benchmark-dashboard/hooks/use-toast.ts +194 -0
  110. data/docs/benchmark-dashboard/lib/benchmark-utils.ts +54 -0
  111. data/docs/benchmark-dashboard/lib/utils.ts +6 -0
  112. data/docs/benchmark-dashboard/next.config.mjs +14 -0
  113. data/docs/benchmark-dashboard/package-lock.json +5859 -0
  114. data/docs/benchmark-dashboard/package.json +72 -0
  115. data/docs/benchmark-dashboard/pnpm-lock.yaml +5 -0
  116. data/docs/benchmark-dashboard/postcss.config.mjs +8 -0
  117. data/docs/benchmark-dashboard/styles/globals.css +94 -0
  118. data/docs/benchmark-dashboard/tailwind.config.ts +96 -0
  119. data/docs/benchmark-dashboard/tsconfig.json +27 -0
  120. data/docs/benchmark-dashboard/vite.config.ts +24 -0
  121. data/docs/build.rb +52 -0
  122. data/docs/content/benchmarks/index.md +96 -0
  123. data/docs/content/getting_started/_index.md +76 -46
  124. data/docs/hugo.yaml +3 -0
  125. data/docs/static/results.json +1 -0
  126. data/docs/static/scripts/benchmark-dashboard.iife.js +211 -0
  127. data/docs/static/styles/benchmark-dashboard.css +1 -0
  128. data/gems/scheduler/Cargo.lock +1 -1
  129. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  130. data/gems/server/Cargo.lock +3 -1
  131. data/gems/server/exe/itsi +6 -1
  132. data/gems/server/lib/itsi/http_request.rb +31 -39
  133. data/gems/server/lib/itsi/http_response.rb +5 -0
  134. data/gems/server/lib/itsi/rack_env_pool.rb +59 -0
  135. data/gems/server/lib/itsi/server/config/dsl.rb +5 -4
  136. data/gems/server/lib/itsi/server/config/middleware/proxy.rb +1 -1
  137. data/gems/server/lib/itsi/server/config/middleware/rackup_file.rb +2 -2
  138. data/gems/server/lib/itsi/server/config/options/auto_reload_config.rb +6 -2
  139. data/gems/server/lib/itsi/server/config/options/include.rb +5 -2
  140. data/gems/server/lib/itsi/server/config/options/pipeline_flush.md +16 -0
  141. data/gems/server/lib/itsi/server/config/options/pipeline_flush.rb +19 -0
  142. data/gems/server/lib/itsi/server/config/options/writev.md +25 -0
  143. data/gems/server/lib/itsi/server/config/options/writev.rb +19 -0
  144. data/gems/server/lib/itsi/server/config.rb +21 -8
  145. data/gems/server/lib/itsi/server/default_config/Itsi.rb +1 -4
  146. data/gems/server/lib/itsi/server/grpc/grpc_call.rb +2 -0
  147. data/gems/server/lib/itsi/server/grpc/grpc_interface.rb +2 -2
  148. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -1
  149. data/gems/server/lib/itsi/server/rack_interface.rb +17 -12
  150. data/gems/server/lib/itsi/server/scheduler_interface.rb +2 -0
  151. data/gems/server/lib/itsi/server/version.rb +1 -1
  152. data/gems/server/lib/itsi/server.rb +1 -0
  153. data/gems/server/lib/ruby_lsp/itsi/addon.rb +12 -13
  154. data/gems/server/test/helpers/test_helper.rb +12 -13
  155. data/gems/server/test/middleware/grpc/grpc.rb +13 -14
  156. data/gems/server/test/middleware/grpc/test_service_impl.rb +3 -3
  157. data/gems/server/test/middleware/proxy.rb +262 -268
  158. data/lib/itsi/version.rb +1 -1
  159. metadata +96 -6
  160. data/tasks.txt +0 -28
@@ -0,0 +1,22 @@
1
+ import { NextResponse } from "next/server"
2
+
3
+ // This would be your actual API endpoint to fetch benchmark data
4
+ export async function GET() {
5
+ try {
6
+ // In a real implementation, you would:
7
+ // 1. Scan the directory structure
8
+ // 2. Read and parse the JSON files
9
+ // 3. Return the aggregated data
10
+
11
+ // For demo purposes, we're returning a mock response
12
+ return NextResponse.json({
13
+ success: true,
14
+ data: [
15
+ // Your benchmark data would go here
16
+ ],
17
+ })
18
+ } catch (error) {
19
+ console.error("Error fetching benchmark data:", error)
20
+ return NextResponse.json({ success: false, error: "Failed to fetch benchmark data" }, { status: 500 })
21
+ }
22
+ }
@@ -0,0 +1,94 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ body {
6
+ font-family: Arial, Helvetica, sans-serif;
7
+ }
8
+
9
+ @layer utilities {
10
+ .text-balance {
11
+ text-wrap: balance;
12
+ }
13
+ }
14
+
15
+ @layer base {
16
+ :root {
17
+ --background: 0 0% 100%;
18
+ --foreground: 0 0% 3.9%;
19
+ --card: 0 0% 100%;
20
+ --card-foreground: 0 0% 3.9%;
21
+ --popover: 0 0% 100%;
22
+ --popover-foreground: 0 0% 3.9%;
23
+ --primary: 0 0% 9%;
24
+ --primary-foreground: 0 0% 98%;
25
+ --secondary: 0 0% 96.1%;
26
+ --secondary-foreground: 0 0% 9%;
27
+ --muted: 0 0% 96.1%;
28
+ --muted-foreground: 0 0% 45.1%;
29
+ --accent: 0 0% 96.1%;
30
+ --accent-foreground: 0 0% 9%;
31
+ --destructive: 0 84.2% 60.2%;
32
+ --destructive-foreground: 0 0% 98%;
33
+ --border: 0 0% 89.8%;
34
+ --input: 0 0% 89.8%;
35
+ --ring: 0 0% 3.9%;
36
+ --chart-1: 12 76% 61%;
37
+ --chart-2: 173 58% 39%;
38
+ --chart-3: 197 37% 24%;
39
+ --chart-4: 43 74% 66%;
40
+ --chart-5: 27 87% 67%;
41
+ --radius: 0.5rem;
42
+ --sidebar-background: 0 0% 98%;
43
+ --sidebar-foreground: 240 5.3% 26.1%;
44
+ --sidebar-primary: 240 5.9% 10%;
45
+ --sidebar-primary-foreground: 0 0% 98%;
46
+ --sidebar-accent: 240 4.8% 95.9%;
47
+ --sidebar-accent-foreground: 240 5.9% 10%;
48
+ --sidebar-border: 220 13% 91%;
49
+ --sidebar-ring: 217.2 91.2% 59.8%;
50
+ }
51
+ .dark {
52
+ --background: 0 0% 3.9%;
53
+ --foreground: 0 0% 98%;
54
+ --card: 0 0% 3.9%;
55
+ --card-foreground: 0 0% 98%;
56
+ --popover: 0 0% 3.9%;
57
+ --popover-foreground: 0 0% 98%;
58
+ --primary: 0 0% 98%;
59
+ --primary-foreground: 0 0% 9%;
60
+ --secondary: 0 0% 14.9%;
61
+ --secondary-foreground: 0 0% 98%;
62
+ --muted: 0 0% 14.9%;
63
+ --muted-foreground: 0 0% 63.9%;
64
+ --accent: 0 0% 14.9%;
65
+ --accent-foreground: 0 0% 98%;
66
+ --destructive: 0 62.8% 30.6%;
67
+ --destructive-foreground: 0 0% 98%;
68
+ --border: 0 0% 14.9%;
69
+ --input: 0 0% 14.9%;
70
+ --ring: 0 0% 83.1%;
71
+ --chart-1: 220 70% 50%;
72
+ --chart-2: 160 60% 45%;
73
+ --chart-3: 30 80% 55%;
74
+ --chart-4: 280 65% 60%;
75
+ --chart-5: 340 75% 55%;
76
+ --sidebar-background: 240 5.9% 10%;
77
+ --sidebar-foreground: 240 4.8% 95.9%;
78
+ --sidebar-primary: 224.3 76.3% 48%;
79
+ --sidebar-primary-foreground: 0 0% 100%;
80
+ --sidebar-accent: 240 3.7% 15.9%;
81
+ --sidebar-accent-foreground: 240 4.8% 95.9%;
82
+ --sidebar-border: 240 3.7% 15.9%;
83
+ --sidebar-ring: 217.2 91.2% 59.8%;
84
+ }
85
+ }
86
+
87
+ @layer base {
88
+ * {
89
+ @apply border-border;
90
+ }
91
+ body {
92
+ @apply bg-background text-foreground;
93
+ }
94
+ }
@@ -0,0 +1,20 @@
1
+ import type { Metadata } from 'next'
2
+ import './globals.css'
3
+
4
+ export const metadata: Metadata = {
5
+ title: 'v0 App',
6
+ description: 'Created with v0',
7
+ generator: 'v0.dev',
8
+ }
9
+
10
+ export default function RootLayout({
11
+ children,
12
+ }: Readonly<{
13
+ children: React.ReactNode
14
+ }>) {
15
+ return (
16
+ <html lang="en">
17
+ <body>{children}</body>
18
+ </html>
19
+ )
20
+ }
@@ -0,0 +1,252 @@
1
+ "use client"
2
+
3
+ import { useState, useEffect } from "react"
4
+ import { BenchmarkDashboard } from "@/components/benchmark-dashboard"
5
+ import { LoadingSpinner } from "@/components/ui/loading-spinner"
6
+
7
+ // Updated sample data with the new group hierarchy and longer version strings
8
+ const sampleHierarchicalData = [
9
+ {
10
+ cpu: "apple_m1_pro",
11
+ groups: [
12
+ {
13
+ group: "rack",
14
+ tests: [
15
+ {
16
+ test: "chunked",
17
+ servers: [
18
+ {
19
+ server: "agoo",
20
+ results: [
21
+ {
22
+ server: "agoo",
23
+ test_case: "chunked",
24
+ version: "Agoo v1.2.3 (Ruby 3.2.0) with experimental HTTP/2 support",
25
+ threads: 1,
26
+ workers: 1,
27
+ http2: false,
28
+ concurrency: 10,
29
+ rss_mb: 1.77,
30
+ results: {
31
+ successRate: 1.0,
32
+ total: 20000.0,
33
+ slowest: 5000000.0,
34
+ fastest: 200000.0,
35
+ average: 2500000.0,
36
+ requestsPerSec: 6500.0,
37
+ totalData: 0,
38
+ sizePerRequest: 0.0,
39
+ sizePerSec: 0.0,
40
+ errorDistribution: {},
41
+ p95_latency: 4.8,
42
+ },
43
+ timestamp: "2025-05-24T10:41:17Z",
44
+ },
45
+ {
46
+ server: "agoo",
47
+ test_case: "chunked",
48
+ version: "Agoo v1.2.3 (Ruby 3.2.0) with experimental HTTP/2 support",
49
+ threads: 1,
50
+ workers: 1,
51
+ http2: false,
52
+ concurrency: 50,
53
+ rss_mb: 1.77,
54
+ results: {
55
+ successRate: 0.95,
56
+ total: 28000.0,
57
+ slowest: 12000000.0,
58
+ fastest: 400000.0,
59
+ average: 6000000.0,
60
+ requestsPerSec: 9500.0,
61
+ totalData: 0,
62
+ sizePerRequest: 0.0,
63
+ sizePerSec: 0.0,
64
+ errorDistribution: {
65
+ timeout: 50,
66
+ },
67
+ p95_latency: 10.2,
68
+ },
69
+ timestamp: "2025-05-24T10:41:17Z",
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ server: "puma",
75
+ results: [
76
+ {
77
+ server: "puma",
78
+ test_case: "chunked",
79
+ version:
80
+ "Puma version 6.6.0+h2o version 2.3.0-DEV@87e2aa634 (Ruby 3.2.2) with HTTP/2 support enabled",
81
+ threads: 1,
82
+ workers: 1,
83
+ http2: true,
84
+ concurrency: 10,
85
+ results: {
86
+ successRate: 1.0,
87
+ total: 15000.0,
88
+ slowest: 4000000.0,
89
+ fastest: 200000.0,
90
+ average: 2000000.0,
91
+ requestsPerSec: 5000.0,
92
+ totalData: 150000000,
93
+ sizePerRequest: 10000.0,
94
+ sizePerSec: 50000000.0,
95
+ errorDistribution: {},
96
+ p95_latency: 3.8,
97
+ },
98
+ },
99
+ {
100
+ server: "puma",
101
+ test_case: "chunked",
102
+ version:
103
+ "Puma version 6.6.0+h2o version 2.3.0-DEV@87e2aa634 (Ruby 3.2.2) with HTTP/2 support enabled",
104
+ threads: 1,
105
+ workers: 1,
106
+ http2: true,
107
+ concurrency: 50,
108
+ results: {
109
+ successRate: 1.0,
110
+ total: 22000.0,
111
+ slowest: 12000000.0,
112
+ fastest: 400000.0,
113
+ average: 6000000.0,
114
+ requestsPerSec: 7500.0,
115
+ totalData: 220000000,
116
+ sizePerRequest: 10000.0,
117
+ sizePerSec: 75000000.0,
118
+ errorDistribution: {},
119
+ p95_latency: 11.2,
120
+ },
121
+ },
122
+ ],
123
+ },
124
+ ],
125
+ },
126
+ {
127
+ test: "io_party",
128
+ servers: [
129
+ {
130
+ server: "itsi",
131
+ results: [
132
+ {
133
+ server: "itsi",
134
+ test_case: "io_party",
135
+ version:
136
+ "ITSI v0.9.1-beta.3 (Experimental) with advanced IO processing and HTTP/2 multiplexing support",
137
+ threads: 1,
138
+ workers: 1,
139
+ http2: true,
140
+ concurrency: 10,
141
+ rss_mb: 64.11,
142
+ results: {
143
+ successRate: 1.0,
144
+ total: 48591.0,
145
+ slowest: 2850375.0,
146
+ fastest: 116292.0,
147
+ average: 486975.0,
148
+ requestsPerSec: 16196.49,
149
+ totalData: 0,
150
+ sizePerRequest: 0.0,
151
+ sizePerSec: 0.0,
152
+ errorDistribution: {},
153
+ p95_latency: 0.977999,
154
+ },
155
+ timestamp: "2025-05-15T03:43:50Z",
156
+ },
157
+ ],
158
+ },
159
+ ],
160
+ },
161
+ ],
162
+ },
163
+ {
164
+ group: "sinatra",
165
+ tests: [
166
+ {
167
+ test: "hello_world",
168
+ servers: [
169
+ {
170
+ server: "falcon",
171
+ results: [
172
+ {
173
+ server: "falcon",
174
+ test_case: "hello_world",
175
+ version:
176
+ "Falcon v0.51.1 (Ruby 3.3.0-preview1) with HTTP/2 and WebSocket support, running on Async::HTTP::Protocol::HTTP2 implementation",
177
+ threads: 2,
178
+ workers: 2,
179
+ http2: true,
180
+ concurrency: 10,
181
+ results: {
182
+ successRate: 1.0,
183
+ total: 30000.0,
184
+ slowest: 10000000.0,
185
+ fastest: 400000.0,
186
+ average: 5000000.0,
187
+ requestsPerSec: 10000.0,
188
+ totalData: 0,
189
+ sizePerRequest: 0.0,
190
+ sizePerSec: 0.0,
191
+ errorDistribution: {},
192
+ p95_latency: 8.5,
193
+ },
194
+ },
195
+ ],
196
+ },
197
+ ],
198
+ },
199
+ ],
200
+ },
201
+ ],
202
+ },
203
+ ]
204
+
205
+ export default function Home() {
206
+ const [isLoading, setIsLoading] = useState(true)
207
+ const [benchmarkData, setBenchmarkData] = useState([])
208
+ const [error, setError] = useState<string | null>(null)
209
+
210
+ useEffect(() => {
211
+ const fetchData = async () => {
212
+ try {
213
+ // In a real app, this would fetch from your API endpoint
214
+ // For demo purposes, we're using the sample hierarchical data
215
+ setBenchmarkData(sampleHierarchicalData)
216
+ setIsLoading(false)
217
+ } catch (err) {
218
+ console.error("Error fetching benchmark data:", err)
219
+ setError("Failed to load benchmark data. Please try again.")
220
+ setIsLoading(false)
221
+ }
222
+ }
223
+
224
+ fetchData()
225
+ }, [])
226
+
227
+ if (isLoading) {
228
+ return (
229
+ <div className="flex h-screen items-center justify-center">
230
+ <LoadingSpinner />
231
+ <span className="ml-2">Loading benchmark data...</span>
232
+ </div>
233
+ )
234
+ }
235
+
236
+ if (error) {
237
+ return (
238
+ <div className="flex h-screen items-center justify-center">
239
+ <div className="text-center">
240
+ <h2 className="text-2xl font-bold text-red-600">Error</h2>
241
+ <p className="mt-2">{error}</p>
242
+ </div>
243
+ </div>
244
+ )
245
+ }
246
+
247
+ return (
248
+ <main className="container mx-auto p-2">
249
+ <BenchmarkDashboard data={benchmarkData} />
250
+ </main>
251
+ )
252
+ }