/// <inheritdoc />
        public void Start(CancellationToken token)
        {
            // check that the file does exists.
            if (!File.Exists(_config.Source))
            {
                try
                {
                    SQLiteConnection.CreateFile(_config.Source);
                }
                catch (Exception ex)
                {
                    _logger.Exception(ex);
                    throw new FileNotFoundException();
                }
            }

            // the connection string
            var connectionString = $"Data Source={_config.Source};Version=3;Pooling=True;Max Pool Size=100;";

            // the readonly.
            _connectionReadOnly = new SQLiteConnection($"{connectionString}Read Only=True;");
            _connectionReadOnly.Open();

            // create the connection spinner and pass the function to create transactions.
            _transactionSpinner = new TransactionsManager(_performance, _logger);

            // initiialise everything
            Initialise(token).GetAwaiter().GetResult();
        }
예제 #2
0
        /// <summary>
        /// Given a list of words, re-create the ones that we need to insert.
        /// </summary>
        /// <param name="words"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        private async Task <IList <long> > InsertWordsAsync(
            interfaces.IO.IWords words,
            CancellationToken token)
        {
            // if we have nothing to do... we are done.
            if (!words.Any())
            {
                return(new List <long>());
            }

            // the ids of the words we just added
            var ids = new List <long>(words.Count);

            try
            {
                foreach (var word in words)
                {
                    // get out if needed.
                    token.ThrowIfCancellationRequested();

                    // if the word is not valid, there isn't much we can do.
                    if (!IsValidWord(word))
                    {
                        continue;
                    }

                    // the word we want to insert.
                    var wordId = await InsertWordAsync(word, token).ConfigureAwait(false);

                    if (-1 == wordId)
                    {
                        // we log errors in the insert function
                        continue;
                    }

                    // we added this id.
                    ids.Add(wordId);
                }

                // all done, return whatever we did.
                return(ids);
            }
            catch (OperationCanceledException)
            {
                _logger.Warning("Received cancellation request - Insert multiple words");
                throw;
            }
            catch (Exception ex)
            {
                _logger.Exception(ex);
                throw;
            }
        }
예제 #3
0
        /// <inheritdoc />
        public async Task <long> WorkAsync(CancellationToken token)
        {
            // check if we are active at the current time.
            if (!_active.IsActive())
            {
                // we are not active ... so we have nothing to do.
                _logger.Verbose("Maintenance Process ignored, out of active hours.");
                return(0);
            }

            var stopwatch = new Stopwatch();

            stopwatch.Start();
            var success = false;

            try
            {
                _logger.Information("Started Maintenance Process.");
                await _persister.MaintenanceAsync(token).ConfigureAwait(false);

                await _parser.MaintenanceAsync(token).ConfigureAwait(false);

                // it worked
                success = true;
            }
            catch (OperationCanceledException)
            {
                // nothing to log
                throw;
            }
            catch (Exception e)
            {
                _logger.Exception("Error while processing Maintenance.", e);
                throw;
            }
            finally
            {
                _logger.Information(success
          ? $"Complete Maintenance Process (Time Elapsed: {stopwatch.Elapsed:g})."
          : $"Complete Maintenance Process with errors (Time Elapsed: {stopwatch.Elapsed:g}).");
            }
            return(0);
        }
예제 #4
0
        /// <inheritdoc />
        public async Task MaintenanceAsync(CancellationToken token)
        {
            lock (_taskLock)
            {
                // are we still running the start?
                if (!_runningTask?.IsCompleted ?? true)
                {
                    return;
                }
            }

            var factory = await _persister.BeginWrite(token).ConfigureAwait(false);

            try
            {
                const string configParse = "maintenance.parse";
                var          lastParse   = await _persister.Config.GetConfigValueAsync(configParse, DateTime.MinValue, factory, token).ConfigureAwait(false);

                // between 3 and 5 hours to prevent running at the same time as others.
                var randomHours = (new Random(DateTime.UtcNow.Millisecond)).Next(3, 5);
                if ((DateTime.UtcNow - lastParse).TotalHours > randomHours)
                {
                    //
                    //  Do maintenance work
                    //
                    _logger.Information("Maintenance files/folders parser");

                    // save the date and commit ... because the parser needs its own factory.
                    await _persister.Config.SetConfigValueAsync(configParse, DateTime.UtcNow, factory, token).ConfigureAwait(false);
                }
                _persister.Commit(factory);
            }
            catch (Exception e)
            {
                _persister.Rollback(factory);
                _logger.Exception("There was an exception re-parsing the directories.", e);
                throw;
            }
        }