Hangfire icon indicating copy to clipboard operation
Hangfire copied to clipboard

Support for `async` background job methods

Open odinserj opened this issue 11 years ago • 43 comments

Heavy I/O bound background jobs consume worker thread inefficiently – instead of doing the real work they wait for the completion of I/O operation(s). Currently if an application has a lot of such background jobs, it is better to increase the worker pool size to process jobs more efficiently. However increased worker pool causes performance problems for CPU-bound jobs.

Instead of waiting for the I/O completion, it would be useful to yield the worker thread to process another background job instead, for example, using the default mechanism with async and await keywords:

public async Task IOBoundMethod()
{
    var documents = await _documentsService.FetchAll();
    documents.Process();
}

But we should ensure that the completion is being called inside the Hangfire's worker thread, and not in CLR's thread pool thread (to not to compete with request processing pipeline, use additional storage connections and so on). Another consideration should be dedicated to job filters – CaptureCultureAttribute changes the thread context, and it should be changed again on each continuation. There are also problems with reliability (outstanding jobs should be requeued), shutdown events (outstanding operations should be canceled), and perhaps with something else.

odinserj avatar Jun 29 '14 15:06 odinserj

Yo this would be amazing. +1

ghuntley avatar Aug 15 '14 11:08 ghuntley

cant wait to see this come really :+1:

devmondo avatar Aug 15 '14 14:08 devmondo

+1 here too. Definitely a requirement on my end.

unt1tled avatar Aug 17 '14 13:08 unt1tled

+1 this would be very nice (http://discuss.hangfire.io/t/async-task-jobs/73)

marius-stanescu avatar Aug 25 '14 21:08 marius-stanescu

that would be great!

marcoCasamento avatar Aug 26 '14 07:08 marcoCasamento

+1 killer feature for me

itmeze avatar Aug 27 '14 22:08 itmeze

:+1:

treymack avatar Sep 04 '14 18:09 treymack

+1

As of now Hangfire does not protect you from incorrectly using async methods as background tasks. I.e. you can schedule an async operation which will run successfully (however, Hangfire will not await the result so esceptions will be lost + job execution statistics will be incorrect). If async support is far down the road, how about throwing an exception when trying to schedule/run a job which returns a Task?

Isantipov avatar Nov 18 '14 11:11 Isantipov

@Isantipov, this is a brilliant proposal, will schedule it for next minor release

odinserj avatar Nov 18 '14 11:11 odinserj

:+1:

di97mni avatar Feb 24 '15 15:02 di97mni

+1. Maybe this year?

parliament718 avatar Apr 24 '15 05:04 parliament718

+1

chfumero avatar May 29 '15 22:05 chfumero

+1

oliverkane avatar Jul 22 '15 23:07 oliverkane

+1

mjohnson0580 avatar Aug 05 '15 08:08 mjohnson0580

+1

jbizkit avatar Aug 24 '15 17:08 jbizkit

+1 (luis.matta recent pro buyer)

levmatta avatar Sep 02 '15 12:09 levmatta

+1

Otto404 avatar Sep 09 '15 08:09 Otto404

+1

keesschollaart81 avatar Sep 14 '15 09:09 keesschollaart81

+1

AdityaSantoso avatar Sep 17 '15 09:09 AdityaSantoso

Wow, such a popular feature, want it too :-) This feature requires a lot of breaking changes and it is postponed to the version 2.0, that will be released in the next year with async methods for storages as well.

odinserj avatar Sep 18 '15 11:09 odinserj

@odinserj, do you already have any idea about the async method you need from the storage ?

marcoCasamento avatar Sep 18 '15 12:09 marcoCasamento

@marcoCasamento, please see #401.

odinserj avatar Sep 18 '15 12:09 odinserj

Is there any news on this yet?

Gillardo avatar Dec 09 '15 09:12 Gillardo

Hi @odinserj - any idea when async will be here. Will definitely be moving up to the pro version when this happens?

dandcg avatar Feb 11 '16 16:02 dandcg

+1

...except I'm not sure how you're going to pull off keeping it limited to pro. In my mind only two things need to be done:

  1. Add overloads that accept Expression<Func<Task>>, including those variations that accept a generic instance argument, ~~and variations that accept CancellationToken instances as well~~ it looks like there is already support for CancellationToken
  2. Add the bit of code that waits for the Task, if any, to complete and catches any AggregateException ~~(possibly with some flattening.)~~ (Link to relevant code)

tuespetre avatar Mar 08 '16 14:03 tuespetre

Alright, so I've submitted a PR that adds support. I should note that for the time being, it's really not a big deal to go without this support -- all one needs to do is provide both SomeMethod and SomeMethodAsync:

public void SomeMethod()
{    
    try
    {
        SomeMethodAsync().Wait();
    }
    catch (AggregateException aggregate)
    {
        throw aggregate.InnerException;
    }
}

public async Task SomeMethodAsync()
{
    await ...
}

A little bit of churn, sure, but then "actual" async support requires one to put in those #pragma warning disable 4014 statements or deal with compiler warnings. Oh well. :beers:

tuespetre avatar Mar 08 '16 16:03 tuespetre

+1

rosdi avatar Mar 19 '16 21:03 rosdi

+1

bezzad avatar Mar 20 '16 08:03 bezzad

+1

mwhitis avatar Mar 23 '16 18:03 mwhitis