Re: comment #21 and gating; if this is fully async, then gating is only going to tighten the race, but not eliminate it. i.e. code like:
if is_leader(): leader_set(...)
can still error as the leadership could be lost between the two calls. The only safe way of doing leadership code is probably something like:
if is_leader():
try:
# do things you have to do before calling leader_set() leader_set(...) # if this passes, we are the leader
# do other things that depend on being the leader
except NotImplementedError: # because that's what bizarrely is returned by charmhelpers
# we're not the leader after all (or something else ... can't really tell)
if not is_leader():
# we're not the leader any more, undo any damage
else: raise # something else went wrong
except OtherErrorsTheCodeMayHaveThrownIfWeAreInterested:
# etc
Anyone spot any problems? If this is a pattern, we should try to get it into charmhelpers as a context manager or similar.
Re: comment #21 and gating; if this is fully async, then gating is only going to tighten the race, but not eliminate it. i.e. code like:
if is_leader():
leader_ set(... )
can still error as the leadership could be lost between the two calls. The only safe way of doing leadership code is probably something like:
if is_leader():
leader_ set(... ) # if this passes, we are the leader rror: # because that's what bizarrely is returned by charmhelpers
raise # something else went wrong odeMayHaveThrow nIfWeAreInteres ted:
try:
# do things you have to do before calling leader_set()
# do other things that depend on being the leader
except NotImplementedE
# we're not the leader after all (or something else ... can't really tell)
if not is_leader():
# we're not the leader any more, undo any damage
else:
except OtherErrorsTheC
# etc
Anyone spot any problems? If this is a pattern, we should try to get it into charmhelpers as a context manager or similar.