Beispiel #1
0
        public static QueueTask Peek(Database database, string queueName)
        {
            if (database == null)
            {
                throw new ArgumentNullException("database", "database is null.");
            }
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName", "queueName is null.");
            }

            Guid workflowId, taskId;
            var  queue = Queue.Get(database, queueName);

            queue.QueueLock.EnterReadLock();
            try
            {
                if (queue.QueuedTasks.Count == 0)
                {
                    return(null);
                }

                var first = queue.QueuedTasks.First.Value;
                workflowId = first.Item1;
                taskId     = first.Item2;
            }
            finally
            {
                queue.QueueLock.ExitReadLock();
            }

            database.WorkflowsLock.EnterReadLock();
            try
            {
                if (!database.Workflows.ContainsKey(workflowId))
                {
                    return(null);
                }
                var workflow = database.Workflows[workflowId];
                workflow.WorkflowLock.EnterReadLock();
                try
                {
                    return(new QueueTask()
                    {
                        WorkflowName = workflow.Name,
                        TaskName = workflow.Tasks[taskId].Name,
                    });
                }
                finally
                {
                    workflow.WorkflowLock.ExitReadLock();
                }
            }
            finally
            {
                database.WorkflowsLock.ExitReadLock();
            }
        }
Beispiel #2
0
        public static void Delete(Database database, string name)
        {
            if (database == null)
            {
                throw new ArgumentNullException("database", "database is null.");
            }
            if (name == null)
            {
                throw new ArgumentNullException("name", "name is null.");
            }
            if (!Queue.Exists(database, name))
            {
                throw new ArgumentException(string.Format("Queue with the name \"{0}\" not found.", name), "name");
            }
            if (!Queue.IsEmpty(database, name))
            {
                throw new InvalidOperationException(string.Format("Failed deleting queue with name \"{0}\", queue is not empty.", name));
            }

            var queue = Queue.Get(database, name);

            queue.QueueLock.EnterWriteLock();
            try
            {
                if (queue.QueuedTasks.Any())
                {
                    throw new InvalidOperationException(string.Format("Failed deleting queue with name \"{0}\", queue is not empty.", name));
                }

                database.QueuesLock.EnterWriteLock();
                try
                {
                    queue.QueuedTasks = null;
                    database.Queues.Remove(queue.Id);
                    database.QueueNames.Remove(queue.Name);
                }
                finally
                {
                    database.QueuesLock.ExitWriteLock();
                }
            }
            finally
            {
                queue.QueueLock.ExitWriteLock();
            }
        }
Beispiel #3
0
        public static QueueTask Dequeue(Database database, string queueName)
        {
            if (database == null)
            {
                throw new ArgumentNullException("database", "database is null.");
            }
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName", "queueName is null.");
            }

            if (Queue.IsEmpty(database, queueName))
            {
                return(null);
            }

            Workflow workflow;
            Task     task;
            Queue    queue;
            Guid     workflowId, taskId;

            for (int attemptNum = 0; attemptNum < MAX_DEQUEUE_ATTEMPTS; attemptNum++)
            {
                queue = Queue.Get(database, queueName);
                queue.QueueLock.EnterReadLock();
                try
                {
                    if (queue.QueuedTasks.Count == 0)
                    {
                        return(null);
                    }
                    var first = queue.QueuedTasks.First.Value;
                    workflowId = first.Item1;
                    taskId     = first.Item2;
                }
                finally
                {
                    queue.QueueLock.ExitReadLock();
                }

                workflow = Workflow.Get(database, workflowId);
                if (workflow == null)
                {
                    continue;
                }
                workflow.WorkflowLock.EnterReadLock();
                try
                {
                    task = workflow.Tasks[taskId];
                }
                finally
                {
                    workflow.WorkflowLock.ExitReadLock();
                }

                workflow.WorkflowLock.EnterWriteLock();
                try
                {
                    queue.QueueLock.EnterWriteLock();
                    try
                    {
                        // Validate state;
                        if (queue.QueuedTasks.Count == 0)
                        {
                            return(null);
                        }
                        if (queue.QueuedTasks.First().Item2 != taskId)
                        {
                            continue;
                        }
                        queue.QueuedTasks.RemoveFirst();
                        queue.RunningTasks.Add(taskId);
                        task.State = TaskState.Running;
                        return(new QueueTask()
                        {
                            WorkflowName = workflow.Name,
                            TaskName = task.Name,
                        });
                    }
                    finally
                    {
                        queue.QueueLock.ExitWriteLock();
                    }
                }
                finally
                {
                    workflow.WorkflowLock.ExitWriteLock();
                }
            }
            return(null);
        }
