coding4 min read

Sayiir: A Durable Workflow Engine in Rust with Python & Node.js Bindings

Explore Sayiir, a lightweight workflow engine built in Rust with seamless Python and Node.js bindings, designed to simplify complex process orchestration.

Sayiir: A Durable Workflow Engine in Rust with Python & Node.js Bindings

Introduction: Why Does Sayiir Matter in Workflow Management?

Learn more about i built an ai pipeline for books: the architecture explained

In software development, workflow engines are essential for orchestrating complex processes. Traditional solutions like Temporal and Airflow often require heavy infrastructure and rigid execution models. Sayiir disrupts this norm by offering a lightweight, durable workflow engine built in Rust, with simple bindings for Python and Node.js. In this post, we will explore Sayiir's unique features and how they can enhance your development experience.

What Sets Sayiir Apart?

What makes Sayiir different from conventional workflow engines? Its continuation-driven execution model is a game changer. Here are some key differentiators:

  • No Replay Overhead: On crash recovery, execution resumes from the last checkpoint, significantly reducing recovery time.
  • No Determinism Constraints: Your tasks can invoke any API, use any library, and follow any logic without the limitations of purity rules.
  • Native Language Constructs: Compose workflows using familiar syntax, eliminating the need for a custom DSL. This approach eases the learning curve for developers familiar with Rust, Python, or TypeScript.

What Are the Core Features of Sayiir?

How Does Continuation-Driven Execution Work?

Sayiir's execution engine prioritizes efficiency. Instead of replaying entire histories during recovery, it employs a continuation-driven model. This leads to:

  1. Faster Recovery: Workflows can quickly recover from failures by resuming from the last checkpoint.
  2. Design Flexibility: Create complex workflows that are less deterministic and more expressive.

Why Choose Native Language Support?

📚 For a deep dive on mastering api error handling testing before production, see our full guide

With Sayiir, you won't have to learn a new DSL or change your coding style. Instead, you can use:

  • A workflow! macro in Rust for concise workflow definitions.
  • A fluent builder in Python and TypeScript.

📚 For a deep dive on mastering react router: loaders, actions, and forms, see our full guide

This accessibility allows a broader audience of developers to get started without a steep learning curve.

What About Pluggable Backends?

Sayiir supports various backends for durability and persistence:

  • PostgreSQL: The stable backend for storing checkpoints.
  • Future Backends: More options are planned to accommodate diverse use cases.
  • Codec Options: JSON is the default format, but you can switch to rkyv or any binary format as needed.

How Can You Get Started with Sayiir?

To begin using Sayiir, add the core library to your project. Here’s a quick example of defining a simple workflow:

#[task(timeout = "30s", retries = 3)]
async fn fetch_user(id: UserId) -> Result<User, BoxError> {
    db.get_user(id).await
}

#[task]
async fn send_email(user: User) -> Result<(), BoxError> {
    email_service.send_welcome(&user).await
}

let workflow = workflow! {
    name: "welcome",
    steps: [fetch_user, send_email]
}
.unwrap();

// In-memory or plug in a durable PostgreSQL backend
let runner = CheckpointingRunner::new(PostgresBackend::connect("postgres://...").await?);
runner.run(&workflow, "welcome-42", user_id).await?;

What Is the Rust Core Like?

Sayiir's core features a hexagonal architecture, ensuring modularity and maintainability:

  • sayiir-core: The execution engine, with zero dependencies on any runtime.
  • sayiir-persistence: Manages pluggable backends and their interactions.
  • sayiir-runtime: Integrates with async runtimes and includes procedural macros for enhanced usability.

How Do Python and Node.js Bindings Work?

Sayiir provides bindings for both Python and Node.js:

  • PyO3/maturin for Python allows developers to leverage Rust's performance easily.
  • NAPI-RS for Node.js enables JavaScript developers to benefit from Sayiir's efficient execution model.

How Does a Workflow Look in Python?

Here’s an example of a workflow in Python:

@task(timeout="30s", retries=3)
async def fetch_user(id):
    return await db.get_user(id)

@task
async def send_email(user):
    await email_service.send_welcome(user)

workflow = Workflow(
    name="welcome",
    steps=[fetch_user, send_email]
)

runner = CheckpointingRunner(PostgresBackend.connect("postgres://..."))
await runner.run(workflow, "welcome-42", user_id)

How Can You Engage with the Sayiir Community?

Sayiir is open-source and MIT licensed, welcoming contributions and feedback. Join our community to share experiences, ask questions, and collaborate on enhancing the project:

Frequently Asked Questions

What Programming Languages Does Sayiir Support?

Sayiir currently supports Rust, Python, and Node.js, with plans for more languages in the future.

Is Sayiir Suitable for Production Use?

Yes, the core, Python bindings, Node.js bindings, and PostgreSQL backend are stable and ready for production.

How Can I Contribute to Sayiir?

You can contribute by reporting issues, submitting pull requests, or providing feedback in our community channels.

Conclusion: Why Choose Sayiir for Your Workflow Needs?


Continue learning: Next, explore mac pro storage configurations leak: what to expect

Sayiir offers a fresh perspective on workflow engines, emphasizing simplicity and flexibility. With its continuation-driven execution model and native language support, it empowers developers to create robust workflows without the complexities of traditional systems. If you're looking for a lightweight, efficient workflow engine that integrates seamlessly with Rust, Python, and Node.js, consider exploring Sayiir. Your feedback will be invaluable as we evolve this tool to meet the needs of the developer community.

Related Articles