I see a lot of charms with both a relation-changed
and a relation-joined
hook for their relations. Sometimes the two hooks are even the same file, with one being a symlink to the other. However, the juju docs say that both the relation-joined
and relation-changed
hooks run when a relation is joined.
Should my charm include only one hook or the other, not both?
This depends on the use case for the charm. Here's a good way to think of what each relation hook does and when it's executed:
relation-joined
This is always the first hook to be executed, it's also only executed once during the lifespan of that specific service to service relation. There's now guarantee on which of the two services hook will fire first, but it will always be the first of the set of relation hooks to fire off. A lot of charms don't need this, but some charms this is very important. If you have any set-up details you need to execute first, then this is where they will happen. Take a database server for example: Most database server charms use the
relation-joined
hook to create the database, user, password, and other details that the other service will be waiting on. It could do this during therelation-changed
hook, but it would add more complexity to make sure it didn't recreate the database and user over and over again (more on why that would happen in a second).relation-changed
This gets run once right after a successful
relation-joined
execution. Then every time data is sent on the wire between the services this hook is executed again. As such, it really needs to be idempotent as it will likely be executed more than once. So a lot of charms will gather the expectedrelation-get
data and make sure it exists before continuing. As to why both therelation-joined
ANDrelation-changed
hooks fire one after the other on the joined event is likely to allow for ease of use and not require arelation-joined
hook explicitly.As to what should your charm include, that's entirely up to you and the use case for your charm. Not every charm has a
relation-joined
, in fact few do considering the size of the store. It's really only used when there's an explicit need to do something only once during the lifecycle of that relation. Just so we're clear, when I mean "only once", I'm speaking about executing of thejuju add-relation
. If you add another relation to another service therelation-joined
hook and the whole lifecycle starts over again. (since you can theoretically connect multiple services to one relation on one service)