Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine
Release notes
Changelog
Elyra
Events — the EventBus

Events — the EventBus

The EventBus is Elyra's Broadcasting: Rust pushes events to the frontend, batched per flush. Rust owns the state; the frontend subscribes to changes instead of polling.

Emitting (Rust)

The bus is created by App and bound in the container, so any command, provider, or task can resolve it:

#[command]
async fn tick(ctx: Ctx) {
    ctx.get::<EventBus>().emit("tick", &42u32).ok();
}

emit<T: Serialize>(channel, &value) is non-blocking and callable from any thread. To emit from main or a background thread, grab a clone before running:

let app = App::new().commands(commands![..]);
let bus = app.events();                       // a clone of the bus
std::thread::spawn(move || { bus.emit("tick", &1u32).ok(); });
app.run()?;

Subscribing (frontend)

channel(name) returns a Svelte-readable store, multiplexed over a single connection:

<script>
  import { channel } from "@elyra/runtime";
  const ticks = channel("tick");   // usable as $ticks
</script>
<p>{$ticks}</p>

Or subscribe manually:

const unsubscribe = channel<number>("tick").subscribe((n) => console.log(n));

Transport & batching

Events travel over a long-poll of elyra://localhost/__events: the shell holds the request open until events are ready, responds with a MessagePack batch ([[channel, value], ...]), and the frontend immediately reconnects. Binary, no base64, one connection for all channels. See wire format.

Emits accumulate and flush together, so N state changes cost one IPC round, not N. By default there's no artificial delay — the natural response→reconnect gap coalesces bursts. For sustained, time-spaced streams you can force frame-level coalescing:

App::new().batch_window(std::time::Duration::from_millis(8));

After ~20s idle the poll returns an empty keep-alive batch and the connection refreshes.

Related