private async void ProcessJobs(CancellationToken cancellationToken) { var consumerTask = Task.Run(() => ConsumeJobs(cancellationToken), cancellationToken); var jobsLastAddedById = new List <int>(); while (!cancellationToken.IsCancellationRequested) { Thread.Sleep(this.pollPeriodInMilliseconds); var newJobs = dispatcher.Dispatch(BackgroundJobActions.GetAllJobs(includeCompleted: false)) .Where(j => !jobQueue.Select(qj => qj.Id).Contains(j.Id)) .Where(j => !jobsLastAddedById.Contains(j.Id)) .OrderBy(j => j.Id); if (newJobs.Any()) { jobsLastAddedById = new List <int>(); } foreach (var job in newJobs) { jobsLastAddedById.Add(job.Id); jobQueue.Add(job); } } await consumerTask; }
private void ConsumeJobs(CancellationToken cancellationToken) { while (!cancellationToken.IsCancellationRequested) { var job = jobQueue.Take(); while (true) { var retryPeriodInMilliseconds = 5000; try { dispatcher.Dispatch(BackgroundJobActions.MarkAsProcessing(job.Id)); // Check if the job is now obsolete (because a newer version of the project device exists) var jobProjectDeviceVersion = dispatcher.Dispatch(ProjectDeviceActions.GetProjectDeviceVersion(job.ProjectDeviceVersionId)); var projectDeviceVersions = dispatcher.Dispatch(ProjectDeviceActions.GetProjectDeviceVersionsForProjectDevice(jobProjectDeviceVersion.ProjectDeviceId)); if (projectDeviceVersions.Select(pdv => pdv.Version).Max() > jobProjectDeviceVersion.Version) { dispatcher.Dispatch(BackgroundJobActions.MarkAsCancelled(job.Id, "A newer version of the project device now exists")); break; } piSyncService.ProcessProjectDeviceVersion(job); dispatcher.Dispatch(BackgroundJobActions.MarkAsComplete(job.Id)); break; } catch (Exception ex) { dispatcher.Dispatch(BackgroundJobActions.MarkAsErrored(job.Id, ex.Message, ex.StackTrace)); if (cancellationToken.IsCancellationRequested) { break; } cancellationToken.WaitHandle.WaitOne(retryPeriodInMilliseconds); } } } }
public void ProcessProjectDeviceVersion(BackgroundJob job) { var projectDeviceVersion = dispatcher.Dispatch(ProjectDeviceActions.GetProjectDeviceVersion(job.ProjectDeviceVersionId)); Guard.This(projectDeviceVersion).AgainstDefaultValue(string.Format("Could not find project device version '{0}'", job.ProjectDeviceVersionId)); var device = dispatcher.Dispatch(DeviceActions.GetProjectDevice(projectDeviceVersion.ProjectDeviceId)); Guard.This(device).AgainstDefaultValue(string.Format("Could not find project device with project device Id '{0}'", projectDeviceVersion.ProjectDeviceId)); Guard.This(device).WithRule(d => deviceStatusService.IsOnline(device), string.Format("Device {0} (with IP Address {1}) is not online", device.Name, device.IpAddress)); var project = dispatcher.Dispatch(ProjectActions.GetProjectFromProjectDevice(projectDeviceVersion.ProjectDeviceId)); Guard.This(project).AgainstDefaultValue(string.Format("Could not find project from project device with id '{0}'", projectDeviceVersion.ProjectDeviceId)); var video = dispatcher.Dispatch(VideoActions.GetVideoForProject(project.Id)); Guard.This(video).AgainstDefaultValue(string.Format("Could not find video for project '{0}'", project.Name)); using (var videoProcessor = videoProcessorInstantiator()) { var videoMetadata = videoProcessor.StartReadingVideo(project.Id, projectDeviceVersion.ProjectDeviceId); var client = piClientFactory.ForDevice(device); // Update video metadata (use project device id instead of video id with client (could have the same video in multiple configurations) var existingVideosOnPi = client.GetAllVideoMetadata(); var existingVideoOnPi = existingVideosOnPi.SingleOrDefault(v => v.Id == projectDeviceVersion.ProjectDeviceId); if (existingVideoOnPi == null) { client.CreateVideoMetadata(new VideoMetadataCreateRequest { Id = projectDeviceVersion.ProjectDeviceId, FileName = video.FilePath, FrameRate = videoMetadata.FrameRate }); } else { client.UpdateVideoMetadata(new VideoMetadataPutRequest { Id = projectDeviceVersion.ProjectDeviceId, FileName = video.FilePath, FrameRate = videoMetadata.FrameRate, }); } // Clear, then send frames to Pi client.ClearFrames(projectDeviceVersion.ProjectDeviceId); int framePosition = 1; while (true) { var read = videoProcessor.ReadNext1000Frames(); client.SendFrames(projectDeviceVersion.ProjectDeviceId, new AppendFramesRequest { AppendFrameRequests = read.Frames .Select(f => new AppendFrameRequest { BinaryData = f, Position = framePosition }) .ToArray() }); dispatcher.Dispatch(BackgroundJobActions.MarkPercentageCompletion(job.Id, read.PercentageComplete)); if (!read.MoreFrames) { break; } framePosition++; } } }
public GlobalJsonResult <IEnumerable <BackgroundJob> > GetAllJobsForProject(int projectId, bool includeCompleted = false) { var result = dispatcher.Dispatch(BackgroundJobActions.GetAllJobsForPoject(projectId, includeCompleted)); return(GlobalJsonResult <IEnumerable <BackgroundJob> > .Success(System.Net.HttpStatusCode.OK, result)); }