diff --git a/package.json b/package.json index 2eb5eb56..5097becd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hawk.api", - "version": "1.5.3", + "version": "1.5.4", "main": "index.ts", "license": "BUSL-1.1", "scripts": { diff --git a/src/mongo.ts b/src/mongo.ts index 60a2d5ff..27bfd1f0 100644 --- a/src/mongo.ts +++ b/src/mongo.ts @@ -7,12 +7,20 @@ const eventsDBUrl = process.env.MONGO_EVENTS_DB_URL || 'mongodb://localhost:2701 const reconnectTries = Number(process.env.MONGO_RECONNECT_TRIES) || 60; const reconnectInterval = Number(process.env.MONGO_RECONNECT_INTERVAL) || 1000; +const maxPoolSize = Number(process.env.MONGO_MAX_POOL_SIZE) || 30; /** * serverSelectionTimeoutMS bounds how long an op waits for an available * server — without it queries hang forever during an outage. + * + * maxPoolSize caps sockets per client (driver default 100 lets API replicas + * alone exhaust the server-side 1024 limit); maxIdleTimeMS closes sockets + * left idle after spikes (default 0 keeps them forever). */ -const connectionConfig: MongoClientOptions = withMongoMetrics({ +const connectionConfig = (appName: string): MongoClientOptions => withMongoMetrics({ + appName, + maxPoolSize, + maxIdleTimeMS: 60000, serverSelectionTimeoutMS: 10000, socketTimeoutMS: 45000, retryWrites: true, @@ -77,7 +85,7 @@ async function connectWithRetry(name: string, url: string): Promise let lastError = 'unknown error'; for (let attempt = 1; attempt <= reconnectTries; attempt++) { - const client = new MongoClient(url, connectionConfig); + const client = new MongoClient(url, connectionConfig(`hawk-api-${name}`)); try { await client.connect(); diff --git a/src/resolvers/project.js b/src/resolvers/project.js index 18da81f3..7e4bf7fe 100644 --- a/src/resolvers/project.js +++ b/src/resolvers/project.js @@ -20,6 +20,7 @@ const EVENTS_PAYLOAD_RELEASE_INDEX_NAME = 'payloadRelease'; const GROUPING_TIMESTAMP_INDEX_NAME = 'groupingTimestamp'; const GROUPING_TIMESTAMP_AND_LAST_REPETITION_TIME_AND_ID_INDEX_NAME = 'groupingTimestampAndLastRepetitionTimeAndId'; const GROUPING_TIMESTAMP_AND_GROUP_HASH_INDEX_NAME = 'groupingTimestampAndGroupHash'; +const DAILY_EVENTS_GROUP_HASH_INDEX_NAME = 'groupHash'; const MAX_SEARCH_QUERY_LENGTH = 50; const FALLBACK_EVENT_TITLE = 'Unknown'; @@ -183,6 +184,12 @@ module.exports = { name: GROUPING_TIMESTAMP_AND_LAST_REPETITION_TIME_AND_ID_INDEX_NAME, }); + await projectDailyEventsCollection.createIndex({ + groupHash: 1, + }, { + name: DAILY_EVENTS_GROUP_HASH_INDEX_NAME, + }); + await projectEventsCollection.createIndex({ 'payload.release': 1, },