Is a set state called multiple times?

Tilman Baumann tilman.baumann at canonical.com
Thu Jul 27 16:29:38 UTC 2017


The confusion comes from the expectations that states are somehow events
and @when decorators are event handlers.
@when are predicates on states. When predicates are true the decorated
code is executed at every hook invocation.


If you want to trigger on edges (state changes) you need to build flipflops.


@when("state.wanted")
@when_not("state.reached")

do stuff here when entering state
set_state("state.reached")


@when_not("state.wanted")
@when("state.reached")

do stuff here when leaving state
remove_state("state.reached")


Reactive is still quite nice after you wrapped your head around that.


// Rant follows

Shame though that ALL interfaces are broken and thus unusable.

Interfaces need to be fixed on a fundamental level IMHO.
I have a workaround proposal
https://github.com/tbaumann/charm-interface-peer-discovery/blob/master/peers.py
But in truth, that is not a great solution, it's just a workaround.

I know I'm derailing the conversation here completely, but the
brokenness of interfaces has been a personal annoyance for a while and I
wish I could do something to change that.

One of the issues is that one can not react on "relation.connected"
states because the context they are supposed to have (argument to
decorated function) only works in the right hook context.
I propose a @interface decorator which will create the right context and
instantiate a interface object.
That way I can use interfaces in all sorts of functions and not only in
hook context and the kludges around to avoid being called outside of
hook context.


Problems with interfaces:
- *.connected state gets dropped when one  unit leaves. Not when the
last one leaves.
- self.* only works when code runs in the right hook context
- interface class reference is only passed in decorated functions if the
hook inside the interface code ran
- Only the first occurrence of a unit joining a relation can be caught
with handler
- Interfaces have 90% identical code which is just boilerplate



Just my 0.02€


On 27.07.2017 03:37, fengxia wrote:
> Hi Juju,
> 
> Once I set a state, set_state("here"), I want to make sure its @when
> will only be executed ONCE (when "here" from False->True).
> 
> So my thought is to remove_state("here") in its @when("here") code
> block. If I don't, will this @when be called multiple times if I don't
> reset this state? What's the good practice here?
> 



More information about the Juju mailing list