Skip to content

Conversation

@hawkw
Copy link
Member

@hawkw hawkw commented Dec 5, 2025

In the days of yore, @jmpesp wrote an omdb db saga show command in PR #4378, which prints a trace of the execution of a given saga. Unfortunately, this code never made it to main. Some parts of #4378 adding other saga-related OMDB commands merged in separate PRs, but the saga show command never made it in. Instead, when it's necessary to display the execution history of a saga for debugging, folks have maintained separate omdb-sagas binaries built from #4378 and copied them onto the dogfood rack or racklettes as needed for debugging.

This is not an ideal situation. If an issue occurs on a customer rack rather than in development, it would be useful for support to be able to display these saga execution traces without copying a random binary onto the customer's rack, which may not be permitted depending on the customer environment. And, when the subcommand is not merged to the main branch and is instead maintained separately, it may drift substantially from the rest of the codebase, potentially encountering schema incompatibilities in future versions.

Therefore, this PR digs up the omdb db saga show command from #4378 and does the minimum amount of changes necessary to make it compile with the current main. Almost all of the added code was written by @jmpesp, and I've just copied it and pasted it, and fixed compiler errors and such. While I'm open to addressing some of the suggestions from @dap's review of #4378, I felt like the priority was to just get the code pulled forward into a working state.

Authored-by: James MacMahon james@oxide.computer
Co-authored-by: Eliza Weisman eliza@elizas.website

hawkw added 2 commits December 5, 2025 09:54
In the days of yore, @jmpesp wrote an `omdb db saga show` command in PR
#4378, which prints a trace of the execution of a given saga.
Unfortunately, this code never made it to `main`. Some parts of #4378
adding _other_ saga-related OMDB commands merged in separate PRs, but
the `saga show` command never made it in. Instead, when it's necessary
to display the execution history of a saga for debugging, folks have
maintained separate `omdb-sagas` binaries built from #4378 and copied
them onto the dogfood rack or racklettes as needed for debugging.

This is not an ideal situation. If an issue occurs on a customer rack
rather than in development, it would be useful for support to be able to
display these saga execution traces without copying a random binary onto
the customer's rack, which may not be permitted depending on the
customer environment. And, when the subcommand is not merged to the
`main` branch and is instead maintained separately, it may drift
substantially from the rest of the codebase, potentially encountering
schema incompatibilities in future versions.

Therefore, this PR digs up the `omdb db saga show` command from #4378
and does the minimum amount of changes necessary to make it compile with
the current `main`. Almost all of the added code was written by @jmpesp,
and I've just copied it and pasted it, and fixed compiler errors and
such. While I'm open to addressing some of the suggestions from @dap's
[review of #4378][1], I felt like the priority was to just get the code
pulled forward into a working state.

[1]:
#4378 (review)

Authored-by: James MacMahon <james@oxide.computer> Co-authored-by: Eliza
Weisman <eliza@elizas.website>
Comment on lines +684 to +716
// Copy some types from Steno, because steno uses pub(crate) everywhere. We
// don't want to change Steno to make the internals public, but these types
// should be fairly stable.
#[derive(Serialize, Deserialize)]
struct StenoDag {
pub saga_name: String,
pub graph: Graph<StenoNode, ()>,
pub start_node: NodeIndex,
pub end_node: NodeIndex,
}

impl StenoDag {
pub fn get(&self, node_index: NodeIndex) -> Option<&StenoNode> {
self.graph.node_weight(node_index)
}

pub fn get_from_saga_node_id(
&self,
saga_node_id: &nexus_db_model::saga_types::SagaNodeId,
) -> Option<&StenoNode> {
self.get(u32::from(saga_node_id.0).into())
}
}

#[derive(Serialize, Deserialize, Debug)]
enum StenoNode {
Start { params: Arc<serde_json::Value> },
End,
Action { name: String, label: String, action_name: String },
Constant { name: String, value: Arc<serde_json::Value> },
SubsagaStart { saga_name: String, params_node_name: String },
SubsagaEnd { name: String },
}
Copy link
Member Author

Choose a reason for hiding this comment

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

@davepacheco left a comment on #4378 suggesting that we would be better off exposing the requisite APIs in steno, rather than duplicating these types here: #4378 (comment)

I agree with this suggestion and would quite like to address it upstream. However, I didn't think this PR ought to be blocked on waiting for those changes in Steno. Instead, I'd like to go add the requisite interfaces there and come back and change this to use them. If others disagree, I'm open to being convinced otherwise.

@hawkw hawkw requested review from davepacheco and jmpesp December 5, 2025 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants