Support for scheduling jobs in the future

I think having the ability to schedule a job for execution after a given point in time is a crucial feature for a background processing system.
At the moment, this is possible with *queue_classic* only by using [queue_classic-later](https://github.com/dpiddy/queue_classic-later), which is quite clunky to use (you need a second database table and a tick process).

So I quickly implemented a very minimal solution that uses the already existing *created_at* column of the jobs table to specify the time by which a job may be executed.

##### Example:

```ruby
# schedule a job in 10 seconds
QC.enqueue_at Time.now + 10, 'Kernel.puts'
# job is not being locked at this point in time
QC.lock # => nil
# when you wait (at least) 10 seconds...
sleep 10
# job can be locked now
QC.lock # => {method: 'Kernel.puts', ...}

# scheduling a job without a time constraint
# works just as it used to
QC.enqueue 'Kernel.print'
QC.lock # => {method: 'Kernel.print', ...}
```

What do you think? Is this feature generally a useful addition? If yes: is the implementation/API ok or would there be a better solution?


*Note: this pull request would need some more work (e.g. documentation) which I would gladly provide/improve, if you decide that you want this feature...*
It should be a delta from now; that should avoid skew between ruby /
Postgres :-)

On Friday, October 10, 2014, Jean-Philippe Boily <notifications@github.com>
wrote:

> In lib/queue_classic/queue.rb:
>
> > +    # must be in the form described in the documentation for the #enqueue
> > +    # method.
> > +    def enqueue_at(time, method, *args)
> > +      offset = time - Time.now
> > +      enqueue_in(offset, method, *args)
> > +    end
> > +
> > +    # enqueue_in(t,m,a) inserts a row into the jobs table representing a job
> > +    # to be executed not before the specified time offset.
> > +    # The seconds argument must be a number. The method and args argument
> > +    # must be in the form described in the documentation for the #enqueue
> > +    # method.
> > +    def enqueue_in(seconds, method, *args)
> > +      QC.log_yield(:measure => 'queue.enqueue') do
> > +        s = "INSERT INTO #{TABLE_NAME} (q_name, method, args, scheduled_at)
> > +             VALUES ($1, $2, $3, now() + interval '#{seconds.to_i} seconds')"
>
> You are using a DB time here, but a Ruby time for the euqueue_at. I would
> stick with one or the other. Thoughts?
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/QueueClassic/queue_classic/pull/217/files#r18726700>.
>


-- 

Russ
Rainforest  |  +1-650-919-3216 |  rainforestqa.com
<https://www.rainforestqa.com/?utm_source=rhs&utm_medium=email&utm_campaign=russ_sig>