Event > List of events> Relation events >
<relation name>-relation-changed
See also: A charm’s life, The lifecycle of charm relations, Discussion on hooks: relation-departed and relation-broken, Relation-broken hook not running in peers relation, Charm hooks
Before juju v.3.0
, ‘integrations’ were called ‘relations’. Remnants of this persist in the names, options, and output of certain commands, and in integration (relation) event names.
relation-changed
is emitted when another unit involved in the relation (from either side) touches the relation data. Relation data is the way for charms to share non-sensitive information (for sensitive information, juju secrets
are on their way in juju 3).
For centralized data – for example, a single password or api token that one application generates to share with another application, we suggest that charm authors use the application data, rather than individual unit data. This data can only be written to by the application leader, and each remote unit related to that application will receive a single
relation-changed
event when it changes.
Hooks bound to this event should be the only ones that rely on remote relation settings. They should not error if the settings are incomplete, since it can be guaranteed that when the remote unit or application changes its settings again, this event will fire once more.
Charm authors should expect this event to fire many times during an application’s life cycle. Units in an application are able to update relation data as needed, and a relation-changed
event will fire every time the data in a relation changes. Since relation data can be updated on a per unit bases, a unit may receive multiple relation-changed
events if it is related to multiple units in an application and all those units update their relation data.
Contents:
Emission sequence
This event is guaranteed to follow immediately after eachrelation-joined
. So all juju
commands that trigger relation-joined
will also cause relation-changed
to be fired. So typical scenarios include:
Scenario | Example Command | Resulting Events |
---|---|---|
Add an integration | juju integrate foo:a bar:b |
(all foo and bar units) *-relation-created -> *-relation-joined -> *-relation-changed
|
Additionally, a unit will receive a relation-changed
event every time another unit involved in the relation changes the relation data. Suppose foo
receives an event, and while handling it the following block executes:
# in charm `foo`
relation.data[self.unit]['foo'] = 'bar' # set unit databag
if self.unit.is_leader():
relation.data[self.app]['foo'] = 'baz' # set app databag
When the hook returns, bar
will receive a relation-changed
event.
Note that units only receive relation-changed
events for other units’ changes. This can matter in a peer relation, where the application leader will not receive a relation-changed
event for the changes that it writes to the peer relation’s application data bag. If all units, including the leader, need to react to a change in that application data, charm authors may include an inline .emit()
for the <name>_relation_changed
event on the leader.
When is data synchronized?
Relation data is sent to the controller at the end of the hook’s execution. If a charm author writes to local relation data multiple times during the a single hook run, the net change will be sent to the controller after the local code has finished executing. The controller inspects the data and determines whether the relation data has been changed. Related units then get therelation-changed
event the next time they check in with the controller.
Observing this event in Ops
In Ops, you can observe the event like you would any other:self.framework.observe(
charm.on.<relation name>_relation_changed,
self._on_<relation name>_relation_changed
)
The RelationChangedEvent
event object does not expose any specific attributes.