Skip to content

Instantly share code, notes, and snippets.

@davisp
Created April 2, 2012 23:45
Show Gist options
  • Save davisp/2288078 to your computer and use it in GitHub Desktop.
Save davisp/2288078 to your computer and use it in GitHub Desktop.
+wait_loop(Parent, Timeout, State) ->
% State transitions
% unset -> (updated | timeout | waiting)
% updated -> (updated | unset)
% timeout -> (unset | updated)
% waiting -> unset
receive
db_updated when State == waiting ->
Parent ! updated,
wait_loop(Parent, Timeout, unset);
db_updated when State == unset orelse State == updated ->
wait_loop(Parent, Timeout, updated);
get_state when State == unset ->
wait_loop(Parent, Timeout, waiting);
get_state ->
Parent ! State,
wait_loop(Parent, Timeout, unset);
done ->
ok
after Timeout ->
case State of
waiting ->
Parent ! timeout;
unset ->
wait_loop(Parent, Timeout, timeout)
end
end.
@bdionne
Copy link

bdionne commented Apr 3, 2012

Paul,

Thanks I basically used this. I think you missed one edge case. If you hit the second db_updated clause in the unset state, but arrived there from having already seen db_updated in the waiting state then after you drain the mailbox you leave the state as updated yet you've already notified the Parent.

I think the version I just pushed handles this case, note I tweaked the state machine accordingly.

Bob

@davisp
Copy link
Author

davisp commented Apr 6, 2012

But the assumption is that you're not leaving db_udpated messages in the mailbox. You could add a step to drain them with a 0 timeout, but you don't want to accidentally miss them. This version is wrong with the timeouts but I think its right for this db_updated message handling.

@bdionne
Copy link

bdionne commented Apr 6, 2012

draining them is what I'm doing here -

cloudant/fabric@20ed391#L0R294

@bdionne
Copy link

bdionne commented Apr 6, 2012

I think I've also got the Timeout clause right -

cloudant/fabric@20ed391#L0R309

this agrees with your newest gist, non?

@bdionne
Copy link

bdionne commented Apr 6, 2012

oops, sorry, no, - cloudant/fabric@822e2f6

is the newest

@davisp
Copy link
Author

davisp commented Apr 6, 2012

I don't think you want that drain in there. The point of looping through the db updated messages is so that your mail box should never have a backlog so there shouldn't be anything to drain.

As to the Timeout clause, there should be no timeout state. That changse the behavior of the keep sending changes loop because its possible to timeout directly after you finish an update. The timeout should only be triggered after the get_state message as waited for Timeout seconds, not if there was more than Timeout seconds before the get_state message with no db_updated message. Its slight and subtle, but I bet it'd at least break tests.

@bdionne
Copy link

bdionne commented Apr 6, 2012

Agree about the timeout (typo there), not sure I agree about the drain but I'll defer to your judgement there. Let me push a PR so we can get more eyeballs on it

cloudant/fabric@cca4750

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment