Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SMSG Messaging

SMSG (Special Message) is the fire-and-forget text messaging facility, modeled after the VM/CMS CP SMSG command.

Sending Messages

There are two ways to send an SMSG:

From outside a handler (via Supervisor)

#![allow(unused)]
fn main() {
// Async — awaits until the message is enqueued in the router
supervisor.smsg(&from, &to, "Hello").await?;
}

From inside a handler (via MachineContext)

#![allow(unused)]
fn main() {
impl MachineHandler for MyHandler {
    fn on_smsg(&mut self, ctx: &MachineContext, msg: SmsgMessage) {
        // Non-blocking — uses try_send
        let _ = ctx.try_send_smsg(msg.from(), "Got it!");
    }
}
}

Message Constraints

ConstraintLimit
Max text length236 bytes
Character setASCII only

These match the real CP SMSG limits (236-byte EBCDIC text).

#![allow(unused)]
fn main() {
// Constructing a message manually
let msg = SmsgMessage::new(
    MachineId::new("ALICE").unwrap(),
    MachineId::new("BOB").unwrap(),
    "Hello Bob",
)?;
}

Delivery Semantics

SMSG delivery is best-effort:

  • If the target machine exists and its channel has room, the message is delivered to on_smsg.
  • If the target’s channel is full, the message is silently dropped.
  • If the target is not logged on, supervisor.smsg() returns MachineNotFound.
  • Messages in-flight when a machine logs off may or may not be delivered.

This matches real VM/CMS behavior where CP SMSG provides no delivery guarantee.

Request/Reply Pattern

Since SMSG is fire-and-forget, implement request/reply by having the receiver send a response back:

#![allow(unused)]
fn main() {
struct EchoHandler;

impl MachineHandler for EchoHandler {
    fn on_smsg(&mut self, ctx: &MachineContext, msg: SmsgMessage) {
        let reply = format!("ECHO: {}", msg.text());
        let _ = ctx.try_send_smsg(msg.from(), &reply);
    }
}
}

See the echo_server example for a complete working version.

Inspecting Messages (Testing)

Use the CollectorHandler (requires test-util feature) to capture messages for inspection:

#![allow(unused)]
fn main() {
use vm_iucv::collector::collector;

let (handler, handle) = collector();
supervisor.ipl(&id, handler).await?;

// ... send messages ...

let messages = handle.messages();
assert_eq!(messages[0].text(), "Hello");
}