Files
@ 88611f9fd179
Branch filter:
Location: CSY/reowolf/testdata/examples/02_error_handling.pdl - annotation
88611f9fd179
3.1 KiB
text/plain
Merge branch 'feat-examples' into 'master'
feat: examples
See merge request nl-cwi-csy/reowolf!12
feat: examples
See merge request nl-cwi-csy/reowolf!12
97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 97217a7b2d18 | // Although in an unstable state, there is an initial implementation for error
// handling. Roughly speaking: if a component has failed then it cannot complete
// any current or future synchronous rounds anymore. Hence, apart from some edge
// cases, any received message by a peer should cause a failure at that peer as
// well. We may have a look at the various places where a component with respect
// to a peer that is receiving its messages
enum ErrorLocation {
BeforeSync,
DuringSyncBeforeFirstInteraction,
DuringSyncBeforeSecondInteraction,
DuringSyncAfterInteractions,
AfterSync,
}
func error_location_to_string(ErrorLocation loc) -> string {
if (let ErrorLocation::BeforeSync = loc) {
return "before sync";
} else if (let ErrorLocation::DuringSyncBeforeFirstInteraction = loc) {
return "during sync before first interaction";
} else if (let ErrorLocation::DuringSyncBeforeSecondInteraction = loc) {
return "during sync before second interaction";
} else if (let ErrorLocation::DuringSyncAfterInteractions = loc) {
return "during sync after interactions";
} else { return "after sync"; }
}
func crash() -> u8 {
return {}[0]; // access index 1 of an empty array
}
comp sender_and_crasher(out<u32> value, ErrorLocation loc) {
print("sender: will crash " @ error_location_to_string(loc));
if (loc == ErrorLocation::BeforeSync) { crash(); }
sync {
if (loc == ErrorLocation::DuringSyncBeforeFirstInteraction) { crash(); }
print("sender: sending first value");
put(value, 0);
if (loc == ErrorLocation::DuringSyncBeforeSecondInteraction) { crash(); }
print("sender: sending second value");
put(value, 1);
if (loc == ErrorLocation::DuringSyncAfterInteractions) { crash(); }
}
if (loc == ErrorLocation::AfterSync) { crash(); }
}
comp receiver(in<u32> value) {
sync {
auto a = get(value);
auto b = get(value);
}
}
// Note that when we run the example with the error location before sync, or
// during sync, that the receiver always crashes. However the location where it
// will crash is somewhat random! Due to the asynchronous nature of the runtime
// a sender of messages will always just `put` the value onto the port and
// continue execution. So even though the sender component might already be done
// with its sync round, the receiver officially still has to receive its first
// message. In any case, a neat error message should be displayed in the
// console.
//
// Note especially, given the asynchronous nature of the runtime, that the
// receiver should figure out when the peer component has crashed, but it can
// still finish the current synchronous round. This might happen if the peer
// component crashes *just* after the synchronous round. There may be a case
// where the peer receives the information that the peer crashed *before* it
// receives the information that the synchronous round has succeeded.
comp main() {
channel tx -> rx;
new sender_and_crasher(tx, ErrorLocation::AfterSync);
new receiver(rx);
}
|