Beispiel #4
0
        public static void Create(Database database, string workflowName, string name, string queueName)
        {
            if (database == null)
            {
                throw new ArgumentNullException("database", "database is null.");
            }
            if (workflowName == null)
            {
                throw new ArgumentNullException("workflowName", "workflowName is null.");
            }
            if (name == null)
            {
                throw new ArgumentNullException("name", "name is null.");
            }
            if (queueName == null)
            {
                throw new ArgumentNullException("queueName", "queueName is null.");
            }

            Task task;
            var  workflow = Workflow.Get(database, workflowName);
            var  queue    = Queue.Get(database, queueName);

            queue.QueueLock.EnterReadLock();
            try
            {
                task = new Task(name, queue.Id);
            }
            finally
            {
                queue.QueueLock.ExitReadLock();
            }

            database.WorkflowsLock.EnterReadLock();
            try
            {
                if (!database.WorkflowNames.ContainsKey(workflowName))
                {
                    throw new Exception(string.Format("Workflow with the name \"{0}\" not found.", workflowName));
                }
                workflow = database.Workflows[database.WorkflowNames[workflowName]];
                if (workflow.Suspended)
                {
                    workflow.WorkflowLock.EnterUpgradeableReadLock();
                    try
                    {
                        workflow.Tasks.Add(task.Id, task);
                        workflow.TaskNames.Add(task.Name, task.Id);
                    }
                    finally
                    {
                        workflow.WorkflowLock.ExitUpgradeableReadLock();
                    }
                }
                else
                {
                    database.QueuesLock.EnterReadLock();
                    try
                    {
                        workflow.WorkflowLock.EnterUpgradeableReadLock();
                        try
                        {
                            queue.QueueLock.EnterWriteLock();
                            try
                            {
                                workflow.Tasks.Add(task.Id, task);
                                workflow.TaskNames.Add(task.Name, task.Id);
                                queue.QueuedTasks.AddLast(new LinkedListNode <Tuple <Guid, Guid> >(new Tuple <Guid, Guid>(workflow.Id, task.Id)));
                            }
                            finally
                            {
                                queue.QueueLock.ExitWriteLock();
                            }
                        }
                        finally
                        {
                            workflow.WorkflowLock.ExitUpgradeableReadLock();
                        }
                    }
                    finally
                    {
                        database.QueuesLock.ExitReadLock();
                    }
                }
            }
            finally
            {
                database.WorkflowsLock.ExitReadLock();
            }
        }
Beispiel #5
0
        public static void AddDependency(Database database, string workflowName, string nameDependantOn, string nameDependancyTo)
        {
            if (database == null)
            {
                throw new ArgumentNullException("database", "database is null.");
            }
            if (workflowName == null)
            {
                throw new ArgumentNullException("workflowName", "workflowName is null.");
            }
            if (nameDependantOn == null)
            {
                throw new ArgumentNullException("nameDependantOn", "nameDependantOn is null.");
            }
            if (workflowName == null)
            {
                throw new ArgumentNullException("nameDependancyTo", "nameDependancyTo is null.");
            }

            var workflow          = Workflow.Get(database, workflowName);
            var dependantOn       = Task.Get(database, workflowName, nameDependantOn);
            var dependancyTo      = Task.Get(database, workflowName, nameDependancyTo);
            var dependancyToQueue = Queue.Get(database, dependancyTo.QueueId);

            workflow.WorkflowLock.EnterWriteLock();
            try
            {
                switch (dependancyTo.State)
                {
                case TaskState.AwaitDependence:
                    break;

                case TaskState.Queued:
                    if (!workflow.Suspended)
                    {
                        dependancyToQueue.QueueLock.EnterWriteLock();
                        try
                        {
                            dependancyToQueue.QueuedTasks.Remove(dependancyToQueue.QueuedTasks.First(t => t.Item2 == dependancyTo.Id));
                        }
                        finally
                        {
                            dependancyToQueue.QueueLock.ExitWriteLock();
                        }
                    }
                    break;

                case TaskState.Running:
                case TaskState.Completed:
                case TaskState.Failed:
                default:
                    throw new InvalidOperationException("Can only add dependancy to a task which has not yet been started.");
                }

                dependancyTo.State = TaskState.AwaitDependence;
                dependantOn.DependencyTo.Add(dependancyTo.Id);
                dependancyTo.DependantOn.Add(dependantOn.Id);

                switch (dependantOn.State)
                {
                case TaskState.AwaitDependence:
                case TaskState.Queued:
                case TaskState.Running:
                    dependancyTo.OutstandingDependencies.Add(dependantOn.Id);
                    break;
                }
            }
            finally
            {
                workflow.WorkflowLock.ExitWriteLock();
            }
        }