-
-
Notifications
You must be signed in to change notification settings - Fork 806
Add Stop, Restart, and Force Rebuild menu items to Tsunami view #2483
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f3482ca
9ce1e57
de00662
cd01857
f889657
9cee89a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -72,26 +72,58 @@ class TsunamiViewModel extends WebViewModel { | |||||||||||||
| }, 300); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| resyncController() { | ||||||||||||||
| private doControllerResync(forceRestart: boolean, logContext: string, triggerRestart: boolean = true) { | ||||||||||||||
| if (triggerRestart) { | ||||||||||||||
| if (globalStore.get(this.isRestarting)) { | ||||||||||||||
| return; | ||||||||||||||
| } | ||||||||||||||
| this.triggerRestartAtom(); | ||||||||||||||
| } | ||||||||||||||
| const prtn = RpcApi.ControllerResyncCommand(TabRpcClient, { | ||||||||||||||
| tabid: globalStore.get(atoms.staticTabId), | ||||||||||||||
| blockid: this.blockId, | ||||||||||||||
| forcerestart: false, | ||||||||||||||
| forcerestart: forceRestart, | ||||||||||||||
| }); | ||||||||||||||
| prtn.catch((e) => console.log("error controller resync", e)); | ||||||||||||||
| prtn.catch((e) => console.log(`error controller resync (${logContext})`, e)); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| forceRestartController() { | ||||||||||||||
| resyncController() { | ||||||||||||||
| this.doControllerResync(false, "resync", false); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| stopController() { | ||||||||||||||
| const prtn = RpcApi.ControllerStopCommand(TabRpcClient, this.blockId); | ||||||||||||||
| prtn.catch((e) => console.log("error stopping controller", e)); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
Comment on lines
+94
to
+98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major 🧩 Analysis chainStop should be awaitable; verify payload shape Expose an async API and rethrow on failure so callers (and tests) can react. Also verify whether stop expects blockId or an object with tabid/blockid. - stopController() {
- const prtn = RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
- prtn.catch((e) => console.log("error stopping controller", e));
- }
+ async stopController() {
+ try {
+ await RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
+ } catch (e) {
+ console.log("error stopping controller", e);
+ throw e;
+ }
+ }Run to confirm expected signature: 🏁 Script executed: #!/bin/bash
# Locate definition and usages to confirm the data argument.
rg -n -C3 "ControllerStopCommand\\s*\\("Length of output: 3317 Make stopController() async and properly handle errors to allow caller reaction The verification confirms the concern: Apply the suggested refactor to match the established pattern elsewhere in the codebase: - stopController() {
- const prtn = RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
- prtn.catch((e) => console.log("error stopping controller", e));
- }
+ async stopController() {
+ try {
+ await RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
+ } catch (e) {
+ console.log("error stopping controller", e);
+ throw e;
+ }
+ }🤖 Prompt for AI Agents |
||||||||||||||
| async restartController() { | ||||||||||||||
| if (globalStore.get(this.isRestarting)) { | ||||||||||||||
| return; | ||||||||||||||
| } | ||||||||||||||
| this.triggerRestartAtom(); | ||||||||||||||
| const prtn = RpcApi.ControllerResyncCommand(TabRpcClient, { | ||||||||||||||
| tabid: globalStore.get(atoms.staticTabId), | ||||||||||||||
| blockid: this.blockId, | ||||||||||||||
| forcerestart: true, | ||||||||||||||
| }); | ||||||||||||||
| prtn.catch((e) => console.log("error controller resync (force restart)", e)); | ||||||||||||||
| try { | ||||||||||||||
| // Stop the controller first | ||||||||||||||
| await RpcApi.ControllerStopCommand(TabRpcClient, this.blockId); | ||||||||||||||
| // Wait a bit for the controller to fully stop | ||||||||||||||
| await new Promise((resolve) => setTimeout(resolve, 300)); | ||||||||||||||
| // Then resync to restart it | ||||||||||||||
| await RpcApi.ControllerResyncCommand(TabRpcClient, { | ||||||||||||||
| tabid: globalStore.get(atoms.staticTabId), | ||||||||||||||
| blockid: this.blockId, | ||||||||||||||
| forcerestart: false, | ||||||||||||||
| }); | ||||||||||||||
| } catch (e) { | ||||||||||||||
| console.log("error restarting controller", e); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
Comment on lines
+99
to
+118
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate restart risk and brittle 300ms UI gating; use best‑effort stop and an in‑flight guard isRestarting resets after 300ms, allowing overlapping restarts and misleading UI. Add a restartInFlight guard, keep UI pulse via triggerRestartAtom, proceed to resync even if stop says “already stopped,” and allow force rebuild reuse. - async restartController() {
- if (globalStore.get(this.isRestarting)) {
- return;
- }
- this.triggerRestartAtom();
- try {
- // Stop the controller first
- await RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
- // Wait a bit for the controller to fully stop
- await new Promise((resolve) => setTimeout(resolve, 300));
- // Then resync to restart it
- await RpcApi.ControllerResyncCommand(TabRpcClient, {
- tabid: globalStore.get(atoms.staticTabId),
- blockid: this.blockId,
- forcerestart: false,
- });
- } catch (e) {
- console.log("error restarting controller", e);
- }
- }
+ async restartController(forceRebuild: boolean = false) {
+ if (this.restartInFlight) return;
+ this.restartInFlight = true;
+ this.triggerRestartAtom();
+ try {
+ // Best‑effort stop; continue even if already stopped.
+ try {
+ await RpcApi.ControllerStopCommand(TabRpcClient, this.blockId);
+ } catch (e) {
+ console.log("controller stop failed (continuing to resync)", e);
+ }
+ await new Promise((resolve) => setTimeout(resolve, 300));
+ await RpcApi.ControllerResyncCommand(TabRpcClient, {
+ tabid: globalStore.get(atoms.staticTabId),
+ blockid: this.blockId,
+ forcerestart: forceRebuild,
+ });
+ } catch (e) {
+ console.log("error restarting controller", e);
+ } finally {
+ this.restartInFlight = false;
+ }
+ }Add this field to the class (outside this hunk): // Near other fields in TsunamiViewModel
private restartInFlight = false;🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| restartAndForceRebuild() { | ||||||||||||||
| this.doControllerResync(true, "force rebuild"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
Comment on lines
+120
to
+123
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Menu label says “Restart … and Force Rebuild” but code doesn’t stop first Current implementation is a resync-only path. Align behavior with the label by reusing restartController(true). - restartAndForceRebuild() {
- this.doControllerResync(true, "force rebuild");
- }
+ async restartAndForceRebuild() {
+ await this.restartController(true);
+ }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| forceRestartController() { | ||||||||||||||
| // Keep this for backward compatibility with the Start button | ||||||||||||||
| this.doControllerResync(true, "force restart"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| setAppMeta(meta: TsunamiAppMeta) { | ||||||||||||||
|
|
@@ -125,7 +157,7 @@ class TsunamiViewModel extends WebViewModel { | |||||||||||||
| getSettingsMenuItems(): ContextMenuItem[] { | ||||||||||||||
| const items = super.getSettingsMenuItems(); | ||||||||||||||
| // Filter out homepage and navigation-related menu items for tsunami view | ||||||||||||||
| return items.filter((item) => { | ||||||||||||||
| const filteredItems = items.filter((item) => { | ||||||||||||||
| const label = item.label?.toLowerCase() || ""; | ||||||||||||||
| return ( | ||||||||||||||
| !label.includes("homepage") && | ||||||||||||||
|
|
@@ -134,6 +166,27 @@ class TsunamiViewModel extends WebViewModel { | |||||||||||||
| !label.includes("nav") | ||||||||||||||
| ); | ||||||||||||||
| }); | ||||||||||||||
|
|
||||||||||||||
| // Add tsunami-specific menu items at the beginning | ||||||||||||||
| const tsunamiItems: ContextMenuItem[] = [ | ||||||||||||||
| { | ||||||||||||||
| label: "Stop WaveApp", | ||||||||||||||
| click: () => this.stopController(), | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| label: "Restart WaveApp", | ||||||||||||||
| click: () => this.restartController(), | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| label: "Restart WaveApp and Force Rebuild", | ||||||||||||||
| click: () => this.restartAndForceRebuild(), | ||||||||||||||
| }, | ||||||||||||||
| { | ||||||||||||||
| type: "separator", | ||||||||||||||
| }, | ||||||||||||||
| ]; | ||||||||||||||
|
|
||||||||||||||
| return [...tsunamiItems, ...filteredItems]; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Return a Promise from doControllerResync and propagate errors
Callers can’t await the resync; errors are only logged. Make it async, return the underlying Promise, and rethrow to let callers handle.
If RpcApi supports RpcOpts timeouts, consider adding a bounded timeout. Please confirm with:
🏁 Script executed:
Length of output: 5675
Return a Promise from doControllerResync and propagate errors
The underlying
RpcApi.ControllerResyncCommandalready returnsPromise<void>, but this method doesn't return or await it. Make the method async to return the Promise and rethrow errors so callers can handle them. Additionally, callers should passRpcOptswith a timeout for robustness.Update all call sites (e.g.,
restartAndForceRebuild,restartController) toawaitthe result. Consider addingrtoptsparameter with timeout.🤖 Prompt for AI Agents