This is a rant.
Today, I dug into updating from Celery 2.5.3 to 3.0.4, and I popped my cork.
I am aggravated by the frequency and extent of Celery API changes. It’s easily changed more often than any other five technologies in our stack combined. I’ve been upgrading Celery and Django-celery every six months or so, which corresponds to upgrading every few minor versions. And the changes are similar in scope to what I see when upgrading any other technology across one or two major versions.
Changes that may seem minor, like moving a class across modules (e.g., from celery.task.base to celery.app.task), are nontrivial when you have change lots of code. I might feel better if the edits gave my code some awesome new capabilities. But they don’t, so my internal reaction is, Why the <expletive> does this code have to change? Couldn’t the <unbelievably gross expletive involving a deformed farm animal> code have stayed where it <repeat the expletive> was?
The decorators change, the imports change, how to specify periodic tasks changes….FUCK. It’s maddening. The 2.5.3 -> 3.0.4 upgrade is enough to make me start thinking about replacing Celery.
I had a nice exchange with @asksol about this on #celery. He’s a smart, helpful, and friendly guy who’s always open to chatting and answering questions. (And he doesn’t deserve people like me using the fruits of his labor!) The exchange went something like this (I’m paraphrasing):
Me: Could the API not change so much?
Asksol: It doesn’t change so much.
Me: What about a, b, and c?
Asksol: There’s a compatibility API for that. You don’t have to change your code.
Me: But the compatibility API isn’t documented, and it will eventually be removed, so I either change my code now or later.
Asksol: It will be a very long time before the compat APIs are removed.
I came away sensing that we had a communications impedance mismatch. Although we spoke the same language, we didn’t see the problem with anywhere near the same degree of importance. He didn’t see it as anything notable, while I was thinking about killing small kittens.
From my perspective, deferring a code change doesn’t mean “I’ll never have to do it.” It means, “I’ll eventually have to do it, and my choice is, do it now or later.”
One could argue it’s always better to not change code unless you must, i.e., only when the deprecated code is actually removed. But the compatibility API isn’t documented, so someone looking for information before they edit this code will be massively confused. And I trust a maintainer when he/she warns that an API is deprecated, and I should use a replacement API; I’d rather make the necessary changes sooner than later because they’re, well, inevitable. It’s “good code hygiene.” Another reason to keep code current is so someone looking at it will (presumably) be better able to understand it. The reason why the maintainer deprecated something is because he/she doesn’t want it used anymore.
I don’t have the time for chasing after any more API changes. Or, more accurately, I choose to no longer do it. It’s time to catalog how many Celery features we use and look for an alternative.
End of rant.
I’m interested in hearing other opinions about when to update code based on a deprecated API. When do you do it?