@adaptic/backend-legacy 0.0.916 → 0.0.917
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.
- package/client.cjs +19 -6
- package/esm/client.d.ts.map +1 -1
- package/esm/client.js.map +1 -1
- package/esm/client.mjs +19 -6
- package/esm/prismaClient.d.ts +15 -0
- package/esm/prismaClient.d.ts.map +1 -1
- package/esm/prismaClient.js.map +1 -1
- package/esm/prismaClient.mjs +146 -1
- package/package.json +1 -1
- package/prismaClient.cjs +150 -1
- package/prismaClient.d.ts +15 -0
- package/server.cjs +90 -57
package/client.cjs
CHANGED
|
@@ -177,12 +177,25 @@ async function enqueueOperation(operation, attempt = 0) {
|
|
|
177
177
|
resolve(result);
|
|
178
178
|
}
|
|
179
179
|
catch (error) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
180
|
+
const isRetryable = error instanceof Error && (error.message.includes('Accelerate') ||
|
|
181
|
+
error.message.includes('code: 1016') ||
|
|
182
|
+
error.message.includes('ECONNREFUSED') ||
|
|
183
|
+
error.message.includes('ECONNRESET') ||
|
|
184
|
+
error.message.includes('ETIMEDOUT') ||
|
|
185
|
+
error.message.includes('fetch failed') ||
|
|
186
|
+
error.message.includes('socket hang up') ||
|
|
187
|
+
error.message.includes('network') ||
|
|
188
|
+
error.message.includes("Can't reach database server") ||
|
|
189
|
+
error.message.includes('Connection pool timeout') ||
|
|
190
|
+
error.message.includes('P2024') ||
|
|
191
|
+
error.message.includes('terminated') ||
|
|
192
|
+
error.message.includes('status code 408') ||
|
|
193
|
+
error.message.includes('status code 502') ||
|
|
194
|
+
error.message.includes('status code 503') ||
|
|
195
|
+
error.message.includes('status code 504'));
|
|
196
|
+
if (attempt < poolConfig.retryAttempts && isRetryable) {
|
|
197
|
+
const delay = poolConfig.retryDelay * Math.pow(2, attempt);
|
|
198
|
+
logger_1.logger.warn(`Apollo operation failed, retrying in ${delay}ms (attempt ${attempt + 1}/${poolConfig.retryAttempts})`, { error: error instanceof Error ? error.message : String(error) });
|
|
186
199
|
setTimeout(() => {
|
|
187
200
|
enqueueOperation(operation, attempt + 1)
|
|
188
201
|
.then(resolve)
|
package/esm/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,IAAI,gBAAgB,EAChC,aAAa,IAAI,iBAAiB,EAClC,qBAAqB,EAEtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpE,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,GACtB,CAAC;AAGF,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,cAAc,gBAAgB,EAAE,YAAY,CAAC;IAC3D,aAAa,EAAE,cAAc,6CAA6C,EAAE,aAAa,CAAC;IAC1F,QAAQ,EAAE,cAAc,0BAA0B,EAAE,QAAQ,CAAC;IAC7D,GAAG,EAAE,cAAc,gBAAgB,EAAE,GAAG,CAAC;IACzC,WAAW,EAAE,cAAc,gBAAgB,EAAE,WAAW,CAAC;IACzD,KAAK,EAAE,cAAc,gBAAgB,EAAE,KAAK,CAAC;IAC7C,UAAU,EAAE,cAAc,6BAA6B,EAAE,UAAU,CAAC;IACpE,OAAO,EAAE,cAAc,2BAA2B,EAAE,OAAO,CAAC;CAC7D;AAGD,UAAU,oBAAoB;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAUD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAuB3D;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACpC,IAAI,CAKN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAS9D;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,IAAI,gBAAgB,EAChC,aAAa,IAAI,iBAAiB,EAClC,qBAAqB,EAEtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEpE,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,qBAAqB,GACtB,CAAC;AAGF,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,cAAc,gBAAgB,EAAE,YAAY,CAAC;IAC3D,aAAa,EAAE,cAAc,6CAA6C,EAAE,aAAa,CAAC;IAC1F,QAAQ,EAAE,cAAc,0BAA0B,EAAE,QAAQ,CAAC;IAC7D,GAAG,EAAE,cAAc,gBAAgB,EAAE,GAAG,CAAC;IACzC,WAAW,EAAE,cAAc,gBAAgB,EAAE,WAAW,CAAC;IACzD,KAAK,EAAE,cAAc,gBAAgB,EAAE,KAAK,CAAC;IAC7C,UAAU,EAAE,cAAc,6BAA6B,EAAE,UAAU,CAAC;IACpE,OAAO,EAAE,cAAc,2BAA2B,EAAE,OAAO,CAAC;CAC7D;AAGD,UAAU,oBAAoB;IAC5B,uBAAuB,EAAE,MAAM,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAUD;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAuB3D;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACpC,IAAI,CAKN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAS9D;AAsID;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAC9C,gBAAgB,CAAC,qBAAqB,CAAC,CACxC,CA0GA;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,aAAa,CAAC,CAK/D;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,kDAAoB,CAAC"}
|
package/esm/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,YAAY;AAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAuCxC,MAAM,mBAAmB,GAAyB;IAChD,uBAAuB,EAAE,GAAG,EAAE,gDAAgD;IAC9E,aAAa,EAAE,CAAC,EAAE,iDAAiD;IACnE,UAAU,EAAE,IAAI,EAAE,kEAAkE;IACpF,iBAAiB,EAAE,KAAK,EAAE,2BAA2B;CACtD,CAAC;AASF,yBAAyB;AACzB,IAAI,aAAwC,CAAC;AAC7C,IAAI,YAAiE,CAAC;AACtE,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAC1B,IAAI,cAAc,GAA+B,EAAE,CAAC;AACpD,IAAI,UAAU,GAAyB,mBAAmB,CAAC;AAC3D,IAAI,mBAA8C,CAAC;AAEnD;;GAEG;AACH,KAAK,UAAU,iBAAiB;IAC9B,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;QACnE,mEAAmE;QACnE,OAAO,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAkB,CAAC;IACnE,CAAC;SAAM,CAAC;QACN,kDAAkD;QAClD,OAAO,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAkB,CAAC;IACnE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAqC;IAErC,UAAU,GAAG,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC;IAC1C,MAAM,CAAC,IAAI,CAAC,0CAA0C,EAAE;QACtD,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;KACvC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAuB;IACtD,mBAAmB,GAAG,QAAQ,CAAC;IAC/B,yDAAyD;IACzD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CACT,yEAAyE,CAC1E,CAAC;QACF,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,oFAAoF;IACpF,MAAM,cAAc,GAAG,kBAAkB,CAAC;IAC1C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,YAAY;IACzB,IAAI,KAAK,GAAG,EAAE,CAAC;IAEf,8CAA8C;IAC9C,IAAI,mBAAmB,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0DAA0D,EAAE;gBACvE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;aACrB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,KAAK;YACH,OAAO,CAAC,GAAG,CAAC,6BAA6B;gBACzC,OAAO,CAAC,GAAG,CAAC,iBAAiB;gBAC7B,EAAE,CAAC;IACP,CAAC;IAED,4BAA4B;IAC5B,IAAI,KAAK,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,8CAA8C;QAC9C,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,8CAA8C;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,CAAC,IAAI,CACT,kEAAkE;YAChE,6EAA6E;YAC7E,oHAAoH,CACvH,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,YAAY;IACnB,2EAA2E;IAC3E,OACE,iBAAiB,GAAG,UAAU,CAAC,uBAAuB;QACtD,cAAc,CAAC,MAAM,GAAG,CAAC,EACzB,CAAC;QACD,MAAM,SAAS,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;QACzC,IAAI,SAAS,EAAE,CAAC;YACd,iBAAiB,EAAE,CAAC;YACpB,KAAK,SAAS,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC5B,iBAAiB,EAAE,CAAC;gBACpB,YAAY,EAAE,CAAC,CAAC,iDAAiD;YACnE,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,SAA2B,EAC3B,OAAO,GAAG,CAAC;IAEX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,gBAAgB,GAAG,KAAK,IAAmB,EAAE;YACjD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;gBACjC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,WAAW,GAAG,KAAK,YAAY,KAAK,IAAI,CAC5C,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;oBACpC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;oBACpC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;oBACtC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;oBACpC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;oBACnC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;oBACtC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;oBACxC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;oBACjC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,6BAA6B,CAAC;oBACrD,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC;oBACjD,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAC/B,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;oBACpC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;oBACzC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;oBACzC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;oBACzC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAC1C,CAAC;gBAEF,IAAI,OAAO,GAAG,UAAU,CAAC,aAAa,IAAI,WAAW,EAAE,CAAC;oBACtD,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;oBAC3D,MAAM,CAAC,IAAI,CACT,wCAAwC,KAAK,eAAe,OAAO,GAAG,CAAC,IAAI,UAAU,CAAC,aAAa,GAAG,EACtG,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAClE,CAAC;oBACF,UAAU,CAAC,GAAG,EAAE;wBACd,gBAAgB,CAAC,SAAS,EAAE,OAAO,GAAG,CAAC,CAAC;6BACrC,IAAI,CAAC,OAAO,CAAC;6BACb,KAAK,CAAC,MAAM,CAAC,CAAC;oBACnB,CAAC,EAAE,KAAK,CAAC,CAAC;gBACZ,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QAEF,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtC,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IAGnC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,CAAC;QACH,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAC5C,CAAC;QAED,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,GAClE,aAAa,CAAC;QAEhB,kCAAkC;QAClC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC;QAC3D,MAAM,OAAO,GACX,OAAO,CAAC,GAAG,CAAC,6BAA6B;YACzC,OAAO,CAAC,GAAG,CAAC,iBAAiB;YAC7B,CAAC,YAAY;gBACX,CAAC,CAAC,gCAAgC;gBAClC,CAAC,CAAC,+BAA+B,CAAC,CAAC;QAEvC,oEAAoE;QACpE,MAAM,gBAAgB,GAAG,IAAI,QAAQ,CAAC;YACpC,GAAG,EAAE,OAAO;YACZ,KAAK;YACL,YAAY,EAAE;gBACZ,OAAO,EAAE,UAAU,CAAC,iBAAiB;aACtC;SACF,CAAC,CAAC;QAEH,kEAAkE;QAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE;YACzD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC;YAC1C,kCAAkC;YAClC,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;YACnC,OAAO;gBACL,OAAO,EAAE;oBACP,GAAG,OAAO;oBACV,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE;oBAC7C,UAAU,EAAE,YAAY;iBACzB;aACF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,mDAAmD;QACnD,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,EAAE;YAC5D,IAAI,aAAa,EAAE,CAAC;gBAClB,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAO,EAAE,EAAE;oBAC1D,MAAM,CAAC,KAAK,CACV,6BAA6B,OAAO,eAAe,SAAS,WAAW,IAAI,EAAE,CAC9E,CAAC;gBACJ,CAAC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,CAAC,KAAK,CAAC,oBAAoB,YAAY,EAAE,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+DAA+D;QAC/D,MAAM,cAAc,GAAmB;YACrC,UAAU,EAAE;gBACV,WAAW,EAAE,mBAAmB;gBAChC,WAAW,EAAE,KAAK;aACnB;YACD,KAAK,EAAE;gBACL,WAAW,EAAE,cAAc;gBAC3B,WAAW,EAAE,KAAK;aACnB;YACD,MAAM,EAAE;gBACN,WAAW,EAAE,KAAK;aACnB;SACF,CAAC;QAEF,wDAAwD;QACxD,6EAA6E;QAC7E,YAAY,GAAG,IAAI,YAAY,CAAC;YAC9B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACzD,KAAK,EAAE,IAAI,aAAa,CAAC;gBACvB,oDAAoD;gBACpD,mEAAmE;gBACnE,YAAY,EAAE,EAAE;aACjB,CAAC;YACF,cAAc;YACd,QAAQ,EAAE;gBACR,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;aAC/C;SACF,CAAC,CAAC;QAEH,wEAAwE;QACxE,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5D,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE9D,YAAY,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE;YAC/B,OAAO,gBAAgB,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC;QAEF,YAAY,CAAC,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE;YAChC,OAAO,gBAAgB,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC;QAEF,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC3E,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,aAAa,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC"}
|
package/esm/client.mjs
CHANGED
|
@@ -137,12 +137,25 @@ async function enqueueOperation(operation, attempt = 0) {
|
|
|
137
137
|
resolve(result);
|
|
138
138
|
}
|
|
139
139
|
catch (error) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
const isRetryable = error instanceof Error && (error.message.includes('Accelerate') ||
|
|
141
|
+
error.message.includes('code: 1016') ||
|
|
142
|
+
error.message.includes('ECONNREFUSED') ||
|
|
143
|
+
error.message.includes('ECONNRESET') ||
|
|
144
|
+
error.message.includes('ETIMEDOUT') ||
|
|
145
|
+
error.message.includes('fetch failed') ||
|
|
146
|
+
error.message.includes('socket hang up') ||
|
|
147
|
+
error.message.includes('network') ||
|
|
148
|
+
error.message.includes("Can't reach database server") ||
|
|
149
|
+
error.message.includes('Connection pool timeout') ||
|
|
150
|
+
error.message.includes('P2024') ||
|
|
151
|
+
error.message.includes('terminated') ||
|
|
152
|
+
error.message.includes('status code 408') ||
|
|
153
|
+
error.message.includes('status code 502') ||
|
|
154
|
+
error.message.includes('status code 503') ||
|
|
155
|
+
error.message.includes('status code 504'));
|
|
156
|
+
if (attempt < poolConfig.retryAttempts && isRetryable) {
|
|
157
|
+
const delay = poolConfig.retryDelay * Math.pow(2, attempt);
|
|
158
|
+
logger.warn(`Apollo operation failed, retrying in ${delay}ms (attempt ${attempt + 1}/${poolConfig.retryAttempts})`, { error: error instanceof Error ? error.message : String(error) });
|
|
146
159
|
setTimeout(() => {
|
|
147
160
|
enqueueOperation(operation, attempt + 1)
|
|
148
161
|
.then(resolve)
|
package/esm/prismaClient.d.ts
CHANGED
|
@@ -6,5 +6,20 @@ declare global {
|
|
|
6
6
|
var prisma: PrismaClient | undefined;
|
|
7
7
|
}
|
|
8
8
|
declare const prisma: PrismaClient;
|
|
9
|
+
/**
|
|
10
|
+
* Starts the periodic database heartbeat monitor.
|
|
11
|
+
* Call once during server startup. The returned cleanup function
|
|
12
|
+
* must be called during graceful shutdown.
|
|
13
|
+
*/
|
|
14
|
+
export declare function startConnectionHealthMonitor(): () => void;
|
|
15
|
+
/**
|
|
16
|
+
* Stops the periodic heartbeat monitor. Safe to call multiple times.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stopConnectionHealthMonitor(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Disconnects the Prisma client with a timeout to prevent hanging during shutdown.
|
|
21
|
+
* @param timeoutMs - Maximum time to wait for disconnect (default: 5000ms)
|
|
22
|
+
*/
|
|
23
|
+
export declare function disconnectWithTimeout(timeoutMs?: number): Promise<void>;
|
|
9
24
|
export default prisma;
|
|
10
25
|
//# sourceMappingURL=prismaClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prismaClient.d.ts","sourceRoot":"","sources":["../../src/prismaClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CACtC;
|
|
1
|
+
{"version":3,"file":"prismaClient.d.ts","sourceRoot":"","sources":["../../src/prismaClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;CACtC;AA6LD,QAAA,MAAM,MAAM,EAAE,YAA4B,CAAC;AA+F3C;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,IAAI,CAgBzD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAMlD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3E;AAED,eAAe,MAAM,CAAC"}
|
package/esm/prismaClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prismaClient.js","sourceRoot":"","sources":["../../src/prismaClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAUxC;;;GAGG;AACH,MAAM,kBAAkB,GAA2B;IACjD,WAAW,EAAE,CAAC;IACd,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;CACf,CAAC;AAEF,0FAA0F;AAC1F,MAAM,uBAAuB,GAAG,KAAK,CAAC;AAEtC;;;;;;;;GAQG;AACH,SAAS,eAAe;IACtB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACnD,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,CAAC,IAAI,CACT,gEAAgE,EAChE;YACE,KAAK,EAAE,WAAW;SACnB,CACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa,CAAC;IACtD,OAAO,kBAAkB,CAAC,OAAO,CAAC,IAAI,kBAAkB,CAAC,WAAW,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB;IACzB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACxD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,CAAC,IAAI,CACT,iEAAiE,EACjE;YACE,KAAK,EAAE,UAAU;SAClB,CACF,CAAC;IACJ,CAAC;IACD,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,gBAAgB;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,WAAW,GAAG,kBAAkB,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAEpD,MAAM,CAAC,IAAI,CAAC,qCAAqC,EAAE;QACjD,QAAQ;QACR,aAAa,EAAE,WAAW;QAC1B,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;KACnD,CAAC,CAAC;IAEH,OAAO,GAAG,OAAO,GAAG,SAAS,oBAAoB,QAAQ,iBAAiB,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"prismaClient.js","sourceRoot":"","sources":["../../src/prismaClient.ts"],"names":[],"mappings":"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"}
|
package/esm/prismaClient.mjs
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { PrismaClient } from '@prisma/client';
|
|
2
2
|
import { logger } from './utils/logger.mjs';
|
|
3
|
+
/** Default statement timeout (30s) prevents hung queries from blocking pool slots indefinitely */
|
|
4
|
+
const DEFAULT_STATEMENT_TIMEOUT_MS = 30000;
|
|
5
|
+
/** Heartbeat interval: how often we verify the DB connection is alive */
|
|
6
|
+
const HEARTBEAT_INTERVAL_MS = 30000;
|
|
7
|
+
/** Consecutive heartbeat failures before triggering client reconnection */
|
|
8
|
+
const MAX_HEARTBEAT_FAILURES = 3;
|
|
9
|
+
/** Heartbeat query timeout (5s) — shorter than pool timeout to detect issues early */
|
|
10
|
+
const HEARTBEAT_TIMEOUT_MS = 5000;
|
|
3
11
|
/**
|
|
4
12
|
* Connection pool size defaults per deployment tier.
|
|
5
13
|
* Can be overridden via the DATABASE_POOL_SIZE environment variable.
|
|
@@ -76,7 +84,8 @@ function buildDatabaseUrl() {
|
|
|
76
84
|
poolTimeoutMs: poolTimeout,
|
|
77
85
|
environment: process.env.NODE_ENV || 'development',
|
|
78
86
|
});
|
|
79
|
-
|
|
87
|
+
const statementTimeoutMs = parseInt(process.env.DATABASE_STATEMENT_TIMEOUT_MS || String(DEFAULT_STATEMENT_TIMEOUT_MS), 10);
|
|
88
|
+
return `${baseUrl}${separator}connection_limit=${poolSize}&pool_timeout=${Math.floor(poolTimeout / 1000)}&statement_timeout=${statementTimeoutMs}&idle_in_transaction_session_timeout=${statementTimeoutMs}`;
|
|
80
89
|
}
|
|
81
90
|
// Create a singleton that works in all environments
|
|
82
91
|
if (!global.prisma) {
|
|
@@ -146,5 +155,141 @@ if (!global.prisma) {
|
|
|
146
155
|
}
|
|
147
156
|
// Initialize a singleton PrismaClient with a connection pool that persists across requests
|
|
148
157
|
const prisma = global.prisma;
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// Connection health monitor — detects stale connections before they cause
|
|
160
|
+
// query hangs by periodically running a lightweight heartbeat query.
|
|
161
|
+
// After MAX_HEARTBEAT_FAILURES consecutive failures, the client is
|
|
162
|
+
// disconnected and reconnected to force Prisma to establish fresh connections.
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
let heartbeatFailures = 0;
|
|
165
|
+
let heartbeatTimer;
|
|
166
|
+
let isReconnecting = false;
|
|
167
|
+
async function heartbeat() {
|
|
168
|
+
if (isReconnecting || !global.prisma)
|
|
169
|
+
return;
|
|
170
|
+
try {
|
|
171
|
+
const start = Date.now();
|
|
172
|
+
await Promise.race([
|
|
173
|
+
global.prisma.$queryRaw `SELECT 1`,
|
|
174
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Heartbeat timeout')), HEARTBEAT_TIMEOUT_MS)),
|
|
175
|
+
]);
|
|
176
|
+
const latencyMs = Date.now() - start;
|
|
177
|
+
if (heartbeatFailures > 0) {
|
|
178
|
+
logger.info('Database heartbeat recovered', { latencyMs, previousFailures: heartbeatFailures });
|
|
179
|
+
}
|
|
180
|
+
heartbeatFailures = 0;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
heartbeatFailures++;
|
|
184
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
185
|
+
logger.warn('Database heartbeat failed', {
|
|
186
|
+
consecutiveFailures: heartbeatFailures,
|
|
187
|
+
error: errorMessage,
|
|
188
|
+
});
|
|
189
|
+
if (heartbeatFailures >= MAX_HEARTBEAT_FAILURES) {
|
|
190
|
+
logger.error('Database heartbeat exceeded failure threshold, reconnecting Prisma client', {
|
|
191
|
+
consecutiveFailures: heartbeatFailures,
|
|
192
|
+
});
|
|
193
|
+
await reconnectPrisma();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async function reconnectPrisma() {
|
|
198
|
+
if (isReconnecting)
|
|
199
|
+
return;
|
|
200
|
+
isReconnecting = true;
|
|
201
|
+
try {
|
|
202
|
+
// Disconnect existing client — this drops all pooled connections
|
|
203
|
+
try {
|
|
204
|
+
await Promise.race([
|
|
205
|
+
global.prisma?.$disconnect(),
|
|
206
|
+
new Promise((resolve) => setTimeout(resolve, 5000)),
|
|
207
|
+
]);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Disconnect may fail if DB is unreachable — that's expected
|
|
211
|
+
}
|
|
212
|
+
// Create a fresh client with the same configuration
|
|
213
|
+
const newClient = new PrismaClient({
|
|
214
|
+
log: [
|
|
215
|
+
{ level: 'error', emit: 'event' },
|
|
216
|
+
{ level: 'warn', emit: 'event' },
|
|
217
|
+
],
|
|
218
|
+
datasources: {
|
|
219
|
+
db: {
|
|
220
|
+
url: buildDatabaseUrl(),
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
// Re-register error/warn handlers
|
|
225
|
+
newClient.$on('error', (e) => {
|
|
226
|
+
logger.error('Prisma client error (reconnected)', { message: e.message, timestamp: e.timestamp });
|
|
227
|
+
});
|
|
228
|
+
newClient.$on('warn', (e) => {
|
|
229
|
+
logger.warn('Prisma client warning (reconnected)', { message: e.message });
|
|
230
|
+
});
|
|
231
|
+
global.prisma = newClient;
|
|
232
|
+
heartbeatFailures = 0;
|
|
233
|
+
logger.info('Prisma client reconnected successfully');
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
logger.error('Failed to reconnect Prisma client', {
|
|
237
|
+
error: error instanceof Error ? error.message : String(error),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
isReconnecting = false;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Starts the periodic database heartbeat monitor.
|
|
246
|
+
* Call once during server startup. The returned cleanup function
|
|
247
|
+
* must be called during graceful shutdown.
|
|
248
|
+
*/
|
|
249
|
+
export function startConnectionHealthMonitor() {
|
|
250
|
+
if (heartbeatTimer)
|
|
251
|
+
return () => stopConnectionHealthMonitor();
|
|
252
|
+
logger.info('Starting database connection health monitor', {
|
|
253
|
+
intervalMs: HEARTBEAT_INTERVAL_MS,
|
|
254
|
+
failureThreshold: MAX_HEARTBEAT_FAILURES,
|
|
255
|
+
});
|
|
256
|
+
heartbeatTimer = setInterval(() => {
|
|
257
|
+
void heartbeat();
|
|
258
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
259
|
+
// Run an initial heartbeat immediately
|
|
260
|
+
void heartbeat();
|
|
261
|
+
return () => stopConnectionHealthMonitor();
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Stops the periodic heartbeat monitor. Safe to call multiple times.
|
|
265
|
+
*/
|
|
266
|
+
export function stopConnectionHealthMonitor() {
|
|
267
|
+
if (heartbeatTimer) {
|
|
268
|
+
clearInterval(heartbeatTimer);
|
|
269
|
+
heartbeatTimer = undefined;
|
|
270
|
+
logger.info('Database connection health monitor stopped');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Disconnects the Prisma client with a timeout to prevent hanging during shutdown.
|
|
275
|
+
* @param timeoutMs - Maximum time to wait for disconnect (default: 5000ms)
|
|
276
|
+
*/
|
|
277
|
+
export async function disconnectWithTimeout(timeoutMs = 5000) {
|
|
278
|
+
stopConnectionHealthMonitor();
|
|
279
|
+
if (!global.prisma)
|
|
280
|
+
return;
|
|
281
|
+
try {
|
|
282
|
+
await Promise.race([
|
|
283
|
+
global.prisma.$disconnect(),
|
|
284
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Prisma disconnect timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
285
|
+
]);
|
|
286
|
+
logger.info('Database connections closed successfully');
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
logger.warn('Database disconnect did not complete cleanly', {
|
|
290
|
+
error: error instanceof Error ? error.message : String(error),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
149
294
|
export default prisma;
|
|
150
295
|
//# sourceMappingURL=prismaClient.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptic/backend-legacy",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.917",
|
|
4
4
|
"description": "Backend executable CRUD functions with dynamic variables construction, and type definitions for the Adaptic AI platform.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "index.d.ts",
|
package/prismaClient.cjs
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startConnectionHealthMonitor = startConnectionHealthMonitor;
|
|
4
|
+
exports.stopConnectionHealthMonitor = stopConnectionHealthMonitor;
|
|
5
|
+
exports.disconnectWithTimeout = disconnectWithTimeout;
|
|
3
6
|
const client_1 = require("@prisma/client");
|
|
4
7
|
const logger_1 = require("./utils/logger");
|
|
8
|
+
/** Default statement timeout (30s) prevents hung queries from blocking pool slots indefinitely */
|
|
9
|
+
const DEFAULT_STATEMENT_TIMEOUT_MS = 30000;
|
|
10
|
+
/** Heartbeat interval: how often we verify the DB connection is alive */
|
|
11
|
+
const HEARTBEAT_INTERVAL_MS = 30000;
|
|
12
|
+
/** Consecutive heartbeat failures before triggering client reconnection */
|
|
13
|
+
const MAX_HEARTBEAT_FAILURES = 3;
|
|
14
|
+
/** Heartbeat query timeout (5s) — shorter than pool timeout to detect issues early */
|
|
15
|
+
const HEARTBEAT_TIMEOUT_MS = 5000;
|
|
5
16
|
/**
|
|
6
17
|
* Connection pool size defaults per deployment tier.
|
|
7
18
|
* Can be overridden via the DATABASE_POOL_SIZE environment variable.
|
|
@@ -78,7 +89,8 @@ function buildDatabaseUrl() {
|
|
|
78
89
|
poolTimeoutMs: poolTimeout,
|
|
79
90
|
environment: process.env.NODE_ENV || 'development',
|
|
80
91
|
});
|
|
81
|
-
|
|
92
|
+
const statementTimeoutMs = parseInt(process.env.DATABASE_STATEMENT_TIMEOUT_MS || String(DEFAULT_STATEMENT_TIMEOUT_MS), 10);
|
|
93
|
+
return `${baseUrl}${separator}connection_limit=${poolSize}&pool_timeout=${Math.floor(poolTimeout / 1000)}&statement_timeout=${statementTimeoutMs}&idle_in_transaction_session_timeout=${statementTimeoutMs}`;
|
|
82
94
|
}
|
|
83
95
|
// Create a singleton that works in all environments
|
|
84
96
|
if (!global.prisma) {
|
|
@@ -148,5 +160,142 @@ if (!global.prisma) {
|
|
|
148
160
|
}
|
|
149
161
|
// Initialize a singleton PrismaClient with a connection pool that persists across requests
|
|
150
162
|
const prisma = global.prisma;
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
// Connection health monitor — detects stale connections before they cause
|
|
165
|
+
// query hangs by periodically running a lightweight heartbeat query.
|
|
166
|
+
// After MAX_HEARTBEAT_FAILURES consecutive failures, the client is
|
|
167
|
+
// disconnected and reconnected to force Prisma to establish fresh connections.
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
let heartbeatFailures = 0;
|
|
170
|
+
let heartbeatTimer;
|
|
171
|
+
let isReconnecting = false;
|
|
172
|
+
async function heartbeat() {
|
|
173
|
+
if (isReconnecting || !global.prisma)
|
|
174
|
+
return;
|
|
175
|
+
try {
|
|
176
|
+
const start = Date.now();
|
|
177
|
+
await Promise.race([
|
|
178
|
+
global.prisma.$queryRaw `SELECT 1`,
|
|
179
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Heartbeat timeout')), HEARTBEAT_TIMEOUT_MS)),
|
|
180
|
+
]);
|
|
181
|
+
const latencyMs = Date.now() - start;
|
|
182
|
+
if (heartbeatFailures > 0) {
|
|
183
|
+
logger_1.logger.info('Database heartbeat recovered', { latencyMs, previousFailures: heartbeatFailures });
|
|
184
|
+
}
|
|
185
|
+
heartbeatFailures = 0;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
heartbeatFailures++;
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
190
|
+
logger_1.logger.warn('Database heartbeat failed', {
|
|
191
|
+
consecutiveFailures: heartbeatFailures,
|
|
192
|
+
error: errorMessage,
|
|
193
|
+
});
|
|
194
|
+
if (heartbeatFailures >= MAX_HEARTBEAT_FAILURES) {
|
|
195
|
+
logger_1.logger.error('Database heartbeat exceeded failure threshold, reconnecting Prisma client', {
|
|
196
|
+
consecutiveFailures: heartbeatFailures,
|
|
197
|
+
});
|
|
198
|
+
await reconnectPrisma();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
async function reconnectPrisma() {
|
|
203
|
+
var _a;
|
|
204
|
+
if (isReconnecting)
|
|
205
|
+
return;
|
|
206
|
+
isReconnecting = true;
|
|
207
|
+
try {
|
|
208
|
+
// Disconnect existing client — this drops all pooled connections
|
|
209
|
+
try {
|
|
210
|
+
await Promise.race([
|
|
211
|
+
(_a = global.prisma) === null || _a === void 0 ? void 0 : _a.$disconnect(),
|
|
212
|
+
new Promise((resolve) => setTimeout(resolve, 5000)),
|
|
213
|
+
]);
|
|
214
|
+
}
|
|
215
|
+
catch (_b) {
|
|
216
|
+
// Disconnect may fail if DB is unreachable — that's expected
|
|
217
|
+
}
|
|
218
|
+
// Create a fresh client with the same configuration
|
|
219
|
+
const newClient = new client_1.PrismaClient({
|
|
220
|
+
log: [
|
|
221
|
+
{ level: 'error', emit: 'event' },
|
|
222
|
+
{ level: 'warn', emit: 'event' },
|
|
223
|
+
],
|
|
224
|
+
datasources: {
|
|
225
|
+
db: {
|
|
226
|
+
url: buildDatabaseUrl(),
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
// Re-register error/warn handlers
|
|
231
|
+
newClient.$on('error', (e) => {
|
|
232
|
+
logger_1.logger.error('Prisma client error (reconnected)', { message: e.message, timestamp: e.timestamp });
|
|
233
|
+
});
|
|
234
|
+
newClient.$on('warn', (e) => {
|
|
235
|
+
logger_1.logger.warn('Prisma client warning (reconnected)', { message: e.message });
|
|
236
|
+
});
|
|
237
|
+
global.prisma = newClient;
|
|
238
|
+
heartbeatFailures = 0;
|
|
239
|
+
logger_1.logger.info('Prisma client reconnected successfully');
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
logger_1.logger.error('Failed to reconnect Prisma client', {
|
|
243
|
+
error: error instanceof Error ? error.message : String(error),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
finally {
|
|
247
|
+
isReconnecting = false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Starts the periodic database heartbeat monitor.
|
|
252
|
+
* Call once during server startup. The returned cleanup function
|
|
253
|
+
* must be called during graceful shutdown.
|
|
254
|
+
*/
|
|
255
|
+
function startConnectionHealthMonitor() {
|
|
256
|
+
if (heartbeatTimer)
|
|
257
|
+
return () => stopConnectionHealthMonitor();
|
|
258
|
+
logger_1.logger.info('Starting database connection health monitor', {
|
|
259
|
+
intervalMs: HEARTBEAT_INTERVAL_MS,
|
|
260
|
+
failureThreshold: MAX_HEARTBEAT_FAILURES,
|
|
261
|
+
});
|
|
262
|
+
heartbeatTimer = setInterval(() => {
|
|
263
|
+
void heartbeat();
|
|
264
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
265
|
+
// Run an initial heartbeat immediately
|
|
266
|
+
void heartbeat();
|
|
267
|
+
return () => stopConnectionHealthMonitor();
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Stops the periodic heartbeat monitor. Safe to call multiple times.
|
|
271
|
+
*/
|
|
272
|
+
function stopConnectionHealthMonitor() {
|
|
273
|
+
if (heartbeatTimer) {
|
|
274
|
+
clearInterval(heartbeatTimer);
|
|
275
|
+
heartbeatTimer = undefined;
|
|
276
|
+
logger_1.logger.info('Database connection health monitor stopped');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Disconnects the Prisma client with a timeout to prevent hanging during shutdown.
|
|
281
|
+
* @param timeoutMs - Maximum time to wait for disconnect (default: 5000ms)
|
|
282
|
+
*/
|
|
283
|
+
async function disconnectWithTimeout(timeoutMs = 5000) {
|
|
284
|
+
stopConnectionHealthMonitor();
|
|
285
|
+
if (!global.prisma)
|
|
286
|
+
return;
|
|
287
|
+
try {
|
|
288
|
+
await Promise.race([
|
|
289
|
+
global.prisma.$disconnect(),
|
|
290
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Prisma disconnect timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
291
|
+
]);
|
|
292
|
+
logger_1.logger.info('Database connections closed successfully');
|
|
293
|
+
}
|
|
294
|
+
catch (error) {
|
|
295
|
+
logger_1.logger.warn('Database disconnect did not complete cleanly', {
|
|
296
|
+
error: error instanceof Error ? error.message : String(error),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
151
300
|
exports.default = prisma;
|
|
152
301
|
//# sourceMappingURL=prismaClient.js.map
|
package/prismaClient.d.ts
CHANGED
|
@@ -6,5 +6,20 @@ declare global {
|
|
|
6
6
|
var prisma: PrismaClient | undefined;
|
|
7
7
|
}
|
|
8
8
|
declare const prisma: PrismaClient;
|
|
9
|
+
/**
|
|
10
|
+
* Starts the periodic database heartbeat monitor.
|
|
11
|
+
* Call once during server startup. The returned cleanup function
|
|
12
|
+
* must be called during graceful shutdown.
|
|
13
|
+
*/
|
|
14
|
+
export declare function startConnectionHealthMonitor(): () => void;
|
|
15
|
+
/**
|
|
16
|
+
* Stops the periodic heartbeat monitor. Safe to call multiple times.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stopConnectionHealthMonitor(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Disconnects the Prisma client with a timeout to prevent hanging during shutdown.
|
|
21
|
+
* @param timeoutMs - Maximum time to wait for disconnect (default: 5000ms)
|
|
22
|
+
*/
|
|
23
|
+
export declare function disconnectWithTimeout(timeoutMs?: number): Promise<void>;
|
|
9
24
|
export default prisma;
|
|
10
25
|
//# sourceMappingURL=prismaClient.d.ts.map
|
package/server.cjs
CHANGED
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -22,10 +55,11 @@ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
|
22
55
|
const auth_1 = require("./middleware/auth.cjs");
|
|
23
56
|
const audit_logger_1 = require("./middleware/audit-logger.cjs");
|
|
24
57
|
const jwtConfig_1 = require("./config/jwtConfig.cjs");
|
|
25
|
-
const prismaClient_1 =
|
|
58
|
+
const prismaClient_1 = __importStar(require("./prismaClient.cjs"));
|
|
26
59
|
const health_1 = require("./health.cjs");
|
|
27
60
|
const child_process_1 = require("child_process");
|
|
28
61
|
const logger_1 = require("./utils/logger.cjs");
|
|
62
|
+
const tracing_1 = require("./config/tracing.cjs");
|
|
29
63
|
let dbUnreachableCount = 0;
|
|
30
64
|
let lastRestartAttempt = 0;
|
|
31
65
|
async function restartDatabase() {
|
|
@@ -82,37 +116,14 @@ const startServer = async () => {
|
|
|
82
116
|
// If we've hit 3 (for example) attempts
|
|
83
117
|
if (dbUnreachableCount >= 3) {
|
|
84
118
|
const now = Date.now();
|
|
85
|
-
// Optional: Check if we've tried restarting recently
|
|
86
119
|
if (now - lastRestartAttempt > 5 * 60 * 1000) {
|
|
87
120
|
lastRestartAttempt = now;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// Reset the counter after attempting a restart
|
|
91
|
-
dbUnreachableCount = 0;
|
|
92
|
-
}
|
|
93
|
-
catch (restartError) {
|
|
121
|
+
dbUnreachableCount = 0;
|
|
122
|
+
restartDatabase().catch((restartError) => {
|
|
94
123
|
logger_1.logger.error('Error trying to restart DB', {
|
|
95
124
|
restartError: String(restartError),
|
|
96
125
|
});
|
|
97
|
-
|
|
98
|
-
const backoffTime = Math.min(30000, 1000 * Math.pow(2, dbUnreachableCount - 3)); // Exponential backoff with a max of 30 seconds
|
|
99
|
-
logger_1.logger.info('Waiting before next restart attempt', {
|
|
100
|
-
backoffSeconds: backoffTime / 1000,
|
|
101
|
-
});
|
|
102
|
-
setTimeout(() => {
|
|
103
|
-
restartDatabase()
|
|
104
|
-
.then(() => {
|
|
105
|
-
dbUnreachableCount = 0; // Reset the counter after a successful restart
|
|
106
|
-
})
|
|
107
|
-
.catch((restartError) => {
|
|
108
|
-
logger_1.logger.error('Error trying to restart DB', {
|
|
109
|
-
restartError: String(restartError),
|
|
110
|
-
});
|
|
111
|
-
// We do not reset the counter here if the restart fails,
|
|
112
|
-
// so it can try again next time.
|
|
113
|
-
});
|
|
114
|
-
}, backoffTime);
|
|
115
|
-
}
|
|
126
|
+
});
|
|
116
127
|
}
|
|
117
128
|
}
|
|
118
129
|
}
|
|
@@ -284,6 +295,8 @@ const startServer = async () => {
|
|
|
284
295
|
return { prisma: global.prisma, user };
|
|
285
296
|
},
|
|
286
297
|
}, wsServer);
|
|
298
|
+
// Start the periodic database connection health monitor
|
|
299
|
+
(0, prismaClient_1.startConnectionHealthMonitor)();
|
|
287
300
|
const PORT = process.env.PORT || 4000;
|
|
288
301
|
httpServer.listen(PORT, () => {
|
|
289
302
|
logger_1.logger.info('Server ready', {
|
|
@@ -294,6 +307,56 @@ const startServer = async () => {
|
|
|
294
307
|
endpoint: `ws://localhost:${PORT}/subscriptions`,
|
|
295
308
|
});
|
|
296
309
|
});
|
|
310
|
+
// --- Graceful shutdown ---
|
|
311
|
+
// Sequence: stop accepting connections → drain in-flight requests →
|
|
312
|
+
// close WebSocket → disconnect DB → flush traces → exit
|
|
313
|
+
let isShuttingDown = false;
|
|
314
|
+
const SHUTDOWN_TIMEOUT_MS = 15000;
|
|
315
|
+
async function gracefulShutdown(signal) {
|
|
316
|
+
if (isShuttingDown)
|
|
317
|
+
return;
|
|
318
|
+
isShuttingDown = true;
|
|
319
|
+
logger_1.logger.info(`Received ${signal}, starting graceful shutdown`);
|
|
320
|
+
// Force exit if shutdown takes too long
|
|
321
|
+
const forceExitTimer = setTimeout(() => {
|
|
322
|
+
logger_1.logger.error('Graceful shutdown timed out, forcing exit');
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}, SHUTDOWN_TIMEOUT_MS);
|
|
325
|
+
forceExitTimer.unref();
|
|
326
|
+
try {
|
|
327
|
+
// 1. Stop accepting new HTTP connections
|
|
328
|
+
await new Promise((resolve) => {
|
|
329
|
+
httpServer.close(() => {
|
|
330
|
+
logger_1.logger.info('HTTP server closed');
|
|
331
|
+
resolve();
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
// 2. Close WebSocket server (rejects new WS connections)
|
|
335
|
+
await new Promise((resolve) => {
|
|
336
|
+
wsServer.close(() => {
|
|
337
|
+
logger_1.logger.info('WebSocket server closed');
|
|
338
|
+
resolve();
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
// 3. Apollo Server drain is handled by ApolloServerPluginDrainHttpServer
|
|
342
|
+
// 4. Stop health monitor and disconnect DB with timeout
|
|
343
|
+
await (0, prismaClient_1.disconnectWithTimeout)(5000);
|
|
344
|
+
// 5. Flush OpenTelemetry traces
|
|
345
|
+
await (0, tracing_1.shutdownTracing)();
|
|
346
|
+
logger_1.logger.info('Graceful shutdown complete');
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
logger_1.logger.error('Error during graceful shutdown', {
|
|
350
|
+
error: error instanceof Error ? error.message : String(error),
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
finally {
|
|
354
|
+
clearTimeout(forceExitTimer);
|
|
355
|
+
process.exit(0);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
process.on('SIGINT', () => { void gracefulShutdown('SIGINT'); });
|
|
359
|
+
process.on('SIGTERM', () => { void gracefulShutdown('SIGTERM'); });
|
|
297
360
|
};
|
|
298
361
|
startServer().catch((error) => {
|
|
299
362
|
logger_1.logger.error('Error starting the server', {
|
|
@@ -312,34 +375,4 @@ process.on('uncaughtException', (error) => {
|
|
|
312
375
|
stack: error.stack,
|
|
313
376
|
});
|
|
314
377
|
});
|
|
315
|
-
// Only disconnect Prisma when the process is truly shutting down
|
|
316
|
-
process.on('SIGINT', async () => {
|
|
317
|
-
var _a;
|
|
318
|
-
logger_1.logger.info('Gracefully shutting down and closing database connections');
|
|
319
|
-
try {
|
|
320
|
-
await ((_a = global.prisma) === null || _a === void 0 ? void 0 : _a.$disconnect());
|
|
321
|
-
logger_1.logger.info('Database connections closed successfully');
|
|
322
|
-
}
|
|
323
|
-
catch (e) {
|
|
324
|
-
logger_1.logger.error('Error disconnecting from database', {
|
|
325
|
-
error: e instanceof Error ? e.message : String(e),
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
process.exit(0);
|
|
329
|
-
});
|
|
330
|
-
// Also handle SIGTERM for containerized environments
|
|
331
|
-
process.on('SIGTERM', async () => {
|
|
332
|
-
var _a;
|
|
333
|
-
logger_1.logger.info('Received SIGTERM, gracefully shutting down');
|
|
334
|
-
try {
|
|
335
|
-
await ((_a = global.prisma) === null || _a === void 0 ? void 0 : _a.$disconnect());
|
|
336
|
-
logger_1.logger.info('Database connections closed successfully');
|
|
337
|
-
}
|
|
338
|
-
catch (e) {
|
|
339
|
-
logger_1.logger.error('Error disconnecting from database', {
|
|
340
|
-
error: e instanceof Error ? e.message : String(e),
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
process.exit(0);
|
|
344
|
-
});
|
|
345
378
|
//# sourceMappingURL=server.js.map
|