Is a set state called multiple times?

Cory Johns cory.johns at
Thu Jul 27 19:53:45 UTC 2017

On Thu, Jul 27, 2017 at 12:29 PM, Tilman Baumann <
tilman.baumann at> wrote:

> Problems with interfaces:
> - *.connected state gets dropped when one  unit leaves. Not when the
> last one leaves.

If this is happening, then it's because the particular interface layer is
doing something wrong in how it's setting or removing the state with the
Conversation API.  However, this is made easy to get wrong by the confusing
nature of the Conversations API, which we are working on addressing.

> - self.* only works when code runs in the right hook context

The purpose of the Conversations API (self.conversations()) was to address
this so that the handlers wouldn't need to keep track of the specific
relation IDs and unit names that the hook context supplies.  So, if the
interface layer is written correctly within that metaphor, the actual hook
context is irrelevant.  However, we're working on an improved API that
solves the same issue while being more explicit about what it's doing to
reduce the confusion.

> - interface class reference is only passed in decorated functions if the
> hook inside the interface code ran

The class reference is passed to any handler decorated with a @when
decorator with a state that was set by an interface layer class using
Conversation.set_state() (or the self.set_state() helper on the interface
class, which is essentially self.conversations()[0].set_state()).  This
will happen regardless of what hook context the charm is currently
executing in.

Part of the API improvements will remove the instances from handler params
and make them available via a global context which will always provide a
consistent way to access them.

> - Only the first occurrence of a unit joining a relation can be caught
> with handler

All joining units can be handled by interface layers.  The joined hook will
run for all joining units, and those units will be added to the interface
instance's conversations if the joined state is applied within the the
@hook decorated handler.  Those units can then all be accessed by iterating
over self.conversations() in a interface instance method called from a
@when decorated handler (but not from the @hook decorated handlers in the
interface class; those will only see the one unit :/).

Part of the API improvements for this will be to have some of the flags
(states), such as joined, managed automatically by the framework (which
should remove the need for @hook handlers entirely and also reduce
boilerplate), and then to provide explicit methods for associating specific
units with flags as well as seeing what units are associated with a given

If you are interested in learning more about how we're looking to improve
charms.reactive and contributing to the discussion, I invite you to take a
look at  That PR
contains documentation for the proposed API changes, and a lot of
discussion hashing out how best those API should look to the user.  In
fact, it might even be a bit too much discussion for a GitHub PR comment
stream to organize well.  :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Juju mailing list