juju emitting `relation_broken` while there are remaining units in the relation

Bug #1979811 reported by Paulo Machado
24
This bug affects 4 people
Affects Status Importance Assigned to Milestone
Canonical Juju
Fix Released
Undecided
Teodora Mihoc

Bug Description

Juju version: 2.9.32 (initially detected on 2.9.29)
LXD cloud

Given an app A with 3 units related to and app B,
when scaling in app A with `juju remove-unit A/0`
the unit A/0 will receive a `relation_broken` event.

This behavior seems to contradict the documentation,
where is said the event will be triggered:
> once all the units have been removed
since app A is active with two units and still related
to app B.

This tests where done against in development mysql-operator
(https://github.com/canonical/mysql-operator/tree/feature/shared_db_refactor)
using `shared-db` relation.

Revision history for this message
Juan M. Tirado (tiradojm) wrote :

Could you please point to the section of the documentation where this is described?

Changed in juju:
status: New → Triaged
Revision history for this message
Paulo Machado (paulomachado) wrote :

Sure!

https://juju.is/docs/sdk/relations#heading--event-types

at the Description of `<name>_relation_broken`

Changed in juju:
status: Triaged → Invalid
Revision history for this message
Joseph Phillips (manadart) wrote :

This is not accidental behaviour - it is quite explicit in the logic, that a dying unit gets a relation-broken hook invocation for relations it is participating in.

We need to update the documentation to this effect.

This behaviour is long-standing. I've traced it as far back as 8 years ago, so the potential for breakage in the ecosystem from changing this is significant.

Revision history for this message
Carl Csaposs (carlcsaposs) wrote :

Would it be possible to add information to the event to determine if the relation is actually breaking?

Many of our charms need to perform cleanup (e.g. delete a user) if the relation is breaking. To do so currently, each of our charms has to add a workaround that stores state during the relation departed event if the departing unit == unit and then check that state during the relation breaking event. Example: https://github.com/canonical/postgresql-operator/blob/e13b871022bb6cff44cfb3ca83427c0e9d03f606/src/relations/db.py#L193

Revision history for this message
Joseph Phillips (manadart) wrote :

Deliberate behaviour and work-arounds aside, I am of the view that a departing unit should *not* actually get a relation broken event.

The life-cycle of the relation itself is an application level concern, and a departing unit should not have the option of acting on that concern if it was not affected at the application level.

Revision history for this message
Carl Csaposs (carlcsaposs) wrote :

Related bug report (no workaround possible) for subordinate charms: https://bugs.launchpad.net/juju/+bug/2025676

Revision history for this message
Ian Booth (wallyworld) wrote :

If you had asked me before this bug was raised, I would have said the juju behaviour would have been to only run relation broken after all counterpart units had left the relation scope. It seems that's not the case and to me that's a bug. Furthermore, the hook behaviour was implemented before we had unit leadership. And I do agree that a broken relation is an application level concern, so the relation broken hook should I think only run on the leader unit.

Regardless of compatibility concerns, if we agree the current behaviour is broken, we should fix it instead of making the problem worse by doing some work around. We can always make it opt in using a charm "assumes" directive and make it default in juju 4.

Revision history for this message
John A Meinel (jameinel) wrote :

All units get 'relation-created' so I think all units should get 'relation-broken'. But I do understand the concern around "the relation isn't really going away, you're just being removed"

Revision history for this message
Paulo Machado (paulomachado) wrote :

Does a unit receives a 'relation-created' if the said unit is created after the relation was established or just pre existing units will receive?

Revision history for this message
Carl Csaposs (carlcsaposs) wrote (last edit ):

Yes, a unit receives relation-created if the unit starts after the relation is established.

This is helpful, for example, with the mysql <-> tls-certificates-operator relation. Each unit needs its own TLS certificate, so each unit requests a certificate on relation-created.

But for that example, getting a relation-broken event during single unit teardown as opposed to a stop or remove event isn't necessary. Off the top of my head, I can't think of an example where getting a relation-broken event during single unit teardown would be helpful

Revision history for this message
Paulo Machado (paulomachado) wrote :

Is it feasible to include a new field in the relation-broken with the reasoning for the break?
So when ops render the event sent to the charm, it's possible to know that the relation is breaking for the unit only.
This would keep the created-broken symmetry and delegate any special treatment to the charm.

Revision history for this message
Mia Altieri (miaaltieri) wrote :

Is it feasible to include a new field in the relation-broken with the reasoning for the break?
So when ops render the event sent to the charm, it's possible to know that the relation is breaking for the unit only.
This would keep the created-broken symmetry and delegate any special treatment to the charm.

^ this would be very helpful for my own charm as well

Teodora Mihoc (tmihoc)
Changed in juju:
assignee: nobody → Teodora Mihoc (tmihoc)
tags: added: canonical-data-platform-eng
Revision history for this message
Teodora Mihoc (tmihoc) wrote :

Updated the doc to clarify.

Changed in juju:
status: Invalid → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.