protected void ImporterLoop()
 {
     while (!IsSuspended)
     {
         // We handle three cases here:
         // 1) Job available - process job and continue
         // 2) No job available - sleep until a job is available or we are suspended
         // 3) Job cannot be processed - exit loop and suspend
         ImportJob job;
         while ((job = PeekImportJob()) != null)
         {
             Process(job);
             ImportJobState state = job.State;
             if (state == ImportJobState.Finished || state == ImportJobState.Erroneous || state == ImportJobState.Cancelled)
             {
                 RemoveImportJob(job); // Maybe the queue was changed (cleared & filled again), so a simple call to Dequeue() could dequeue the wrong job
             }
             if (IsSuspended)
             {
                 break;
             }
         }
         if (!IsImportJobAvailable)
         {
             WaitHandle.WaitAny(new WaitHandle[] { _importJobsReadyAvailableEvent, _suspendedEvent });
         }
     }
 }
 protected void CheckImportStillRunning(ImportJobState state)
 {
     CheckSuspended(null);
     if (state == ImportJobState.Cancelled || state == ImportJobState.Erroneous)
     {
         throw new ImportAbortException();
     }
 }
 public ImportJobInformation(ImportJobInformation other)
 {
     _jobType               = other.JobType;
     _basePath              = other.BasePath;
     _metadataExtractorIds  = new HashSet <Guid>(other.MetadataExtractorIds);
     _includeSubDirectories = other.IncludeSubDirectories;
     _state = other.State;
 }
 public ImportJobInformation(ImportJobType jobType, ResourcePath basePath, IEnumerable <Guid> metadataExtractorIds, bool includeSubDirectories)
 {
     _jobType               = jobType;
     _basePath              = basePath;
     _metadataExtractorIds  = new HashSet <Guid>(metadataExtractorIds);
     _includeSubDirectories = includeSubDirectories;
     _state = ImportJobState.None;
 }
 public ImportJobInformation(ImportJobType jobType, ResourcePath basePath, IEnumerable<Guid> metadataExtractorIds, bool includeSubDirectories)
 {
   _jobType = jobType;
   _basePath = basePath;
   _metadataExtractorIds = new HashSet<Guid>(metadataExtractorIds);
   _includeSubDirectories = includeSubDirectories;
   _state = ImportJobState.None;
 }
        /// <summary>
        /// Executes the given <paramref name="importJob"/>.
        /// </summary>
        /// <remarks>
        /// This method automatically terminates if it encounters that this importer worker was suspended or that the
        /// given <paramref name="importJob"/> was cancelled.
        /// </remarks>
        /// <param name="importJob">Import job to be executed. The state variables of this parameter will be updated by
        /// this method.</param>
        protected void Process(ImportJob importJob)
        {
            ImportJobState state = importJob.State;

            if (state == ImportJobState.Finished || state == ImportJobState.Cancelled || state == ImportJobState.Erroneous)
            {
                return;
            }

            // Preparation
            IMediaAccessor       mediaAccessor = ServiceRegistration.Get <IMediaAccessor>();
            IImportResultHandler resultHandler;
            IMediaBrowsing       mediaBrowsing;

            lock (_syncObj)
            {
                resultHandler = _importResultHandler;
                mediaBrowsing = _mediaBrowsingCallback;
            }
            if (mediaBrowsing == null || resultHandler == null)
            {
                // Can be the case if this importer worker was asynchronously suspended
                return;
            }
            try
            {
                try
                {
                    ICollection <IMetadataExtractor> metadataExtractors = new List <IMetadataExtractor>();
                    foreach (Guid metadataExtractorId in importJob.MetadataExtractorIds)
                    {
                        IMetadataExtractor extractor;
                        if (!mediaAccessor.LocalMetadataExtractors.TryGetValue(metadataExtractorId, out extractor))
                        {
                            continue;
                        }
                        metadataExtractors.Add(extractor);
                    }

                    // Prepare import
                    if (state == ImportJobState.Scheduled)
                    {
                        ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Starting import job '{0}'", importJob);
                        ImporterWorkerMessaging.SendImportMessage(ImporterWorkerMessaging.MessageType.ImportStarted, importJob.BasePath);
                        IResourceAccessor ra;
                        if (!importJob.BasePath.TryCreateLocalResourceAccessor(out ra))
                        {
                            throw new ArgumentException(string.Format("Unable to access resource path '{0}'", importJob.BasePath));
                        }
                        using (ra)
                        {
                            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;
                            if (fsra != null)
                            { // Prepare complex import process
                                importJob.PendingResources.Add(new PendingImportResource(Guid.Empty, (IFileSystemResourceAccessor)fsra.Clone()));
                                importJob.State = ImportJobState.Active;
                            }
                            else
                            { // Simple resource import
                                ImportSingleFile(importJob, ra, metadataExtractors, mediaBrowsing, resultHandler, mediaAccessor);
                                lock (importJob.SyncObj)
                                    if (importJob.State == ImportJobState.Active)
                                    {
                                        importJob.State = ImportJobState.Finished;
                                    }
                                return;
                            }
                        }
                    }
                    else
                    {
                        ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Resuming import job '{0}' ({1} items pending)", importJob, importJob.PendingResources.Count);
                    }

                    // Actual import process
                    while (importJob.HasPendingResources)
                    {
                        Thread.Sleep(0);
                        CheckImportStillRunning(importJob.State);
                        PendingImportResource pendingImportResource;
                        lock (importJob.SyncObj)
                            pendingImportResource = importJob.PendingResources.FirstOrDefault();
                        if (pendingImportResource.IsValid)
                        {
                            IFileSystemResourceAccessor fsra = pendingImportResource.ResourceAccessor;
                            int    numPending    = importJob.PendingResources.Count;
                            string moreResources = numPending > 1 ? string.Format(" ({0} more resources pending)", numPending) : string.Empty;
                            ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Importing '{0}'{1}", fsra.ResourcePathName, moreResources);
                            if (fsra.IsFile && fsra.Exists)
                            {
                                ImportResource(importJob, fsra, pendingImportResource.ParentDirectory, metadataExtractors, resultHandler, mediaAccessor);
                            }
                            else if (!fsra.IsFile)
                            {
                                CheckImportStillRunning(importJob.State);
                                Guid?currentDirectoryId = ImportDirectory(importJob, pendingImportResource.ParentDirectory, fsra, metadataExtractors,
                                                                          mediaBrowsing, resultHandler, mediaAccessor);
                                CheckImportStillRunning(importJob.State);
                                if (currentDirectoryId.HasValue && importJob.IncludeSubDirectories)
                                {
                                    // Add subdirectories in front of work queue
                                    lock (importJob.SyncObj)
                                    {
                                        ICollection <IFileSystemResourceAccessor> directories = FileSystemResourceNavigator.GetChildDirectories(fsra, false);
                                        if (directories != null)
                                        {
                                            foreach (IFileSystemResourceAccessor childDirectory in directories)
                                            {
                                                importJob.PendingResources.Insert(0, new PendingImportResource(currentDirectoryId.Value, childDirectory));
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                ServiceRegistration.Get <ILogger>().Warn("ImporterWorker: Cannot import resource '{0}': It's neither a file nor a directory", fsra.CanonicalLocalResourcePath.Serialize());
                            }
                        }
                        lock (importJob.SyncObj)
                            importJob.PendingResources.Remove(pendingImportResource);
                        pendingImportResource.Dispose();
                    }
                    lock (importJob.SyncObj)
                        if (importJob.State == ImportJobState.Active)
                        {
                            importJob.State = ImportJobState.Finished;
                        }
                    ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Finished import job '{0}'", importJob);
                    ImporterWorkerMessaging.SendImportMessage(ImporterWorkerMessaging.MessageType.ImportCompleted, importJob.BasePath);
                }
                catch (Exception e)
                {
                    CheckSuspended(e); // Throw ImportAbortException if suspended - will skip warning and tagging job as erroneous
                    ServiceRegistration.Get <ILogger>().Warn("ImporterWorker: Problem processing '{0}'", e, importJob);
                    ImporterWorkerMessaging.SendImportMessage(ImporterWorkerMessaging.MessageType.ImportCompleted, importJob.BasePath);
                    importJob.State = ImportJobState.Erroneous;
                }
            }
            catch (ImportSuspendedException)
            {
                ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Suspending import job '{0}' ({1} items pending - will be continued next time)", importJob, importJob.PendingResources.Count);
            }
            catch (ImportAbortException)
            {
                ServiceRegistration.Get <ILogger>().Info("ImporterWorker: Aborting import job '{0}' ({1} items pending)", importJob, importJob.PendingResources.Count);
            }
        }
Example #7
0
 protected void CheckImportStillRunning(ImportJobState state)
 {
   CheckSuspended(null);
   if (state == ImportJobState.Cancelled || state == ImportJobState.Erroneous)
     throw new ImportAbortException();
 }
 public ImportJobInformation(ImportJobInformation other)
 {
   _jobType = other.JobType;
   _basePath = other.BasePath;
   _metadataExtractorIds = new HashSet<Guid>(other.MetadataExtractorIds);
   _includeSubDirectories = other.IncludeSubDirectories;
   _state = other.State;
 }