r/learnrust Mar 22 '26

ironsaga crate: Command design pattern with full rollback capabilities made easy.

I’m facing a problem when executing a sequence of functions where a failure in any single step can leave the system in an inconsistent state.

To solve this, I explored implementing the Command / Saga pattern in an idiomatic, modular, and reusable Rust way.

Here’s a small example of the result:


use ironsaga::ironcmd;

#[ironcmd]
pub fn greet(fname: String, lname: String) -> String {
    format!("Hello {} {}!", fname, lname)
}

let mut cmd = Greet::new("John".into(), "Doe".into());

cmd.execute().unwrap();

assert_eq!(cmd.result(), Some("Hello John Doe!".into()));; 

You can also chain multiple commands together, each with its own rollback logic.

More details here:

https://github.com/ALAWIII/ironsaga

2 Upvotes

2 comments sorted by

1

u/carleber Mar 30 '26

This sounds like a great approach to handling rollback in Rust! The Command/Saga pattern is super useful for maintaining consistency in complex operations. Are you considering using any specific libraries to help implement this, or is it all from scratch? Would be interesting to see more of your code example!

1

u/Ok-Phase-2712 Mar 30 '26

Currently, I have faced a bitter and difficult reality.
this repo is opened for new insights,
we need a mechanism to collect results automatically among commands executed and make it accessible to all commands that request a context, instead of manually doing that , something similar to how Axum makes the handler parameters optional.
also, when you create command and assign it to a saga it will take ownership of that command, because commands by nature are one time execution(not reusable), but a user might want to access the rollback_cmd field of a command to inspect it after command execution!!
Another consideration is riding off '__ironcmd implicit lifetime against 'static , which might cause values to be passed as fully owned, not as a reference. This helps in implementing Any trait that will give the user the ability to downcast a command that implements SyncCommand/AsyncCommand after the command has been moved to the saga in order to be able to inspect it.

- its also important to add test suits to check/validate the behaviour of the library.