Skip to content

Conversation

@hahn-kev
Copy link
Collaborator

@hahn-kev hahn-kev commented Sep 9, 2025

It turns out that windows doesn't have a gracefull shutdown of a process outside of Ctrl+C which you can't just send to a process you've spawned. Hence this fix.

  • Introduces a dedicated shutdownFwLite function for graceful termination, replacing direct process killing.
  • Updates FwLiteWeb to properly handle shutdown commands via stdin.
  • Refines process stdio configuration for consistency.

* Replace direct process killing with a dedicated `shutdownFwLite` function for graceful termination.
* Update FwLiteWeb to properly handle `shutdown` commands via stdin.
* Adjust process stdio configuration for consistency.
@coderabbitai
Copy link

coderabbitai bot commented Sep 9, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Adds a console-triggered shutdown path: the web app starts a background Task that reads stdin and calls app.StopAsync() when it reads exactly "shutdown". The extension enables stdin for the spawned process, adds a shutdownFwLite helper that sends "shutdown\n", awaits exit (rejects on non-zero), and enforces a 10s SIGKILL if needed; cleanup now uses that helper.

Changes

Cohort / File(s) Summary
Web app stdin shutdown listener
backend/FwLite/FwLiteWeb/Program.cs
Starts a background Task.Run that reads lines from stdin and, on exact "shutdown", calls app.StopAsync(). Startup flow and app.WaitForShutdownAsync() remain unchanged. No public API changes.
Extension process management & graceful shutdown
platform.bible-extension/src/main.ts
Adds shutdownFwLite(...) which writes "shutdown\n" to the fwLite process stdin, waits for exit (resolves on code 0, rejects on non-zero or error), and forces kill after 10s. Changes process spawn stdio to ['pipe','pipe','pipe'] to enable stdin and replaces direct kill() cleanup with the graceful helper. Uses ReturnType typing for the process parameter. No exported signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Potential review focus:

  • Verify robust handling of stdin stream end, partial reads, and exact-match behavior for the "shutdown" token in Program.cs.
  • Confirm no deadlocks or unobserved exceptions from the unawaited Task.Run.
  • Check the extension's timeout/force-kill logic and error propagation from the child process observer.

Poem

I nibble keys and hum a tune,
I whisper "shutdown" by the moon.
A gentle stop, a tidy hop,
Processes sleep — no sudden drop.
Rabbity cheers for graceful ends 🐇🎉

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Improve shutdown for FwLiteWeb in Paratext' directly and clearly summarizes the main change: introducing graceful shutdown improvements for the FwLiteWeb process.
Description check ✅ Passed The description is clearly related to the changeset, explaining the Windows shutdown limitation and detailing the three main changes: the shutdownFwLite function, stdin handling, and stdio configuration updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📙 Platform.Bible labels Sep 9, 2025
@github-actions
Copy link

github-actions bot commented Sep 9, 2025

UI unit Tests

  1 files  ±0   45 suites  ±0   16s ⏱️ -2s
111 tests ±0  111 ✅ ±0  0 💤 ±0  0 ❌ ±0 
160 runs  ±0  160 ✅ ±0  0 💤 ±0  0 ❌ ±0 

Results for commit 4f1a684. ± Comparison against base commit 6b416be.

♻️ This comment has been updated with latest results.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
backend/FwLite/FwLiteWeb/Program.cs (1)

18-25: Optional: guard against unexpected read errors and log.

Wrap the loop in try/catch so unexpected I/O failures don’t tear down the background task silently. If you have logging on the host, log and call StopAsync().

platform.bible-extension/src/main.ts (1)

296-315: Optional: kill the process tree on Windows if FwLiteWeb spawns children.

If FwLiteWeb ever spawns child processes, consider terminating the whole tree (e.g., taskkill /T /F or a library like tree-kill) in the fallback, otherwise stdout/stderr handles may keep the parent alive.

(stackoverflow.com)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31cea4c and 525d58c.

📒 Files selected for processing (2)
  • backend/FwLite/FwLiteWeb/Program.cs (1 hunks)
  • platform.bible-extension/src/main.ts (3 hunks)
🧰 Additional context used
🪛 GitHub Actions: Platform.Bible extension CI/CD
platform.bible-extension/src/main.ts

[warning] 1-1: Code style issues found in 'src/main.ts'. Run 'prettier --write .' to fix.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: frontend
  • GitHub Check: frontend-component-unit-tests
  • GitHub Check: Build FW Lite and run tests
  • GitHub Check: Analyze (csharp)
🔇 Additional comments (3)
platform.bible-extension/src/main.ts (3)

