@nmakarov/cli-toolkit 0.53.0 → 0.55.0

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/index.js CHANGED
@@ -5587,6 +5587,16 @@ async function pruneReleases(service, paths, options = {}) {
5587
5587
  function sleep(ms) {
5588
5588
  return new Promise((resolve3) => setTimeout(resolve3, ms));
5589
5589
  }
5590
+ function isPidAlive(pid) {
5591
+ const n = Number(pid);
5592
+ if (!Number.isFinite(n) || n <= 0) return false;
5593
+ try {
5594
+ process.kill(n, 0);
5595
+ return true;
5596
+ } catch {
5597
+ return false;
5598
+ }
5599
+ }
5590
5600
  async function getPm2Process(appName, options = {}) {
5591
5601
  const { logger } = options;
5592
5602
  const { stdout } = await runCapture("bash", ["-lc", "pm2 jlist"], { logger });
@@ -5623,21 +5633,44 @@ async function waitPm2(appName, predicate, options = {}) {
5623
5633
  `pm2 wait timed out after ${timeoutMs}ms for ${appName} (${label}); last status=${lastStatus}`
5624
5634
  );
5625
5635
  }
5636
+ function isFreshOnline(proc, oldPid) {
5637
+ if (proc?.pm2_env?.status !== "online") return false;
5638
+ const pid = Number(proc.pid);
5639
+ if (!Number.isFinite(pid) || pid <= 0) return false;
5640
+ if (oldPid != null) {
5641
+ if (pid === oldPid) return false;
5642
+ if (isPidAlive(oldPid)) return false;
5643
+ }
5644
+ return true;
5645
+ }
5626
5646
  async function reloadPm2(paths, options = {}) {
5627
5647
  const { dryRun = false, logger = console, appName = null, waitTimeoutMs = 65e3 } = options;
5628
5648
  if (dryRun) {
5629
5649
  logger.info(`[dryRun] would pm2 startOrReload ${paths.ecosystem} --update-env`);
5630
5650
  return;
5631
5651
  }
5652
+ let oldPid = null;
5653
+ if (appName) {
5654
+ const before = await getPm2Process(appName, { logger });
5655
+ const n = Number(before?.pid);
5656
+ if (Number.isFinite(n) && n > 0 && before?.pm2_env?.status === "online") {
5657
+ oldPid = n;
5658
+ logger.info(`pm2 ${appName}: reloading (old pid=${oldPid})`);
5659
+ }
5660
+ }
5632
5661
  await runShell(`pm2 startOrReload "${paths.ecosystem}" --update-env`, { logger });
5633
5662
  logger.info("pm2 reloaded");
5634
5663
  if (appName) {
5635
- await waitPm2(
5664
+ const proc = await waitPm2(
5636
5665
  appName,
5637
- (proc) => proc?.pm2_env?.status === "online",
5638
- { timeoutMs: waitTimeoutMs, logger, label: "online after reload" }
5666
+ (p) => isFreshOnline(p, oldPid),
5667
+ {
5668
+ timeoutMs: waitTimeoutMs,
5669
+ logger,
5670
+ label: oldPid ? `online on new pid (old ${oldPid} gone)` : "online after reload"
5671
+ }
5639
5672
  );
5640
- logger.info(`pm2 ${appName} online`);
5673
+ logger.info(`pm2 ${appName} online pid=${proc?.pid ?? "?"}`);
5641
5674
  }
5642
5675
  }
5643
5676
  async function stopPm2(appName, options = {}) {
@@ -5655,10 +5688,15 @@ async function stopPm2(appName, options = {}) {
5655
5688
  logger.info(`pm2 ${appName}: already stopped`);
5656
5689
  return;
5657
5690
  }
5691
+ const oldPid = Number(before.pid);
5658
5692
  await runShell(`pm2 stop "${appName}"`, { logger });
5659
5693
  await waitPm2(
5660
5694
  appName,
5661
- (proc) => !proc || proc.pm2_env?.status === "stopped",
5695
+ (proc) => {
5696
+ if (proc && proc.pm2_env?.status !== "stopped") return false;
5697
+ if (Number.isFinite(oldPid) && oldPid > 0 && isPidAlive(oldPid)) return false;
5698
+ return true;
5699
+ },
5662
5700
  { timeoutMs: waitTimeoutMs, logger, label: "stopped" }
5663
5701
  );
5664
5702
  logger.info(`pm2 ${appName} stopped`);
@@ -5672,12 +5710,12 @@ async function startPm2(paths, options = {}) {
5672
5710
  await runShell(`pm2 start "${paths.ecosystem}" --update-env`, { logger });
5673
5711
  logger.info("pm2 started");
5674
5712
  if (appName) {
5675
- await waitPm2(
5713
+ const proc = await waitPm2(
5676
5714
  appName,
5677
- (proc) => proc?.pm2_env?.status === "online",
5715
+ (p) => isFreshOnline(p, null),
5678
5716
  { timeoutMs: waitTimeoutMs, logger, label: "online after start" }
5679
5717
  );
5680
- logger.info(`pm2 ${appName} online`);
5718
+ logger.info(`pm2 ${appName} online pid=${proc?.pid ?? "?"}`);
5681
5719
  }
5682
5720
  }
5683
5721
 
@@ -9206,6 +9244,8 @@ export {
9206
9244
  installDeps,
9207
9245
  installOperatorShell,
9208
9246
  ipcFileLogsTableNameForSourceResource,
9247
+ isFreshOnline,
9248
+ isPidAlive,
9209
9249
  joiEdateType,
9210
9250
  joiStringArrayType,
9211
9251
  listServicesRegistry as listAliveRunnerHeartbeats,