Breakdowns in Communication
Sometimes, the Target program may not respond for various reasons. It's crucial to handle such scenarios appropriately.
wait_for()
To address this issue, let's use wait_for(DURATION_IN_BLOCKS)
.
Reminder: This function automatically wakes up the message from the waiting list after a specified number of blocks if exec::wake()
has not been called.
Target Program
Add exec::wait()
to the Target program so that it does not reply to incoming messages.
#[no_mangle]
extern "C" fn handle() {
exec::wait();
let action: Action = msg::load().expect("Error in decode message");
// ...
Proxy Program
In the Proxy program, the handle()
function will be modified. Instead of exec::wait()
, let's use exec::wait_for(3)
. This ensures that if exec::wake()
in handle_reply()
is not called within 3 blocks, message processing will automatically resume.
#[no_mangle]
extern "C" fn handle() {
debug!("!!!! HANDLE !!!!");
debug!("Message ID: {:?}", msg::id());
let action: Action = msg::load().expect("Unable to decode `Action`");
debug!("Message payload: {:?}", action);
let session = unsafe { SESSION.as_mut().expect("The session is not initialized") };
// match session_status
match &session.session_status {
SessionStatus::Waiting => {
debug!("HANDLE: SessionStatus::Waiting");
let msg_id = msg::send(session.target_program_id, action, 0)
.expect("Error in sending a message");
debug!("HANDLE: SessionStatus::MessageSent");
session.session_status = SessionStatus::MessageSent;
session.msg_ids = (msg_id, msg::id());
debug!("HANDLE: WAIT");
exec::wait_for(3);
}
SessionStatus::MessageSent => {
if msg::id() == session.msg_ids.1 {
debug!("HANDLE: No response was received");
msg::reply(Event::NoReplyReceived, 0).expect("Error in sending a reply");
debug!("HANDLE: SessionStatus::Waiting");
session.session_status = SessionStatus::Waiting;
} else {
debug!("HANDLE: Event::MessageAlreadySent");
msg::reply(Event::MessageAlreadySent, 0).expect("Error in sending a reply");
}
}
SessionStatus::ReplyReceived(reply_message) => {
debug!("HANDLE: SessionStatus::ReplyReceived");
msg::reply(reply_message, 0).expect("Error in sending a reply");
debug!("HANDLE: SessionStatus::Waiting");
session.session_status = SessionStatus::Waiting;
}
}
debug!("HANDLE: END");
}
In such a case, the program will return to handle()
, but this time with the session status as SessionStatus::Sent
. Consequently, a message will be sent to the user indicating the absence of a response, and the status will be updated to SessionStatus::Waiting
.