This repository has been archived by the owner on May 26, 2021. It is now read-only.
forked from resque/resque
-
Notifications
You must be signed in to change notification settings - Fork 1
Failures 2.0
tarcieri edited this page Apr 4, 2013
·
8 revisions
The Resque::Failure API presently suffers from a lot of problems. Here are some of the major ones:
-
Too many singletons: Have a look through failure.rb and failure/base.rb and you will notice that the API is almost exclusively singletons. There are hardly any instance methods (
base.rb
defines a#save
method and that's really it) - Failures aren't objects: There's a clear reason why there are so many singletons: when you ask for a failure, what you get back isn't a Resque::Failure object. It's just a JSON blob parsed into hash literals. Want to know anything about the failure? You have to dig through the JSON structure, which depending on where it originated from (lots of people like implementing Resque-alikes in other languages) may or may not have the elements you care about. IMO, when you ask for a failure, you should get a Resque::Failure object.
- Failures don't have unique IDs: I think that every failure should be identified by a unique ID (similar to a primary key) and that all APIs should accept these IDs. I have done some work with the existing code to try to facilitate this, but the API isn't great.
-
Too many arguments: Looking at failure.rb#79,
Resque::Failure#each
already takes 5 arguments. This seems like a pretty clear candidate for an options hash. -
Wacky APIs: For whatever reason, by default Resque::Failure.all only returns one failure object (as a parsed JSON blob). To actually return all failures, we need to consult
Resque::Failure.count
first, then pass that intoResque::Failure#all
. It seems pretty clear to me this API is in need of some love. -
Multiple backends with inconsistent logic: To see how painful this is, check out resque-web's RetryController. ZOMG! That is some gnarly code, working around the above mentioned deficiencies and inconsistencies between the existing failure backends. Ideally, all backends would be unified under a consistent API. That was the original goal of the
Resque::Failure
module, but unfortunately it falls quite short.
These are @tarcieri's suggestions for fixing the API:
-
More like ActiveRecord: I think an ActiveRecord-alike API would make
Resque::Failure
intuitive to anyone who's familiar with ActiveRecord, and provides a fairly decent pattern for how these sort of persistence APIs should work. CallingResque::Failure.all(:queue => 'myqueue')
should return an array of Resque::Failure objects. I should be able to do things to aResque::Failure
object via instance methods, like#destroy
it or#retry
it. -
Multiple failure queues or GTFO: Resque originally supported a single 'failed' queue, unfortunately as more people started using it, this was quickly shown not to scale very well. The failure API should be designed around the idea that every queue has its own individual failure queue. IMO,
Resque::Failure::Redis
should be completely deleted from Resque 2.0, and theResque::Failure::RedisMultiQueue
backend should replace it. - Support ActiveRecord as a failure backend: Redis queues are just not a great way to store failures. If one person views the failure page and deletes a failure, and someone else tries to delete a different failure, the second person will end up deleting the wrong failure, because its position in the failure queue has changed. THIS IS BAD! I'm not saying that we should dump a Redis-based failure backend, but it's quite clear that the failure system has outgrown what Redis can do, and really needs a database that can do better querying of the data and can represent each failure with a primary key. I think it would really make sense to (optionally) support an ActiveRecord-based failure backend which provides a lot more rigorous semantics around how failures are handled.