Skip to main content

in block

Local statements inside a global protocol, executed by one component. It is where a global protocol says what a single component does between exchanges.

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

message struct Ack {
    track_id: uint32;
}

global protocol Report {
    exch any TrackReport into let latest: TrackReport from Radar to CommandPost;
    in CommandPost {
        var alerts: int32 = 0;
        branch
        | latest.track_id > 0 => set alerts = alerts + 1;
        | else =>
        end
    }
    exch any Ack from CommandPost to Radar;
}

Statements​

in C { … } holds local-protocol statements, and C names a component. The enclosed statements follow the local-protocol rules, so a send inside the block sends from C:

  • let, var, and set — the state C keeps between exchanges, and what most in blocks are for.
  • branch and listen — a decision C makes privately. No other component's behavior forks with it, which is what separates this from a choice.
  • loop and break.
  • do — running another local protocol of C.
  • send and recv — legal, and seldom what a global protocol wants. An interaction belongs in an exch, which states both halves at once; a lone send here has no matching receive anywhere, so nothing ever takes the message.
  • A standalone annotation.

Bindings​

  • A let or var declared in the block is component-scoped: it is visible to later global statements that involve C, and to nothing else. A statement involves a component by naming it as a connection endpoint, deriving that endpoint from a connection, or choosing in it.
  • Visibility runs forward only. A statement above the block cannot name what it binds.
  • Binding names are one namespace across every in block of the protocol, whichever component each block names.
component Radar;
component CommandPost;
component Launcher;

message struct TrackReport {
    track_id: uint32;
}

message struct EngageOrder {
    track_id: uint32;
}

global protocol Engage {
    exch any TrackReport from Radar to CommandPost;
    in CommandPost {
        var engagements: int32 = 0;
        set engagements = engagements + 1;
    }
    choice in CommandPost
    | engagements > 0 => exch any EngageOrder from CommandPost to Launcher;
    | else =>
    end
}

Errors​

An in block for something that is not a component​

An in block's statements run as one component, and a group is not one.

component Radar;
component CommandPost;

message struct TrackReport {
    track_id: uint32;
}

group Sensors {
    Radar;
}

global protocol Report {
    exch any TrackReport from Radar to CommandPost;
    in Sensors {   // error: in-block-component-not-component
        var reports: int32 = 0;
    }
}

One name in two in blocks​

component Radar;
component CommandPost;
component Launcher;

message struct TrackReport {
    track_id: uint32;
}

global protocol Engage {
    exch any TrackReport from Radar to CommandPost;
    in CommandPost {
        var count: int32 = 0;
    }
    in Launcher {
        var count: int32 = 0;   // error: duplicate-in-block-binding
    }
}

Reading a binding from a component that is not involved​

component Radar;
component CommandPost;
component Launcher;

message struct TrackReport {
    track_id: uint32;
}

message struct EngageOrder {
    track_id: uint32;
}

global protocol Engage {
    in CommandPost {
        var engagements: int32 = 0;
    }
    choice in Launcher
    | engagements > 0 => exch any EngageOrder from Launcher to CommandPost;   // error: unresolved-reference
    | else =>
    end
}
  • global protocol — the statements an in block sits among.
  • local protocol — the statements it holds, and the let/var/set rules.
  • choice — the statement that reads an in block's state most often.