예제 #1
0
        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;
        }
예제 #2
0
        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);
                    }
                }
            }
        }
예제 #3
0
        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++;
                }
            }
        }
예제 #4
0
        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));
        }