Is it possible to support the built in CancellationToken instead of IJobCancellationToken?
This would be useful, when using a common method that is used by a Hangfire job and another windows service, I would like to only have to pass it one type of cancellation token.
I've exposed the IJobCancellationToken.ShutdownToken property to be able to cancel outstanding operations on server shutdown without additional waits. It cancels only on shutdown event instead of IJobCancellationToken itself, that is being canceled also on a job's state change. I can' imagine how to fully convert IJobCancellationToken to the CancellationToken and think that shutdown event would be enough for the most cases.
public void LongRunningJob(IJobCancellationToken cancellationToken)
{
OutstandingOperation(cancellationToken.ShutdownToken);
}
In theory, this is a breaking change, however I can't imagine someone will have a custom implementation in practice (if I wrong, I'll reconsider my conservativity).
Hi!
Checking cancellation token instead of immediately throwing on it or passing .net CancellationToken struct is widely used scenario in my project.
First generic example i can think of:
await Task.Delay(time, token);
I tried to create workarounds for this, involving background polling of jobToken. Using an exception-driven-development pattern to poll "ThrowIfCancellationRequested" (cancel in catch), or reflection to poll private ServerJobCancellationToken.IsJobAborted method. Both are working, but fishy...
Is there another way to deal with user cancellation in Hangfire without throwing exceptions? Or maybe, Hangfire-legit way to subscribe to job state change event inside the job?
Thank you.
@odinserj
I have a scenario where I make a POST request using the HttpClient class. In that POST I send a CancellationToken from the System.Threading namespace because on the other side we have a long running operation and sometimes we need to cancel it before it is finished. Is there a way to make the IsJobAborted method from the ServerJobCancellationToken observable? Doing so I could call the CancellationTokenSource.Cancel method to cancel the request.
The main reason to do this is because we have to wait a whole iteration to complete to really abort the operation. Shouldn't the ShutdownToken be in the cancelled state even if the cancelation was not generated by a shutdown? That way we could create a LinkedTokenSource.
Thank you.
Why is important to allow cancel outstanding calls "only" on shutdown events? Why not allow cancel outstanding calls when the job state change?
This is turning out to be a growing need for our product which is using Hangfire. Digging into the dashboard code, it seems that deleting a processing job only changes the state in the storage. Each running job needs to poll periodically to handle any changes. I don't see an easy way to do this in Hangfire without many changes...
Personally to overcome the limitations imposed by IJobCancellationToken, I unwrapped the thrown error to call back a cancel to my own, true CancellationToken.
var source = new CancellationTokenSource();
#pragma warning disable 4014
Task.Run(() =>
#pragma warning restore 4014
{
try
{
while (true)
{
Thread.Sleep(1000);
cancellationToken.ThrowIfCancellationRequested();
}
}
catch (Exception e)
{
source.Cancel();
}
}, source.Token);
var result = await Task.Run(async () => await Abc(source.Token), source.Token);
Rather disappointed I had to do this, as I'm utilizing Hangfire among many reasons but notably to eliminate polling. Using the IObservable pattern I have an Observer within the job that I'd like to cancel, which doesn't involve any loops where I could simply make a call to ThrowIfCancellationRequested.
I mistakenly assumed the ShutdownCancellationToken would be called when the job was otherwise deleted, how is this not a part of the functionality?
Most helpful comment
Why is important to allow cancel outstanding calls "only" on shutdown events? Why not allow cancel outstanding calls when the job state change?