예제 #1
0
        /// <summary>
        /// Get task that has been marked for cancellation.
        /// </summary>
        /// <param name="specification">The <see cref="TaskRequestSpecification"/> instance.</param>
        /// <param name="taskIds">List of tasks' identifiers that have been canceled.</param>
        /// <returns>True if there is at minimum one task that has been marked for cancel.</returns>
        public bool TryGetCancelTasks(TaskRequestSpecification specification, out List <Int64> taskIds)
        {
            const string selectStatement = "select [Id] from {0}.{1} where [QueueId] = {2} and [ServerId] = {3} and [State] = {4}";

            string sqlCommand = string.Format(selectStatement, sqlSettings.WiseQueueDefaultSchema, taskTableName, specification.QueueId, specification.ServerId, (int)TaskStates.Cancel);

            using (IDbConnection connection = connectionFactory.CreateConnection())
            {
                using (IDbCommand command = connectionFactory.CreateCommand(connection))
                {
                    command.CommandText = sqlCommand;
                    using (IDataReader rdr = command.ExecuteReader())
                    {
                        taskIds = new List <Int64>();
                        while (rdr.Read())
                        {
                            Int64 id = (Int64)rdr["Id"];
                            taskIds.Add(id);
                        }
                    }
                }
            }

            return(taskIds.Count > 0);
        }
예제 #2
0
        /// <summary>
        /// Get available task from the storage.
        /// </summary>
        /// <param name="specification">The <see cref="TaskRequestSpecification"/> instance.</param>
        /// <param name="taskModels">List of <see cref="WiseQueue.Core.Common.Models.Tasks.TaskStateModel"/> instances if it has been found</param>
        /// <returns>True if the list of TaskModel instances has been populated. Otherwise, false.</returns>
        public bool TryGetAvailableTask(TaskRequestSpecification specification, out List <TaskModel> taskModels)
        {
            if (specification == null)
            {
                throw new ArgumentNullException("specification");
            }

            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append("Declare @TempTable table ([Id] [bigint], ");
            stringBuilder.Append("[QueueId] [bigint], ");
            stringBuilder.Append("[ServerId] [bigint] NULL, ");
            stringBuilder.Append("[State] [smallint], ");
            stringBuilder.Append("[CompletedAt] [datetime] NULL, ");
            stringBuilder.Append("[ExecuteAt] [datetime] NOT NULL, ");
            stringBuilder.Append("[RepeatCrashCount] [int] NOT NULL, ");
            stringBuilder.Append("[InstanceType] [nvarchar](4000), ");
            stringBuilder.Append("[Method] [nvarchar](4000), ");
            stringBuilder.Append("[ParametersTypes] [nvarchar](4000), ");
            stringBuilder.AppendLine("[Arguments] [nvarchar](4000)); ");

            stringBuilder.AppendFormat("UPDATE TOP ({0}) {1}.{2} ", specification.MaxTasks, sqlSettings.WiseQueueDefaultSchema, taskTableName);
            stringBuilder.AppendFormat("SET State = {0}, ", (short)TaskStates.Pending);
            stringBuilder.AppendFormat("ServerId = {0} ", specification.ServerId);
            //stringBuilder.Append("RepeatCount = RepeatCount - 1 ");
            stringBuilder.Append("OUTPUT inserted.* INTO @TempTable ");
            stringBuilder.AppendFormat("Where (State = {0} ", (short)TaskStates.New);
            stringBuilder.AppendFormat("OR ( (State = {0} OR State = {1}) AND [ServerId] IS NULL)) ", (short)TaskStates.Pending, (short)TaskStates.Running);
            stringBuilder.AppendFormat("AND (QueueId = {0}) AND ([ExecuteAt] <= GETUTCDATE()) AND [RepeatCrashCount] > 0;", specification.QueueId);

            stringBuilder.AppendLine();
            stringBuilder.AppendLine("SELECT * FROM @TempTable");

            using (IDbConnection connection = connectionFactory.CreateConnection())
            {
                using (IDbTransaction transaction = connection.BeginTransaction(IsolationLevel.Serializable))
                {
                    using (IDbCommand command = connectionFactory.CreateCommand(connection, transaction))
                    {
                        command.CommandText = stringBuilder.ToString();
                        using (IDataReader rdr = command.ExecuteReader())
                        {
                            taskModels = new List <TaskModel>();
                            while (rdr.Read())
                            {
                                Int64      id        = (Int64)rdr["Id"];
                                Int64      queueId   = (Int64)rdr["QueueId"];
                                Int64      serverId  = (Int64)rdr["ServerId"];
                                TaskStates taskState = (TaskStates)(short)rdr["State"];

                                int repeatCrashCount = (int)rdr["RepeatCrashCount"];

                                string     typeDetails      = (string)rdr["InstanceType"];
                                string     methodDetails    = (string)rdr["Method"];
                                string     parameterDetails = (string)rdr["ParametersTypes"];
                                string     argumentDetails  = (string)rdr["Arguments"];
                                TaskEntity taskEntity       = new TaskEntity
                                {
                                    Id               = id,
                                    QueueId          = queueId,
                                    ServerId         = serverId,
                                    TaskState        = taskState,
                                    InstanceType     = typeDetails,
                                    Method           = methodDetails,
                                    ParametersTypes  = parameterDetails,
                                    Arguments        = argumentDetails,
                                    RepeatCrashCount = repeatCrashCount
                                };

                                TaskModel taskModel = taskConverter.Convert(taskEntity);
                                taskModels.Add(taskModel);
                            }
                        }
                    }
                    if (taskModels.Count > 0)
                    {
                        transaction.Commit();
                        return(true);
                    }
                }

                return(false);
            }
        }
