feat: add Meilisearch backend integration with Docker Compose setup and Excalidraw support
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import autocannon from 'autocannon';
|
||||
|
||||
const API_URL = process.env.API_URL || 'http://127.0.0.1:4000';
|
||||
const QUERIES = [
|
||||
'*',
|
||||
'tag:work notes',
|
||||
'path:Projects file:readme',
|
||||
'obsidian search',
|
||||
'tag:dev path:Projects'
|
||||
];
|
||||
|
||||
console.log('🚀 Starting Meilisearch search benchmark...');
|
||||
console.log(`API URL: ${API_URL}`);
|
||||
console.log(`Queries to test: ${QUERIES.length}\n`);
|
||||
|
||||
async function benchQuery(query) {
|
||||
const encodedQuery = encodeURIComponent(query);
|
||||
const url = `${API_URL}/api/search?q=${encodedQuery}`;
|
||||
|
||||
console.log(`\n📊 Benchmarking: "${query}"`);
|
||||
console.log(`URL: ${url}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
autocannon(
|
||||
{
|
||||
url,
|
||||
connections: 20,
|
||||
duration: 10,
|
||||
pipelining: 1
|
||||
},
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\n✅ Results for "${query}":`);
|
||||
console.log(` Average: ${result.latency.mean.toFixed(2)} ms`);
|
||||
console.log(` Median (P50): ${result.latency.p50.toFixed(2)} ms`);
|
||||
console.log(` P95: ${result.latency.p95.toFixed(2)} ms`);
|
||||
console.log(` P99: ${result.latency.p99.toFixed(2)} ms`);
|
||||
console.log(` Requests/sec: ${result.requests.average.toFixed(2)}`);
|
||||
console.log(` Total requests: ${result.requests.total}`);
|
||||
|
||||
resolve({
|
||||
query,
|
||||
latency: result.latency,
|
||||
requests: result.requests
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function runBenchmarks() {
|
||||
const results = [];
|
||||
|
||||
for (const query of QUERIES) {
|
||||
try {
|
||||
const result = await benchQuery(query);
|
||||
results.push(result);
|
||||
} catch (err) {
|
||||
console.error(`\n❌ Failed to benchmark "${query}":`, err.message);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n\n' + '='.repeat(60));
|
||||
console.log('📈 SUMMARY');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
for (const result of results) {
|
||||
console.log(`\n"${result.query}"`);
|
||||
console.log(` P95: ${result.latency.p95.toFixed(2)} ms | Avg: ${result.latency.mean.toFixed(2)} ms`);
|
||||
}
|
||||
|
||||
const allP95s = results.map(r => r.latency.p95);
|
||||
const maxP95 = Math.max(...allP95s);
|
||||
const avgP95 = allP95s.reduce((a, b) => a + b, 0) / allP95s.length;
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(`Overall P95: Avg ${avgP95.toFixed(2)} ms | Max ${maxP95.toFixed(2)} ms`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
if (maxP95 < 150) {
|
||||
console.log('\n✅ SUCCESS: P95 < 150ms target met!');
|
||||
} else {
|
||||
console.log('\n⚠️ WARNING: P95 exceeds 150ms target');
|
||||
}
|
||||
}
|
||||
|
||||
runBenchmarks().catch(err => {
|
||||
console.error('\n💥 Benchmark suite failed:', err);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user