252-252: Good: register graceful cleanup instead of hard kill.

Hooking cleanup to a shutdown function is the right direction. Verify the activation host treats a rejected Promise from a disposer as a non-fatal deactivation; otherwise prefer resolving false instead of rejecting.


279-279: Stdin pipe is required here—LGTM.

Switching stdio to ['pipe','pipe','pipe'] is necessary so the backend can read the shutdown command.


1-1: Run Prettier via the package’s format script
CI flagged formatting in platform.bible-extension/src/main.ts; execute in that folder:

cd platform.bible-extension && pnpm run format

Likely an incorrect or invalid review comment.

@argos-ci
Copy link

argos-ci bot commented Sep 9, 2025

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Dec 18, 2025, 10:34 PM

Copy link
Collaborator

@myieye myieye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🙃 😬

@myieye
Copy link
Collaborator

myieye commented Nov 11, 2025

@copilot Please review and implement as appropriate the open suggestions from coderabbitai. So:

Copy link
Contributor

Copilot AI commented Nov 11, 2025

@myieye I've opened a new pull request, #2101, to work on those changes. Once the pull request is ready, I'll request review from you.

@myieye
Copy link
Collaborator

myieye commented Nov 21, 2025

@imnasnainaec I've implemented the AI feedback.

Would you be willing to take another look and maybe actually run it?
I haven't run the extension for a long time.

@imnasnainaec imnasnainaec marked this pull request as draft November 26, 2025 13:37
@imnasnainaec imnasnainaec self-assigned this Nov 26, 2025
Copy link
Collaborator

@imnasnainaec imnasnainaec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting on paranext/paranext-core#1936 (or something equivalent).

@imnasnainaec imnasnainaec marked this pull request as ready for review December 18, 2025 16:11
@imnasnainaec
Copy link
Collaborator

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@imnasnainaec imnasnainaec reopened this Dec 18, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
backend/FwLite/FwLiteWeb/Program.cs (1)

23-30: Stdin shutdown listener correctly handles EOF and whitespace.

The implementation properly exits on both null (EOF) and the "shutdown" command, preventing a busy loop if stdin closes. The use of .Trim() and the fire-and-forget pattern are appropriate.

Optional: Consider case-insensitive comparison for robustness

While the current case-sensitive match works with the controlled sender, a case-insensitive comparison would be more resilient:

-    // Windows doesn't allow sending SIGINT to a process, so we need to listen for a shutdown command
-    _ = Task.Run(async () =>
-         {
-             // Wait for the "shutdown" command from stdin
-             while ((await Console.In.ReadLineAsync())?.Trim() is not ("shutdown" or null)) { }
-
-             await app.StopAsync();
-         });
+    // Windows doesn't allow sending SIGINT to a process, so we need to listen for a shutdown command
+    _ = Task.Run(async () =>
+    {
+        string? line;
+        while ((line = await Console.In.ReadLineAsync()) is not null
+               && !string.Equals(line.Trim(), "shutdown", StringComparison.OrdinalIgnoreCase))
+        { /* keep waiting */ }
+
+        await app.StopAsync();
+    });

This matches the suggestion from the previous review and allows "Shutdown", "SHUTDOWN", etc.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 525d58c and 2af3a7d.

📒 Files selected for processing (1)
  • backend/FwLite/FwLiteWeb/Program.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
backend/**/*.cs

📄 CodeRabbit inference engine (backend/AGENTS.md)

backend/**/*.cs: Use async/await for asynchronous operations in C# code; avoid using .Result or .Wait()
Prefer Records for DTOs and immutable data structures in C#

Use Entity Framework Core for data access in backend projects following the LexData layer pattern

Files:

  • backend/FwLite/FwLiteWeb/Program.cs
backend/**/{*Kernel.cs,Program.cs}

📄 CodeRabbit inference engine (backend/AGENTS.md)

Use AddScoped for request-scoped services and AddSingleton for app-wide services in dependency injection registration

Files:

  • backend/FwLite/FwLiteWeb/Program.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: frontend-component-unit-tests
  • GitHub Check: frontend
  • GitHub Check: Build FW Lite and run tests
  • GitHub Check: lint (ubuntu-latest)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Analyze (csharp)
  • GitHub Check: Build FW Lite and run tests

Copy link
Collaborator

@myieye myieye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finishing this up @imnasnainaec

@imnasnainaec imnasnainaec merged commit 37cc762 into develop Dec 19, 2025
17 checks passed
@imnasnainaec imnasnainaec deleted the gracefull-shutdown-from-pt branch December 19, 2025 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📙 Platform.Bible

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants