Skip to content

Commit f7ce7dc

Browse files
committed
fix race condition
1 parent 2b2958d commit f7ce7dc

3 files changed

Lines changed: 26 additions & 7 deletions

File tree

src/server.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ export const createServer = (): Server => {
4545
}
4646

4747
try {
48+
// Ensure context is initialized before handling tools to avoid undefined services
49+
await context.initialize();
4850
// Fire and forget, don't slow down the tool call for telemetry
4951
void sendEvent({
5052
mcp_name: request.params.name,

src/tools/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Examples:
1818
- {query: "scheduler"}`,
1919
inputSchema: z.object({
2020
query: z.string().describe('Search query'),
21-
limit: z.number().optional().default(5).describe('Maximum number of results'),
21+
limit: z.number().optional().default(2).describe('Maximum number of results'),
2222
exactMatch: z.boolean().optional().default(false).describe('Only use exact version match'),
2323
}),
2424
handler: async ({ params, context }) => {

src/utils/context.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export class Context {
1818
private _dbPath!: string;
1919
private _fixturesPath!: string;
2020
_docsService!: DocumentManagementService;
21+
private _initPromise: Promise<void> | null = null;
22+
private _initialized = false;
2123

2224
constructor() {}
2325

@@ -111,15 +113,28 @@ export class Context {
111113
}
112114

113115
async initialize() {
114-
this._latestRelease = await this._getLatestRelease();
115-
this._dbPath = await this._downloadAndCacheDb(this._latestRelease);
116-
this._fixturesPath = await this._downloadFixtures(this._latestRelease);
117-
this._docsService = new DocumentManagementService(this._dbPath, this._fixturesPath);
118-
await this._docsService.initialize();
116+
if (this._initialized) return;
117+
if (this._initPromise) return this._initPromise;
118+
119+
this._initPromise = (async () => {
120+
this._latestRelease = await this._getLatestRelease();
121+
this._dbPath = await this._downloadAndCacheDb(this._latestRelease);
122+
this._fixturesPath = await this._downloadFixtures(this._latestRelease);
123+
this._docsService = new DocumentManagementService(this._dbPath, this._fixturesPath);
124+
await this._docsService.initialize();
125+
this._initialized = true;
126+
})().catch((error) => {
127+
this._initPromise = null;
128+
throw error;
129+
});
130+
131+
return this._initPromise;
119132
}
120133

121134
async shutdown() {
122-
await this._docsService.shutdown();
135+
if (this._docsService) {
136+
await this._docsService.shutdown();
137+
}
123138
if (this._dbPath) {
124139
try {
125140
await fs.unlink(this._dbPath);
@@ -136,5 +151,7 @@ export class Context {
136151
logger.error(`Error deleting temporary fixtures ${this._fixturesPath}:`, error);
137152
}
138153
}
154+
this._initialized = false;
155+
this._initPromise = null;
139156
}
140157
}

0 commit comments

Comments
 (0)