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, andset— the stateCkeeps between exchanges, and what mostinblocks are for.branchandlisten— a decisionCmakes privately. No other component's behavior forks with it, which is what separates this from achoice.loopandbreak.do— running another local protocol ofC.sendandrecv— legal, and seldom what a global protocol wants. An interaction belongs in anexch, which states both halves at once; a lonesendhere has no matching receive anywhere, so nothing ever takes the message.- A standalone annotation.
Bindings
- A
letorvardeclared in the block is component-scoped: it is visible to later global statements that involveC, 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
inblock 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
}Related
- global protocol — the statements an
inblock sits among. - local protocol — the statements it holds, and the
let/var/setrules. - choice — the statement that reads an
inblock's state most often.