public async void RunAllJobs() { if (IsRunningJob) { return; } while (true) { IShareJob nextJob = null; // TryDequeue is thread-safe if (!InnerQueue.TryDequeue(out nextJob)) { AllJobsFinished?.Invoke(this, new EventArgs()); return; } nextJob.StatusUpdate += Job_StatusUpdate; nextJob.Finished += NextJob_Finished; IsRunningJob = true; CurrentJob = nextJob; JobStarted?.Invoke(this, new ShareJobQueueStatusEventArgs(nextJob, "Started")); await nextJob.Execute(); // executes NextJob_Finished when finished IsRunningJob = false; CurrentJob.StatusUpdate -= Job_StatusUpdate; } }
public async static Task StartJob(string jobDescription, int jobLength) { if (!IsJobRunning) { IsJobRunning = true; JobStarted?.Invoke(nameof(StartJob), new JobStartedEventArgs(jobDescription, jobLength)); // task delay so that user would atleast see something happening await Task.Delay(1000); } }
private async Task Run(CancellationToken token) { // checking if it's supposed to run // it assumes that CalculateNextRun has been called previously from somewhere else if (!NextRun.HasValue) { return; } // calculating delay var delay = NextRun.Value - DateTime.Now; // delaying until it's time to run or a cancellation was requested await Task.Delay(delay < TimeSpan.Zero?TimeSpan.Zero : delay, token); // checking if a cancellation was requested if (token.IsCancellationRequested) { return; } // used on both JobStarted and JobEnded events var startTime = DateTime.Now; // raising JobStarted event JobStarted?.Invoke(this, new JobStartedEventArgs(startTime)); // used on JobEnded event Exception exception = null; try { // running the job _job(); } catch (Exception e) { // catching the exception if any exception = e; } // used on JobEnded event var endTime = DateTime.Now; // calculating the next run // used on both JobEnded event and for the next run of this method CalculateNextRun(startTime); // raising JobEnded event JobEnded?.Invoke(this, new JobEndedEventArgs(exception, startTime, endTime, NextRun)); // recursive call // note that the NextRun was already calculated in this run _task = Run(token); }
public void OnJobStarted(JobInfo job) { using var scope = scopeFactory.CreateScope(); using var dataContext = scope.ServiceProvider.GetRequiredService <DataContext>(); job.State = JobState.Running; job.Started = DateTimeOffset.UtcNow; dataContext.SaveChanges(); userLogger.LogInfo("Job started", userId: job.UserId, jobId: job.Id); JobStarted?.Invoke(this, new JobStartedEventArgs() { Job = job }); }
/// <summary> /// Executes the job. /// </summary> /// <param name="job">The job.</param> /// <exception cref="NotImplementedException"></exception> public void ExecuteJob(IEngineJob job) { // Check if task can be executed if (!job.CanBeExecuted()) { job.AddMessage($"The job cannot be executed.", MessageSeverity.Error); throw new EngineException(logger, $"The job cannot be executed. This job was aborted."); } // Execute job if (JobStarted != null) { JobStarted.Invoke((Guid)job.EntityId, (Guid)job.InstanceID); } job.Start(); // Stop the job job.Stop(); if (job.HasErrors) { if (JobFinished != null) { JobFinished.Invoke((Guid)job.EntityId, (Guid)job.InstanceID, false); } job.AddMessage($"The job (instance: {job.InstanceID}) was not executed cause one or more errors occurs.", MessageSeverity.Error); throw new EngineException(logger, $"The job (instance: {job.InstanceID}) was not executed cause one or more errors occurs. This job was aborted."); } else if (job.HasWarnings) { if (JobFinished != null) { JobFinished.Invoke((Guid)job.EntityId, (Guid)job.InstanceID, false); } job.AddMessage($"The job (instance: {job.InstanceID}) was executed but one or more warning occurs.", MessageSeverity.Warning); throw new EngineException(logger, $"The job (instance: {job.InstanceID}) was executed but one or more warning occurs. This job was aborted."); } if (JobFinished != null) { JobFinished.Invoke((Guid)job.EntityId, (Guid)job.InstanceID, true); } }
private void _updateTimer_Elapsed(object sender) { var scsTelemetry = SharedMemory.Update <SCSTelemetry>(); var time = scsTelemetry.Timestamp; Data?.Invoke(scsTelemetry, time != lastTime); // Job close & start events if (wasFinishingJob != scsTelemetry.SpecialEventsValues.JobFinished) { wasFinishingJob = scsTelemetry.SpecialEventsValues.JobFinished; if (scsTelemetry.SpecialEventsValues.JobFinished) { JobFinished?.Invoke(this, new EventArgs()); } } if (wasOnJob != scsTelemetry.SpecialEventsValues.OnJob) { wasOnJob = scsTelemetry.SpecialEventsValues.OnJob; if (scsTelemetry.SpecialEventsValues.OnJob) { JobStarted?.Invoke(this, new EventArgs()); } } if (wasConnected != scsTelemetry.SpecialEventsValues.TrailerConnected) { wasConnected = scsTelemetry.SpecialEventsValues.TrailerConnected; if (scsTelemetry.SpecialEventsValues.TrailerConnected) { TrailerConnected?.Invoke(this, new EventArgs()); } else { TrailerDisconnected?.Invoke(this, new EventArgs()); } } lastTime = time; }
private void _updateTimer_Elapsed(object sender) { var scsTelemetry = sharedMemory.UpdateData(); // check if sdk is NOT running if (!scsTelemetry.SdkActive && !paused) { // if so don't check so often the data var tsInterval = new TimeSpan(0, 0, 0, 0, _defaultPausedUpdateInterval); updateTimer.Change(tsInterval.Add(tsInterval), tsInterval); paused = true; // if sdk not active we don't need to do something return; } if (paused && scsTelemetry.SdkActive) { // ok sdk is active now paused = false; Resume(); // going back to normal update rate } var time = scsTelemetry.Timestamp; var updated = false; if (time != lastTime || wasPaused != scsTelemetry.Paused) { // time changed or game state change -> update data Data?.Invoke(scsTelemetry, true); wasPaused = scsTelemetry.Paused; lastTime = time; updated = true; } //TODO: make it nicer thats a lot of code for such less work // Job start event if (wasOnJob != scsTelemetry.SpecialEventsValues.OnJob) { wasOnJob = scsTelemetry.SpecialEventsValues.OnJob; if (wasOnJob) { if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } JobStarted?.Invoke(this, new EventArgs()); } } if (cancelled != scsTelemetry.SpecialEventsValues.JobCancelled) { cancelled = scsTelemetry.SpecialEventsValues.JobCancelled; if (cancelled) { if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } JobCancelled?.Invoke(this, new EventArgs()); } } if (delivered != scsTelemetry.SpecialEventsValues.JobDelivered) { delivered = scsTelemetry.SpecialEventsValues.JobDelivered; if (delivered) { if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } JobDelivered?.Invoke(this, new EventArgs()); } } if (fined != scsTelemetry.SpecialEventsValues.Fined) { fined = scsTelemetry.SpecialEventsValues.Fined; if (fined) { Fined?.Invoke(this, new EventArgs()); } } if (tollgate != scsTelemetry.SpecialEventsValues.Tollgate) { tollgate = scsTelemetry.SpecialEventsValues.Tollgate; if (tollgate) { Tollgate?.Invoke(this, new EventArgs()); } } if (ferry != scsTelemetry.SpecialEventsValues.Ferry) { ferry = scsTelemetry.SpecialEventsValues.Ferry; if (ferry) { if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } Ferry?.Invoke(this, new EventArgs()); } } if (train != scsTelemetry.SpecialEventsValues.Train) { train = scsTelemetry.SpecialEventsValues.Train; if (train) { if (!updated) { Data?.Invoke(scsTelemetry, true); updated = true; } Train?.Invoke(this, new EventArgs()); } } if (refuel != scsTelemetry.SpecialEventsValues.Refuel) { refuel = scsTelemetry.SpecialEventsValues.Refuel; if (scsTelemetry.SpecialEventsValues.Refuel) { RefuelStart?.Invoke(this, new EventArgs()); } else { RefuelEnd?.Invoke(this, new EventArgs()); } } if (refuelPayed != scsTelemetry.SpecialEventsValues.RefuelPaid) { refuelPayed = scsTelemetry.SpecialEventsValues.RefuelPaid; if (scsTelemetry.SpecialEventsValues.RefuelPaid) { RefuelPaid?.Invoke(this, new EventArgs()); } } // currently the design is that the event is called, doesn't matter if data changed // also the old demo didn't used the flag and expected to be refreshed each call // so without making a big change also call the event without update with false flag if (!updated) { Data?.Invoke(scsTelemetry, false); } }
static void OnJobStarted(IJob job) { JobStarted?.Invoke(job); }
private void _updateTimer_Elapsed(object sender) { var scsTelemetry = SharedMemory.Update <SCSTelemetry>(); // check if sdk is NOT running if (!scsTelemetry.SdkActive && !paused) { // if so don't check so often the data var tsInterval = new TimeSpan(0, 0, 0, 0, DefaultPausedUpdateInterval); _updateTimer.Change(tsInterval.Add(tsInterval), tsInterval); paused = true; // if sdk not active we don't need to do something return; } if (paused && scsTelemetry.SdkActive) { // ok sdk is active now paused = false; resume(); // going back to normal update rate } var time = scsTelemetry.Timestamp; Data?.Invoke(scsTelemetry, time != lastTime); //TODO: make it nicer thats a lot of code for such less work // Job start event if (wasOnJob != scsTelemetry.SpecialEventsValues.OnJob) { wasOnJob = scsTelemetry.SpecialEventsValues.OnJob; if (scsTelemetry.SpecialEventsValues.OnJob) { JobStarted?.Invoke(this, new EventArgs()); } } if (cancelled != scsTelemetry.SpecialEventsValues.JobCancelled) { cancelled = scsTelemetry.SpecialEventsValues.JobCancelled; if (scsTelemetry.SpecialEventsValues.JobCancelled) { JobCancelled?.Invoke(this, new EventArgs()); } } if (delivered != scsTelemetry.SpecialEventsValues.JobDelivered) { delivered = scsTelemetry.SpecialEventsValues.JobDelivered; if (scsTelemetry.SpecialEventsValues.JobDelivered) { JobDelivered?.Invoke(this, new EventArgs()); } } if (fined != scsTelemetry.SpecialEventsValues.Fined) { fined = scsTelemetry.SpecialEventsValues.Fined; if (scsTelemetry.SpecialEventsValues.Fined) { Fined?.Invoke(this, new EventArgs()); } } if (tollgate != scsTelemetry.SpecialEventsValues.Tollgate) { tollgate = scsTelemetry.SpecialEventsValues.Tollgate; if (scsTelemetry.SpecialEventsValues.Tollgate) { Tollgate?.Invoke(this, new EventArgs()); } } if (ferry != scsTelemetry.SpecialEventsValues.Ferry) { ferry = scsTelemetry.SpecialEventsValues.Ferry; if (scsTelemetry.SpecialEventsValues.Ferry) { Ferry?.Invoke(this, new EventArgs()); } } if (train != scsTelemetry.SpecialEventsValues.Train) { train = scsTelemetry.SpecialEventsValues.Train; if (scsTelemetry.SpecialEventsValues.Train) { Train?.Invoke(this, new EventArgs()); } } if (refuel != scsTelemetry.SpecialEventsValues.Refuel) { refuel = scsTelemetry.SpecialEventsValues.Refuel; if (scsTelemetry.SpecialEventsValues.Refuel) { Refuel?.Invoke(this, new EventArgs()); } } lastTime = time; }
protected virtual void OnJobStarted(JobStartedEventArgs <CachedLog> e) { JobStarted?.Invoke(this, e); }
public async Task RunArea(int x1, int y1, int x2, int y2, Municipality m) { cancellationSource = new CancellationTokenSource(); jobs = new ObservableCollection <Job>(); Dictionary <TileId, Tile> tiles = new Dictionary <TileId, Tile>(); for (int x = x1; x <= x2; x++) { for (int y = y1; y <= y2; y++) { TileId id = new TileId(x, y); if (repository.Municipalities.map[id] != m.Id) { continue; } if (repository.Tiles.ContainsKey(id)) { tiles[id] = repository.Tiles[id]; } else { var tile = repository.GenerateTile(id); tiles[id] = repository.Tiles[id] = tile; } repository.UpdateTile(tiles[id]); } } waitingQueue = new BufferBlock <Tile>(new DataflowBlockOptions() { EnsureOrdered = true }); workerBlock = new TransformBlock <Tile, Tile>(async t => { t.Rescan(repository.DirectoryForTile(t.Id)); var job = Job.NextJob(t); if (job == null) { return(t); } JobStarted.Invoke(this, job); await job.Run(cancellationSource.Token, Cleanup); t.Rescan(repository.DirectoryForTile(t.Id)); JobFinished.Invoke(this, job); byte[] csvLine = job.CsvBytes; repository.logFile.Write(csvLine, 0, csvLine.Length); repository.logFile.Flush(); return(t); }, new ExecutionDataflowBlockOptions() { CancellationToken = cancellationSource.Token, MaxDegreeOfParallelism = workers, }); //ActionBlock<Tile> mapUpdater = new ActionBlock<Tile>(t => repository.UpdateTile(t)); TaskCompletionSource <int> finishTask = new TaskCompletionSource <int>(); int finishedCounter = tiles.Count; ActionBlock <Tile> tileFinished = new ActionBlock <Tile>(t => { finishedCounter--; if (finishedCounter == 0) { finishTask.SetResult(finishedCounter); } }); waitingQueue.LinkTo(workerBlock); link = workerBlock.LinkTo(waitingQueue, t => Job.NextJob(t) != null); workerBlock.LinkTo(tileFinished, t => Job.NextJob(t) == null); //workerBlock.LinkTo(mapUpdater); foreach (var pair in tiles) { await waitingQueue.SendAsync(pair.Value); } await finishTask.Task; }
public void Started(AgentConfig agent) { state = BuildState.Running; JobStarted?.Invoke(this, new JobStartedEventArgs(agent)); }
private void OnJobStarted(JobStartedEventArgs eventArgs) => JobStarted?.Invoke(this, eventArgs);
protected void OnJobStarted() { JobStarted?.Invoke(this, new WorkStateEventArgs(CurrentWorkState)); }
private static void OnJobStarted(AsyncJob args) { JobStarted?.Invoke(JobStarted, args); }
public WorkflowResult Execute() { //A given instance of this class should only be executable one time since we hold //on to processing and error state at the end of the run. //We're not expecting this class to be used in a multi-threaded situation, but //just the same, it's easy to prevent that unintended usage, so we'll do so here. lock (_syncObject) { if (Complete || Executed) { throw new InvalidOperationException("The process may only be executed once."); } Executed = true; } JobStarted?.Invoke(); var rollback = false; for (var i = 0; i < _steps.Count; ++i) { CurrentStep = i; var step = _steps[i]; try { RunStep(step); _lastStepCompleted = i; } catch (Exception e) { ActionException = e; Error = true; ErrorMessage = step.GetFormattedFailureMessage(e); _logger.Error($"{WorkflowName} - {ErrorMessage}"); rollback = true; break; } } if (rollback) { Rollback(); } Complete = true; JobCompleted?.Invoke(); return(new WorkflowResult { Error = Error, ActionException = ActionException, ErrorDuringRollback = ErrorDuringRollback, ErrorMessage = ErrorMessage, RollbackErrorMessage = RollbackErrorMessage, RollbackException = RollbackException, TotalSteps = TotalSteps, StepsCompletedSuccessfully = StepsCompletedSuccessfully, StepsRolledBack = StepsRolledBack }); }