예제 #3
0
        /// <summary>
        /// Occurs when object should do its action.
        /// </summary>
        public void Execute()
        {
            if (taskManagerState == TaskManagerState.ClientOnly)
            {
                logger.WriteDebug("The server has client algorithm only.");
                return;
            }

            logger.WriteDebug("Searching for new tasks in available queue...");

            IReadOnlyCollection <QueueModel> queues = queueManager.GetAvailableQueues();

            foreach (QueueModel queueModel in queues)
            {
                Int64 queueId  = queueModel.Id;
                Int64 serverId = serverManager.ServerId;
                TaskRequestSpecification specification = new TaskRequestSpecification(queueId, serverId, maxTasksPerQueue);
                List <TaskModel>         taskModels;

                bool isReceived = taskDataContext.TryGetAvailableTask(specification, out taskModels);

                if (isReceived)
                {
                    foreach (TaskModel taskModel in taskModels)
                    {
                        IRunningTask currentTask = null;
                        try
                        {
                            currentTask = taskBuilder.Build(taskModel);

                            lock (activeTasks)
                            {
                                activeTasks.Add(taskModel.Id, currentTask);
                            }

                            currentTask.OnCompletedEventHandler += OnCompletedEventHandler;
                            currentTask.Execute(); //TODO: Provide global Cancelation Token.

                            logger.WriteDebug("The task {0} has been received.", taskModel);
                        }
                        catch (Exception ex)
                        {
                            string msg = string.Format("There was an error during executing task: {0}.", taskModel);
                            logger.WriteError(ex, msg);
                            RestartTask(taskModel, msg, ex);
                        }
                    }
                }
                else
                {
                    logger.WriteDebug("There is no new task in the storage.");
                }

                List <Int64> taskIds;
                isReceived = taskDataContext.TryGetCancelTasks(queueId, serverId, out taskIds);
                if (isReceived)
                {
                    foreach (Int64 taskId in taskIds)
                    {
                        logger.WriteTrace("The task (id = {0}) has been marked for cancelation. Cancelling...", taskId);

                        IRunningTask runningTask;
                        lock (activeTasks)
                        {
                            if (activeTasks.ContainsKey(taskId) == false)
                            {
                                continue;
                            }
                            runningTask = activeTasks[taskId];
                        }

                        logger.WriteTrace("The task ({0}) is running. Cancelling...", taskId);
                        try
                        {
                            runningTask.Cancel();
                        }
                        catch (Exception ex)
                        {
                            //TODO: Decide what to do.
                            logger.WriteError("there was an exception during cancelation task.", ex);
                        }

                        logger.WriteTrace("The task has been marked for canceling.");
                    }
                }
                else
                {
                    logger.WriteDebug("There is no task for cancelation.");
                }
            }

            logger.WriteDebug("All tasks have been found if existed.");
        }