-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate event deferral #966
Comments
Thanks for that list of reasons, @sed-i. I actually think this is a good idea, and you're right that defers cause a bunch of problems. If you're waiting for some other precondition to be true, just wait for that precondition / event, rather than defer. That said, it might be a bit premature to deprecate it until we have custom workload events (via the upcoming Pebble Notices). Some things the charm will need to be woken up by aren't events right now, so charms have to rely on defer (and the deferred event being re-emitted during update-status). Thoughts on deprecating @jameinel? I know you've expressed a similar sentiment in the past. |
@benhoyt I pretty much agree with you. We should get rid of defers but we need a better waiting mechanism than "just do it in update-status". Duplicate code often gets out of sync and might cause more bugs than deferring. The alternative would be just waiting inside the hook which seems like a very bad idea as it could halt the execution of all hooks for an unbounded amount of time. I definitely think it would be premature at this point. |
Agreed too. Having a way to |
A scenario that I hit recently which I think could easily trip up others is when conditions, such as leadership, gate deferring an event. For example if an application (lets say a database) has multiple units it is reasonable for a charm author to say that they want the lead unit to manage creating users etc in the database itself. The request for a db user via a juju relation could come at anytime during the charms lifecycle so if this happens before the db is ready the code below will defer the event for the lead unit but not for the others
If the leader pod is recreated for any reason the client request is lost. In fact, if the leadership changes for any reason before the db is ready the deferred request will not be processed (unless leadership happens to flip back to the previous leader). An alternative approach would be for all units to defer the request. But on a system where leadership is stable every non-leader unit on every hook execution will have to process and re-defer these events potentially for the lifetime of the application (in a DBaaS offering this could be a lot of events). Perhaps I have missed a trick somewhere but I hit this very situation when testing the OpenStack k8s charms (admittedly on a system under memory pressure) |
Hi team, I'd like to make a case for keeping The main advantage of
And we need to run whatever logic in C-* events after B-*. Now, at deployment of that bundle, we will have in unit of app A, the following events happening: Some time ago, we'd use
With
The The first iteration of charm lib could not do it, unfortunately. Actually, on that first iteration, it was common to do exactly as mentioned in:
The second iteration (reactive), we could create custom states and gate certain functions to be called at certain moments. It was very flexible and we could break the code as we wanted. The We may have issues with For example, if events have all the same parameters (or are empty), I honestly think we should silently abandon a deferred event if another is already scheduled. That means less event runs, with potentially less time touching relation databags, restarting services, etc. Likewise, there are solutions for the stop issue, as proposed in the bug. At upgrade, I do not really see a problem to break the "deferred events" and have the upgrade-charm to be in charge of bridging any intermediary state. I can actually make the same case for a "install" event that happens at day-2, i.e. we have a bunch of units and databag is already populated. There is some figuring out in "where we are at this moment" which is inevitable. In my opinion, this problem is independent of |
That's robust push-back and excellent commentary, thanks @phvalguima. I'm putting together a notes document which I'll use to guide the agenda for the meeting at the sprint. |
@phvalguima How are you able to separate the C relation logic entirely if handling for the C relation depends on information in the B relation? The mysql router charm handles exactly the situation you mentioned—it has two relations & it has to handle them in a specific order.
The relation with the App depends on information in the relation with Server. Previously, the charm was written with two separate files for each relation with their own event handler & with defers. However, these weren't cleanly separated and self-contained event handlers—each event handler contained a lot of information about the other relation. This made the charm quite difficult to read (and buggy)—so we refactored the two event handlers into a single event handler and it make things much simpler & more robust. What I'm getting at is that if you have event ordering dependencies between two relations, I believe you also have information dependencies across the two relations—and it won't be possible to have two cleanly separated handlers Do you see a clean design with I think there's a lot of use cases for |
For clarification: when I say @carlcsaposs-canonical, as I understand, in your case Mysql Router is in charge of receiving its own credentials from server and then, during its lifecycle, generating 1/more app credentials and passes them to the app. You can always mix handlers: as you are doing in reconcile. So, in my view, your charms work like: With defer, we could write it as follows:
|
I wonder if pebble notices could obviate defer for the use cases @carlcsaposs-canonical describes. |
We're not going to deprecate |
event.defer()
sends charm authors on the wrong path (see enumeration below) and stands in the way of new necessary features. Can we deprecate it?Why you shouldn't use
defer
(Adapted from #935 (comment))
defer()
, which would be functionally equivalent.defer()
functionality encourages charm authors to usedefer()
for inter-event flow control, which, as mentioned above, breaks on upgrade.defer()
and re-emit, making deferred events not as useful.defer()
pattern puts a charm in error state because "two objects claiming to be X have been created".The text was updated successfully, but these errors were encountered: