예제 #1
0
        public bool EnqueueObject(QueueObjectAction obj)
        {
            #region Складываем задачу в память
            if (!obj.Action.IsHighLevelReliability)
            {
                ListQueueObjects.ListQueueActions.AddOrUpdate(obj, 0, Update);
                ChangeQueue();
                return(true);
            }
            #endregion Складываем задачу в базу
            #region Складываем задачу в базу
            lock (_lockDb)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_dbDsn))
                {
                    try
                    {
                        connection.Open();
                        string insSql = "INSERT INTO retro_queue (GUID, DT1970, OBJECT_XML, COUNT_ERROR) " +
                                        "VALUES (@GUID, @DT1970, @OBJECT_XML, @COUNT_ERROR)";
                        using (SQLiteCommand command = new SQLiteCommand(insSql, connection))
                        {
                            SQLiteParameter guid       = new SQLiteParameter("@GUID");
                            SQLiteParameter dt1970     = new SQLiteParameter("@DT1970");
                            SQLiteParameter objectXml  = new SQLiteParameter("@OBJECT_XML");
                            SQLiteParameter countError = new SQLiteParameter("@COUNT_ERROR");

                            guid.Value       = obj.Guid.ToString();
                            dt1970.Value     = obj.Dt1970;
                            objectXml.Value  = obj.Action.ToXml();
                            countError.Value = obj.CountError;

                            command.Parameters.Add(guid);
                            command.Parameters.Add(dt1970);
                            command.Parameters.Add(objectXml);
                            command.Parameters.Add(countError);

                            command.ExecuteNonQuery();
                        }
                        ChangeQueue();
                    }
                    catch (Exception e)
                    {
                        Log.Error(NameTh + "> ОШИБКА!!! Возникла ошибка при записи объекта в очередь!", e);
                        return(false);
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
            return(true);

            #endregion
        }
예제 #2
0
        /// <summary>
        /// Проверка валидности действия
        /// </summary>
        /// <param name="objectAction"></param>
        /// <returns></returns>
        public bool IsReceivedObject(QueueObjectAction objectAction)
        {
            TimeSpan timeLastError = DateTime.Now - objectAction.DateError;

            if (timeLastError.TotalMinutes < _minuteToReceiveError)
            {
                return(false);
            }

            if (objectAction.CountError > _configStorage.CountError)
            {
                _svcSignal.SendSignal(SysSignal.Define.ServiceFault);
                Log.Error("Превышено количество попыток выполнения задачи" + objectAction.Guid);
                _queueAction.DeleteRecord(objectAction);
                return(false);
            }
            return(true);
        }
예제 #3
0
        public void DeleteRecord(QueueObjectAction record)
        {
            #region Удаляем задачу из памяти
            if (!record.Action.IsHighLevelReliability)
            {
                int i = 0;
                ListQueueObjects.ListQueueActions.TryRemove(record, out i);
                return;
            }
            #endregion
            #region Удаляем задачу из базы
            lock (_lockDb)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_dbDsn))
                {
                    try
                    {
                        connection.Open();
                        string sql = "delete from retro_queue where GUID = @GUID";

                        using (SQLiteCommand command = new SQLiteCommand(sql, connection))
                        {
                            SQLiteParameter guid = new SQLiteParameter("@GUID")
                            {
                                Value = record.Guid.ToString()
                            };
                            command.Parameters.Add(guid);

                            command.ExecuteNonQuery();
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(NameTh + "> ОШИБКА!!! Возникла ошибка при удалении объекта из очереди! ID=" + record.Guid, e);
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }
            #endregion
        }
예제 #4
0
        public QueueObjectAction GetFirst()
        {
            List <QueueObjectAction> result = new List <QueueObjectAction>();
            Random r = new Random();

            if (ListQueueObjects.ListQueueActions != null && !ListQueueObjects.ListQueueActions.IsEmpty)
            {
                result.AddRange(ListQueueObjects.ListQueueActions.Keys);
            }

            lock (_lockDb)
            {
                using (SQLiteConnection connection = new SQLiteConnection(_dbDsn))
                {
                    try
                    {
                        connection.Open();
                        string sql = "select * from retro_queue";
                        using (SQLiteCommand command = new SQLiteCommand(sql, connection))
                        {
                            using (SQLiteDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    QueueObjectAction g = FillQueueAction(reader);
                                    result.Add(g);
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(NameTh + "> ОШИБКА!!! Возникла ошибка при получении объекта из очереди!", e);
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
            }

            if (result.Count == 0)
            {
                return(null);
            }
            List <QueueObjectAction> listQueue      = new List <QueueObjectAction>();
            List <QueueObjectAction> listErrorQueue = new List <QueueObjectAction>();

            foreach (var action in result)
            {
                if (action.DateError == new DateTime())
                {
                    listQueue.Add(action);
                }
                else
                {
                    listErrorQueue.Add(action);
                }
            }
            return(listQueue.Count > 0 ? listQueue[r.Next(0, listQueue.Count - 1)] : listErrorQueue[r.Next(0, listErrorQueue.Count - 1)]);
        }
예제 #5
0
        private int Update(QueueObjectAction arg1, int arg2)
        {
            Random r = new Random();

            return(r.Next(0, 100));
        }
예제 #6
0
        /// <summary>
        /// Удаляем выполненные действия
        /// </summary>
        /// <param name="objectAction"></param>
        private void RemoveActionRunning(QueueObjectAction objectAction)
        {
            int i;

            _listActionsRunning.TryRemove(objectAction.Guid, out i);
        }
예제 #7
0
        /// <summary>
        /// В очереди появилась задача - выполняем.
        /// Метод всегда запускается в отдельном потоке (new Thread(ReceiveRetroProcess)) - не изменять это!
        /// </summary>
        private void ReceiveRetroProcess()
        {
            QueueObjectAction objectAction = null;

            try
            {
                if (_queueAction == null || _queueAction.IsEmptyQueue())
                {
                    return;
                }
#if DEBUG
                Log.Info("По таймеру разбираем очередь ");
#endif

                objectAction = _queueAction.GetFirst();

                // Обрабатываем только новые действия
                if (objectAction == null || _listActionsRunning.ContainsKey(objectAction.Guid))
                {
                    return;
                }

                if (!IsReceivedObject(objectAction))
                {
                    Log.Info("Выполнение действия прервано " + objectAction.Action.GuidAction);
                    return;
                }

                _listActionsRunning[objectAction.Guid] = 0;

                DateTime dtNow = DateTime.Now;

                // Отложим время выполнения действия если задана соответствующая настройка
                if (objectAction.Action.RunTimeOffset > 0)
                {
                    Log.Info("Выполнение действия отложено " + objectAction.Action.GuidAction);
                    Thread.Sleep(TimeSpan.FromSeconds(objectAction.Action.RunTimeOffset));
                    Log.Info("Выполнение действия возобновлено " + objectAction.Action.GuidAction);
                }

                var dataRegistry = Registry.GetNewRegistry(_rsduDbConf.DSN, _rsduDbConf.Login, _rsduDbConf.Password);
                dataRegistry.SetAppName(_rsduDbConf.AppName);

                lock (dataRegistry.Locker)
                {
                    Log.Info("Количество задач в очереди до обработки " + _queueAction.Count());
                    _timerThread.Start();
                    var archives = new List <ParamData>();

                    // Получение кадра из бд
                    RetroKadr kadr = GetKadr(objectAction.Action.KadrId, dataRegistry);
                    if (kadr == null)
                    {
                        _timerThread.Stop();
                        RemoveActionRunning(objectAction);
                        return;
                    }

                    var conditionsDates = new List <QueryConditionsDates>();

                    // Расчет периода и запрос архивов
                    Dictionary <DateTime, DateTime> startFinish = new Dictionary <DateTime, DateTime>();
                    foreach (var queryCondition in objectAction.Action.QueryConditions)
                    {
                        DateTime start  = GetDateStart(queryCondition, dtNow);
                        DateTime finish = GetDateFinish(queryCondition.Interval, queryCondition.IntervalCount, start);

                        conditionsDates.Add(new QueryConditionsDates(queryCondition, start, finish));

                        List <ParamData> archive = GetDataArc(start, finish, kadr, dataRegistry);

                        if (archive != null)
                        {
                            archives.AddRange(archive);
                        }

                        startFinish.Add(start, finish);
                    }

                    IDataExporter dataExporter = new DataExporter(objectAction.Action, kadr, archives, conditionsDates);
                    Log.Info("Выполняется задача " + objectAction.Guid);
                    bool exported = dataExporter.Export(startFinish, dtNow);
                    Log.Info("Выполнена задача " + objectAction.Guid + " - " + exported);

                    if (exported)
                    {
                        _queueAction.DeleteRecord(objectAction);
                    }
                    else
                    {
                        _queueAction.DeleteRecord(objectAction);
                        objectAction.CountError = objectAction.CountError + 1;
                        _queueAction.EnqueueObject(objectAction);
                    }
                    _evGetRetro.Set();
                    _timerThread.Stop();
                    RemoveActionRunning(objectAction);
#if DEBUG
                    Log.Info("Количество задач в очереди после обработки " + _queueAction.Count());
#endif
                }
                dataRegistry = null;
            }
            catch (ThreadAbortException)
            {
                // При остановке сервиса все потоки грохаются с помощью Thread.Abort.
                // Предотвращаем появление исключения "Поток находился в процессе ожидания" из-за того,
                // что некоторые потоки находятся в приостановленном состоянии т.к. мы Thread.Sleep делаем
                Thread.ResetAbort();
            }
            catch (Exception ex)
            {
                Log.Error("Не удалось выполнить задачу из очереди", ex);

                if (objectAction != null)
                {
                    RemoveActionRunning(objectAction);
                }
            }
        }