Exemplo n.º 1
0
        public async Task <bool> BatchRun(BatchJob opts, CancellationToken cancellationToken = default)
        {
            m_UserLogger.WriteLine($"Batch macro running started");

            var batchStartTime = DateTime.Now;

            var allFiles = PrepareJobScope(opts.Input, opts.Filters, opts.Macros).ToArray();

            m_UserLogger.WriteLine($"Running batch processing for {allFiles.Length} file(s)");

            m_ProgressHandler.SetJobScope(allFiles, batchStartTime);

            if (!allFiles.Any())
            {
                throw new UserMessageException("Empty job. No files matching specified filter");
            }

            TimeSpan timeout = default;

            if (opts.Timeout > 0)
            {
                timeout = TimeSpan.FromSeconds(opts.Timeout);
            }

            IXApplication app    = null;
            Process       appPrc = null;

            if (cancellationToken != default)
            {
                cancellationToken.Register(() =>
                {
                    m_UserLogger.WriteLine($"Cancelled by the user");
                    TryShutDownApplication(appPrc);
                });
            }

            var jobResult = false;

            try
            {
                await Task.Run(() =>
                {
                    var curBatchSize = 0;

                    for (int i = 0; i < allFiles.Length; i++)
                    {
                        var curAppPrc = appPrc?.Id;

                        var curFile = allFiles[i];
                        var res     = AttemptProcessFile(ref app, ref appPrc, curFile, opts, cancellationToken);
                        m_ProgressHandler?.ReportProgress(curFile, res);

                        if (!res && !opts.ContinueOnError)
                        {
                            throw new UserMessageException("Cancelling the job. Set 'Continue On Error' option to continue job if file failed");
                        }

                        if (appPrc?.Id != curAppPrc)
                        {
                            curBatchSize = 1;
                        }
                        else
                        {
                            curBatchSize++;
                        }

                        if (opts.BatchSize > 0 && curBatchSize >= opts.BatchSize && !cancellationToken.IsCancellationRequested)
                        {
                            m_UserLogger.WriteLine("Closing application as batch size reached the limit");
                            TryShutDownApplication(appPrc);
                            curBatchSize = 0;
                        }
                    }
                }).ConfigureAwait(false);

                jobResult = true;
            }
            finally
            {
                TryShutDownApplication(appPrc);
            }

            var duration = DateTime.Now.Subtract(batchStartTime);

            m_ProgressHandler.ReportCompleted(duration);

            m_UserLogger.WriteLine($"Batch running completed in {duration.ToString(@"hh\:mm\:ss")}");

            return(jobResult);
        }
Exemplo n.º 2
0
        private bool AttemptProcessFile(ref IXApplication app, ref Process appPrc,
                                        JobItemFile file, BatchJob opts, CancellationToken cancellationToken = default)
        {
            file.Status = JobItemStatus_e.InProgress;

            int curAttempt = 1;

            var macrosStack = new List <JobItemMacro>(file.Macros);

            TimeSpan?timeout = null;

            if (opts.Timeout > 0)
            {
                timeout = TimeSpan.FromSeconds(opts.Timeout);
            }

            while (curAttempt <= MAX_ATTEMPTS)
            {
                if (app == null || !IsAppAlive(app, appPrc) && !cancellationToken.IsCancellationRequested)
                {
                    TryShutDownApplication(appPrc);

                    var vers = m_AppProvider.ParseVersion(opts.VersionId);
                    app = AttemptStartApplication(vers, opts.StartupOptions, cancellationToken, timeout);

                    appPrc = app.Process;
                }

                IXDocument doc = null;
                CancellationTokenSource cancellationTokenSrc = null;

                CancellationToken timeoutCancellationToken = default;

                try
                {
                    if (timeout.HasValue)
                    {
                        cancellationTokenSrc     = new CancellationTokenSource(timeout.Value);
                        timeoutCancellationToken = cancellationTokenSrc.Token;

                        var thisAppPrc = appPrc;

                        timeoutCancellationToken.Register(() =>
                        {
                            TryShutDownApplication(thisAppPrc);
                        });
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw new JobCancelledException();
                    }

                    var fileProcessStartTime = DateTime.Now;
                    m_UserLogger.WriteLine($"Started processing file {file.FilePath}");

                    doc = app.Documents.FirstOrDefault(d => string.Equals(d.Path, file.FilePath));

                    var forbidSaving = false;

                    if (doc == null)
                    {
                        doc = app.Documents.PreCreate <IXDocument>();

                        doc.Path = file.FilePath;

                        var state = DocumentState_e.Default;

                        if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Silent))
                        {
                            state |= DocumentState_e.Silent;
                        }

                        if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.ReadOnly))
                        {
                            state |= DocumentState_e.ReadOnly;
                        }

                        if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Rapid))
                        {
                            state |= DocumentState_e.Rapid;
                        }

                        if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Invisible))
                        {
                            state |= DocumentState_e.Hidden;
                        }

                        if (opts.OpenFileOptions.HasFlag(OpenFileOptions_e.ForbidUpgrade))
                        {
                            if (app.Version.Compare(doc.Version) == VersionEquality_e.Newer)
                            {
                                forbidSaving = true;

                                if (!state.HasFlag(DocumentState_e.ReadOnly))
                                {
                                    m_UserLogger.WriteLine($"Setting the readonly flag to {file.FilePath} to prevent upgrade of the file");
                                    state |= DocumentState_e.ReadOnly;
                                }
                            }
                        }

                        doc.State = state;
                        doc.Commit(cancellationToken);
                    }

                    if (!opts.OpenFileOptions.HasFlag(OpenFileOptions_e.Invisible))
                    {
                        app.Documents.Active = doc;
                    }

                    AttempRunMacros(app, doc, macrosStack, opts.Actions, forbidSaving, cancellationToken);

                    if (file.Macros.All(m => m.Status == JobItemStatus_e.Succeeded))
                    {
                        file.Status = JobItemStatus_e.Succeeded;
                    }
                    else
                    {
                        file.Status = file.Macros.Any(m => m.Status == JobItemStatus_e.Succeeded) ? JobItemStatus_e.Warning : JobItemStatus_e.Failed;
                    }

                    m_UserLogger.WriteLine($"Processing file '{file.FilePath}' completed. Execution time {DateTime.Now.Subtract(fileProcessStartTime).ToString(@"hh\:mm\:ss")}");

                    return(file.Status != JobItemStatus_e.Failed);
                }
                catch (Exception ex)
                {
                    var errDesc = "";

                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw new JobCancelledException();
                    }

                    if (timeoutCancellationToken.IsCancellationRequested)
                    {
                        errDesc = "Timeout processing document";
                    }

                    else
                    {
                        if (ex is OpenDocumentFailedException)
                        {
                            errDesc = $"Failed to open document {file.FilePath}: {(ex as OpenDocumentFailedException).Message}";
                        }
                        else
                        {
                            errDesc = "Failed to process document";
                        }
                    }

                    m_UserLogger.WriteLine($"{errDesc}. Attempt: {curAttempt}");
                    curAttempt++;
                }
                finally
                {
                    cancellationTokenSrc?.Dispose();
                    TryCloseDocument(doc);
                }
            }

            file.Status = JobItemStatus_e.Failed;
            m_UserLogger.WriteLine($"Processing file '{file.FilePath}' failed");

            return(false);
        }