@spfn/core 0.2.0-beta.17 → 0.2.0-beta.18

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/dist/db/index.js CHANGED
@@ -503,6 +503,8 @@ var setMonitoringConfig = (config) => {
503
503
  globalThis.__SPFN_DB_MONITORING__ = config;
504
504
  };
505
505
  var dbLogger3 = logger.child("@spfn/core:database");
506
+ var CLIENT_CLOSE_TIMEOUT = 5;
507
+ var isReconnecting = false;
506
508
  async function testDatabaseConnection(db) {
507
509
  await db.execute("SELECT 1");
508
510
  }
@@ -514,8 +516,13 @@ async function performHealthCheck(getDatabase2) {
514
516
  await testDatabaseConnection(read);
515
517
  }
516
518
  }
517
- async function reconnectAndRestore(options, closeDatabase2) {
518
- await closeDatabase2();
519
+ async function closeClient(client) {
520
+ try {
521
+ await client.end({ timeout: CLIENT_CLOSE_TIMEOUT });
522
+ } catch {
523
+ }
524
+ }
525
+ async function reconnectAndRestore(options) {
519
526
  const result = await createDatabaseFromEnv(options);
520
527
  if (!result.write) {
521
528
  return false;
@@ -524,15 +531,23 @@ async function reconnectAndRestore(options, closeDatabase2) {
524
531
  if (result.read && result.read !== result.write) {
525
532
  await testDatabaseConnection(result.read);
526
533
  }
534
+ const oldWriteClient = getWriteClient();
535
+ const oldReadClient = getReadClient();
527
536
  setWriteInstance(result.write);
528
537
  setReadInstance(result.read);
529
538
  setWriteClient(result.writeClient);
530
539
  setReadClient(result.readClient);
531
540
  const monConfig = buildMonitoringConfig(options?.monitoring);
532
541
  setMonitoringConfig(monConfig);
542
+ if (oldWriteClient) {
543
+ closeClient(oldWriteClient);
544
+ }
545
+ if (oldReadClient && oldReadClient !== oldWriteClient) {
546
+ closeClient(oldReadClient);
547
+ }
533
548
  return true;
534
549
  }
535
- function startHealthCheck(config, options, getDatabase2, closeDatabase2) {
550
+ function startHealthCheck(config, options, getDatabase2) {
536
551
  const healthCheck = getHealthCheckInterval();
537
552
  if (healthCheck) {
538
553
  dbLogger3.debug("Health check already running");
@@ -543,47 +558,56 @@ function startHealthCheck(config, options, getDatabase2, closeDatabase2) {
543
558
  reconnect: config.reconnect
544
559
  });
545
560
  const interval = setInterval(async () => {
561
+ if (isReconnecting) {
562
+ dbLogger3.debug("Health check skipped: reconnection in progress");
563
+ return;
564
+ }
546
565
  try {
547
566
  await performHealthCheck(getDatabase2);
548
567
  } catch (error) {
549
568
  const message = error instanceof Error ? error.message : "Unknown error";
550
569
  dbLogger3.error("Database health check failed", { error: message });
551
570
  if (config.reconnect) {
552
- await attemptReconnection(config, options, closeDatabase2);
571
+ await attemptReconnection(config, options);
553
572
  }
554
573
  }
555
574
  }, config.interval);
556
575
  setHealthCheckInterval(interval);
557
576
  }
558
- async function attemptReconnection(config, options, closeDatabase2) {
577
+ async function attemptReconnection(config, options) {
578
+ isReconnecting = true;
559
579
  dbLogger3.warn("Attempting database reconnection", {
560
580
  maxRetries: config.maxRetries,
561
581
  retryInterval: `${config.retryInterval}ms`
562
582
  });
563
- for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
564
- try {
565
- dbLogger3.debug(`Reconnection attempt ${attempt}/${config.maxRetries}`);
566
- if (attempt > 1) {
567
- await new Promise((resolve) => setTimeout(resolve, config.retryInterval));
583
+ try {
584
+ for (let attempt = 1; attempt <= config.maxRetries; attempt++) {
585
+ try {
586
+ dbLogger3.debug(`Reconnection attempt ${attempt}/${config.maxRetries}`);
587
+ if (attempt > 1) {
588
+ await new Promise((resolve) => setTimeout(resolve, config.retryInterval));
589
+ }
590
+ const success = await reconnectAndRestore(options);
591
+ if (success) {
592
+ dbLogger3.info("Database reconnection successful", { attempt });
593
+ return;
594
+ } else {
595
+ dbLogger3.error(`Reconnection attempt ${attempt} failed: No write database instance created`);
596
+ }
597
+ } catch (error) {
598
+ const message = error instanceof Error ? error.message : "Unknown error";
599
+ dbLogger3.error(`Reconnection attempt ${attempt} failed`, {
600
+ error: message,
601
+ attempt,
602
+ maxRetries: config.maxRetries
603
+ });
568
604
  }
569
- const success = await reconnectAndRestore(options, closeDatabase2);
570
- if (success) {
571
- dbLogger3.info("Database reconnection successful", { attempt });
572
- return;
573
- } else {
574
- dbLogger3.error(`Reconnection attempt ${attempt} failed: No write database instance created`);
605
+ if (attempt === config.maxRetries) {
606
+ dbLogger3.error("Max reconnection attempts reached, will retry on next health check");
575
607
  }
576
- } catch (error) {
577
- const message = error instanceof Error ? error.message : "Unknown error";
578
- dbLogger3.error(`Reconnection attempt ${attempt} failed`, {
579
- error: message,
580
- attempt,
581
- maxRetries: config.maxRetries
582
- });
583
- }
584
- if (attempt === config.maxRetries) {
585
- dbLogger3.error("Max reconnection attempts reached, giving up");
586
608
  }
609
+ } finally {
610
+ isReconnecting = false;
587
611
  }
588
612
  }
589
613
  function stopHealthCheck() {
@@ -593,6 +617,7 @@ function stopHealthCheck() {
593
617
  setHealthCheckInterval(void 0);
594
618
  dbLogger3.info("Database health check stopped");
595
619
  }
620
+ isReconnecting = false;
596
621
  }
597
622
 
598
623
  // src/db/manager/manager.ts
@@ -742,7 +767,7 @@ async function initDatabase(options) {
742
767
  );
743
768
  const healthCheckConfig = buildHealthCheckConfig(options?.healthCheck);
744
769
  if (healthCheckConfig.enabled) {
745
- startHealthCheck(healthCheckConfig, options, getDatabase, closeDatabase);
770
+ startHealthCheck(healthCheckConfig, options, getDatabase);
746
771
  }
747
772
  const monConfig = buildMonitoringConfig(options?.monitoring);
748
773
  setMonitoringConfig(monConfig);