How do I manually trigger a RelationChangedEvent?

I have a situation where if ConfigChangedEvent is processed on a charm, I then need RelationChangedEvent to be fired to tell another charm that relation data has changed so that it can process it.

This is because the charm whose config has changed sends some of the config data to the other charm that provides the interface, along with some other data obtained from other sources, so that the interface provider can re-configure itself appropriately.

Is there a way tell the operator framework that I’d like it to emit the RelationChangedEvent, preferably in such a way that the charm’s existing handler for the event can process it and populate the required data before the interface provider then receives it?

This will heavily depend upon the interface implementation.

You can see an example here:

https://git.launchpad.net/interface-prometheus/tree/operator.py?h=operator

In your interface implementation, you will need a callable function that your charm can call to update the information or at least trigger the configuration changes to currently related units.

The example on_config_changed addition for your charm.py is here:
https://git.launchpad.net/interface-prometheus/tree/operator.py?h=operator#n21

The called function to validate/update the relation information and inform current related units is here:
https://git.launchpad.net/interface-prometheus/tree/operator.py?h=operator#n147

and ultimately, the function that triggers relation-changed to the related units is here:
https://git.launchpad.net/interface-prometheus/tree/operator.py?h=operator#n107

Note: This implementation does not use the “use_lib” operator standard, so the formatting may be slightly different than you might expect.

2 Likes

RelationChanged is fired when the remote data has changed, not when your data has changed that you are giving to the other side.

If you just want to update your relation data that you are telling other applications about I would think it would be something like:

for relation in self.model.relations['db']:
  relation.data[self.unit] = ???

IOW you are updating your relation data bucket in response to config changed, which should fire the relation-changed event for units of related applications.

2 Likes

Excellent, thank you very much, updating the relation’s data does the job perfectly.

I didn’t realize that this would automatically update the remote without some other manual trigger, but it works really well.

1 Like

Glad to hear that’s working well.

Under the covers, the provider of the relation runs the “relation-set” juju agent tool with the context of the relation ID and remote unit to set the new value on the relation, and then the juju controller triggers the relation-changed event on the remote unit to have it pick up and process the new data set in the relation’s context.