// token only for Abortable Jobs protected abstract LongRunStatus?ExecuteRaw(T args, LongRunInfo info, CancellationToken cancellationToken);
public async Task <LongRunResult> EnqueueLongRunAsync <TJob, TArgs>(TArgs args, BackgroundJobPriority priority = BackgroundJobPriority.Normal, TimeSpan?delay = null) where TJob : LongRunBackgroundJob <TArgs> { LongRunInfo longRunInfo; string longRunId; // i removed try catches for persisting. // let it be handled by unit of work and thorwing exceptions using (var unitOfWork = UnitOfWorkManager.Begin()) { longRunId = _keyGenerator.Generate <string>(); longRunInfo = new LongRunInfo { Id = longRunId, //todo: serializer? or json repo? Args = JsonConvert.SerializeObject(args), LongRunStatus = LongRunStatus.Queued, Type = typeof(TJob).ToString(), }; await _longRunInfoRepo.InsertAsync(longRunInfo); await unitOfWork.CompleteAsync(); } string jobId; try { // try to queue job var longRunArgs = new LongRunArgs <TArgs> { Args = args, LongRunInfoId = longRunId }; jobId = await EnqueueAsync <TJob, LongRunArgs <TArgs> >(longRunArgs, priority, delay); } catch (Exception e) { try { using (var unitOfWork = UnitOfWorkManager.Begin()) { longRunInfo = await _longRunInfoRepo.GetAsync(longRunInfo.Id); longRunInfo.LongRunStatus = LongRunStatus.QueueFailed; longRunInfo.Error = e.ToString(); await unitOfWork.CompleteAsync(); } } catch (Exception) { //todo: additional handler? } throw; } try { using (var unitOfWork = UnitOfWorkManager.Begin()) { longRunInfo = await _longRunInfoRepo.GetAsync(longRunInfo.Id); longRunInfo.JobId = jobId; await unitOfWork.CompleteAsync(); } } catch (Exception) { //todo: additional handler? } return(new LongRunResult { LongRunId = longRunId, JobId = jobId }); }