An implementation of a SQL based multi-access Queue that provides random acccess to requests so they can be retrived for long running tasks where both client and server can interact with each message for processing. Great for long running tasks or even light workflow scenarios.
Inheritance: IDisposable
コード例 #1
0
 /// <summary>
 /// Override this method to process your async  operation. Required for
 /// anything to happen when the message is processed. If the operation
 /// succeeds (no exception), OnExecuteComplete will
 /// be called. This method should throw an exception if the operation fails,
 /// so that OnExecuteFailed will be fired.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 protected virtual void OnExecuteStart(QueueMessageManager manager)
 {
     if (ExecuteStart != null)
     {
         ExecuteStart(manager);
     }
 }
コード例 #2
0
 /// <summary>
 /// Override this method to do any post processing that needs to happen
 /// after each async operation has successfully completed. Optional - use
 /// for things like logging or reporting on status.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 protected virtual void OnExecuteComplete(QueueMessageManager Message)
 {
     if (ExecuteComplete != null)
     {
         ExecuteComplete(Message);
     }
 }
コード例 #3
0
 /// <summary>
 /// Override this method to handle any errors that occured during processing
 /// of the async task. Optional - implement for logging or notifications.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 /// <param name="ex">
 /// Exeception that caused the operation to fail
 /// </param>
 protected virtual void OnExecuteFailed(QueueMessageManager manager, Exception ex)
 {
     if (ExecuteFailed != null)
     {
         ExecuteFailed(manager, ex);
     }
 }
コード例 #4
0
 /// <summary>
 /// Override this method to handle any errors that occured trying to receive
 /// the next message from the SQL table.
 ///
 /// Allows for error handling or logging in your own applications.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 /// <param name="ex">
 /// Exeception that caused the operation to fail
 /// </param>
 protected virtual void OnNextMessageFailed(QueueMessageManager manager, Exception ex)
 {
     if (NextMessageFailed != null)
     {
         NextMessageFailed(manager, ex);
     }
 }
コード例 #5
0
        // global instances that keep controller and windows service alive

        public void Start(QueueMessageManager manager = null)
        {
            if (manager == null)
                manager = new QueueMessageManagerSql();

            LogManager.Current.LogInfo("Start called");

            var config = QueueMessageManagerConfiguration.Current;

            Controller = new QueueController()
            {
                ConnectionString = config.ConnectionString,
                QueueName = config.QueueName,
                WaitInterval = config.WaitInterval,
                ThreadCount = config.ControllerThreads                
            };
            

            LogManager.Current.LogInfo("Controller created.");
            
            // asynchronously start the SignalR hub
            SignalR = WebApplication.Start<SignalRStartup>("http://*:8080/");

            // *** Spin up n Number of threads to process requests
            Controller.StartProcessingAsync();

            LogManager.Current.LogInfo(String.Format("QueueManager Controller Started with {0} threads.",
                                       Controller.ThreadCount));            

            // Set static instances so that these 'services' stick around
            GlobalService.Controller = Controller;
            GlobalService.Service = this;
        }
コード例 #6
0
        protected void OnError(QueueMessageManager manager, string message = null)
        {
            if (message == null)
                message = manager.ErrorMessage;

            // clear out the message
            // don't do this
            manager.CancelRequest(messageText: "Failed: " + message,autoSave: true);

            LogManager.Current.LogError(message);
            // send email
            //AppUtils.SendAdminEmail("MPWFQMM Failure", errorMessage);            
        }
コード例 #7
0
        protected override void ExecuteSteps(QueueMessageManager manager)
        {
            // show a started message
            Stopwatch watch = new Stopwatch();
            watch.Start();

            // store on a thread
            LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(STR_STARTTIME_KEY);
            Thread.SetData(threadData, watch);
            
            QueueMonitorServiceHub.WriteMessage(manager.Item);

            base.ExecuteSteps(manager);
        }
        /// <summary>
        /// Implement OnExecuteStart to run queued actions/operations.
        /// Call manager.CompleteRequest() or manager.CancelRequest() to
        /// complete queue items.
        /// 
        /// Below is a commented simple example
        /// </summary>
        /// <param name="manager"></param>
        //protected override void OnExecuteStart(QueueMessageManager manager)
        //{
        //    base.OnExecuteStart(manager);            
        //
        //    string action = manager.Item.Action;
        //    try
        //    {
        //        switch (action)
        //        {
        //            case "HelloWorld":
        //            {
        //                Thread.Sleep(2000);
        //                manager.CompleteRequest(messageText: queueItem.Message + " - NEW completed at " + DateTime.Now,
        //                    autoSave: true);
        //                break;
        //            }
        //            default:
        //            {
        //                manager.CancelRequest(messageText: "Failed: No matching action", autoSave: true);
        //                break;
        //            }
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        manager.CancelRequest(messageText: "Failed: " + ex.Message, autoSave: true);
        //    }
        //}

        protected override void OnExecuteComplete(QueueMessageManager manager)
        {
            base.OnExecuteComplete(manager);

            // Get Starting timestamp from TextInput
            int elapsed = 0;
            DateTime time = DateTime.UtcNow;
            if (DateTime.TryParse(manager.Item.TextInput, out time))
                elapsed = (int) DateTime.UtcNow.Subtract(time.ToUniversalTime()).TotalMilliseconds;

            // also send down a waiting message count
            int waitingMessages =  GetWaitingMessageCount(manager);

            WriteMessage(manager.Item, elapsed, waitingMessages);
        }
        protected override void OnExecuteFailed(QueueMessageManager manager, Exception ex)
        {
            base.OnExecuteFailed(manager, ex);

            //timestamp from text input
            int elapsed = 0;
            DateTime time = DateTime.UtcNow;
            if (DateTime.TryParse(manager.Item.TextInput, out time))
                elapsed = (int) DateTime.UtcNow.Subtract(time.ToUniversalTime()).TotalMilliseconds;

            var qm = manager.Item;
            int waitingMessages = GetWaitingMessageCount(manager);

            WriteMessage(qm, elapsed, waitingMessages);
        }
コード例 #10
0
        /// <summary>
        /// This is the 'handler' code that actually does processing work
        /// It merely calls into any events that are hooked up to the controller
        /// for these events:
        ///
        /// ExecuteStart
        /// ExecuteComplete
        /// ExecuteFailed
        /// </summary>
        /// <param name="manager">Instance of QueueMessageManager and it's Item property</param>
        protected virtual void ExecuteSteps(QueueMessageManager manager)
        {
            try
            {
                // Hook up start processing
                OnExecuteStart(manager);

                // Hookup end processing
                OnExecuteComplete(manager);
            }
            catch (Exception ex)
            {
                OnExecuteFailed(manager, ex);
            }

            MessagesProcessed++;
        }
        protected void OnError(QueueMessageManager manager, string message = null, Exception ex = null)
        {
            if (message == null)
                message = manager.ErrorMessage;

            manager.CancelRequest(messageText: "Queue Error: " + message);
            manager.Save();


            string details = null;
            if (ex != null)
                details = ex.Source + "\r\n" + ex.StackTrace;

            //LogManager.Current.LogError(message, details);
            // send email
            //AppUtils.SendAdminEmail("MPWFQMM Failure", errorMessage);            
        }
コード例 #12
0
        protected override void OnExecuteStart(QueueMessageManager manager)
        {
            base.OnExecuteStart(manager);            

            var queueItem = manager.Item;

            try
            {
                string action = queueItem.Action;

                if (!string.IsNullOrEmpty(action))
                {
                    //Initialize Anything
                    action = action.Trim();
                }

                switch (action)
                {
                    default:
                        // TODO: Remove for production                                                
                        Thread.Sleep( (int) (DateTime.Now.Ticks % 500));

                        // use this instead to ensure that messages get updated properly and consistently
                        // that is: All flags are set, date is always UTC date, etc.
                        //if (!manager.CancelRequest(messageText: "Unknown Action", autoSave: true))
                        if (!manager.CompleteRequest(messageText: "Processing complete.", autoSave: true))
                        {
                            // this is pointless - if this save fails
                            // it's likely the save you are doing in
                            // onError will also fail
                            OnError(manager);
                            return;
                        }
                        //manager.CompleteCancelRequest(messageText: "Invalid message action provided.");
                        break;
                }
            }
            catch (Exception ex)
            {
                OnError(manager,ex.GetBaseException().Message);
                return;
            }

        }
  int GetWaitingMessageCount(QueueMessageManager manager, int delay = 10)
 {
     return manager.GetWaitingQueueMessageCount(QueueName);
 }
 void Controller_ExecuteComplete(QueueMessageManager Message)
 {
     this.WriteEntry("Complete: " + Message.Item.Completed + "->" + Message.Item.Id +  " - " + Message.Item.Message);
 }
 void Controller_ExecuteStart(QueueMessageManager Message)
 {
     this.WriteEntry("Started: " + Message.Item.Started + "->" + Message.Item.Id);
 }
コード例 #16
0
 /// <summary>
 /// Message hook that's responsible for retrieving the next message.
 /// The base version pulls the next message for the given queue.
 /// You can override this method to conditionally override this
 /// behavior such as filter when and how messages are read.
 /// </summary>
 /// <param name="manager">A manager instance that can retrieve</param>
 /// <param name="queueName">The queue to check</param>
 /// <returns></returns>
 protected virtual QueueMessageItem OnGetNextQueueMessage(QueueMessageManager manager, string queueName)
 {
     return(manager.GetNextQueueMessage(queueName));
 }
コード例 #17
0
 /// <summary>
 /// Override this method to handle any errors that occured during processing
 /// of the async task. Optional - implement for logging or notifications.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 /// <param name="ex">
 /// Exeception that caused the operation to fail
 /// </param>
 protected virtual void OnExecuteFailed(QueueMessageManager manager, Exception ex)
 {
     if (ExecuteFailed != null)
         ExecuteFailed(manager, ex);
 }
コード例 #18
0
        /// <summary>
        /// This is where your processing happens
        /// </summary>
        /// <param name="manager"></param>
        private void controller_ExecuteStart(QueueMessageManager manager)
        {
            // get active queue item
            var item = manager.Item;

            // Typically perform tasks based on some Action/request
            if (item.Action == "PRINTIMAGE")
            {
                // recommend you offload processing
                //PrintImage(manager);                
            }
            else if (item.Action == "RESIZETHUMBNAIL")
            {
                //ResizeThumbnail(manager);
            }

            // just for kicks
           Interlocked.Increment(ref RequestCount);

            // every other request should throw exception, trigger ExecuteFailed            
            if (RequestCount % 2 == 0)
            {
                // Execption:
                object obj = null;
                obj.ToString();
            }

            // Complete request 
            manager.CompleteRequest(messageText: "Completed request " + DateTime.Now,
                                    autoSave: true);            
        }
 void Controller_ExecuteFailed(QueueMessageManager Message, Exception ex)
 {
     this.WriteEntry("Failed: " + Message.Item.Completed + "->" + Message.Item.Id +  " - "  + ex.Message);
 }
コード例 #20
0
 private void controller_ExecuteFailed(QueueMessageManager manager, Exception ex)
 {
     Console.WriteLine("Failed (on purpose): " + manager.Item.QueueName + " - " +  manager.Item.Id + " - " + ex.Message);
 }
コード例 #21
0
 /// <summary>
 /// Override this method to do any post processing that needs to happen
 /// after each async operation has successfully completed. Optional - use
 /// for things like logging or reporting on status.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 protected virtual void OnExecuteComplete(QueueMessageManager Message)
 {
     if (ExecuteComplete != null)
         ExecuteComplete(Message);
 }
コード例 #22
0
 protected override void OnExecuteFailed(QueueMessageManager manager, Exception ex)
 {
     var qm = manager.Item;
     WriteMessage(qm);
     base.OnExecuteFailed(manager, ex);
 }
コード例 #23
0
 /// <summary>
 /// Override this method to handle any errors that occured trying to receive 
 /// the next message from the SQL table.
 /// 
 /// Allows for error handling or logging in your own applications.
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 /// <param name="ex">
 /// Exeception that caused the operation to fail
 /// </param>
 protected virtual void OnNextMessageFailed(QueueMessageManager manager, Exception ex)
 {
     if (NextMessageFailed != null)
         NextMessageFailed(manager, ex);
 }
コード例 #24
0
 /// <summary>
 /// Override this method to process your async  operation. Required for
 /// anything to happen when the message is processed. If the operation 
 /// succeeds (no exception), OnExecuteComplete will
 /// be called. This method should throw an exception if the operation fails,
 /// so that OnExecuteFailed will be fired. 
 /// </summary>
 /// <param name="manager">
 /// QueueManager instance. Use its Item property to get access to the current method
 /// </param>
 protected virtual void OnExecuteStart(QueueMessageManager manager)
 {
     if (ExecuteStart != null)
         ExecuteStart(manager);
 }
コード例 #25
0
        /// <summary>
        /// This is the 'handler' code that actually does processing work 
        /// It merely calls into any events that are hooked up to the controller
        /// for these events:
        /// 
        /// ExecuteStart
        /// ExecuteComplete
        /// ExecuteFailed
        /// </summary>
        /// <param name="manager">Instance of QueueMessageManager and it's Item property</param>
        protected virtual void ExecuteSteps(QueueMessageManager manager)
        {
            try
            {
                // Hook up start processing
                OnExecuteStart(manager);

                // Hookup end processing
                OnExecuteComplete(manager);
            }
            catch (Exception ex)
            {
                OnExecuteFailed(manager, ex);
            }

            MessagesProcessed++;
        }
コード例 #26
0
        private void controller_ExecuteComplete(QueueMessageManager manager)
        {
            // grab the active queue item
            var item = manager.Item;

            // Log or otherwise complete request
            Console.WriteLine(item.Id + " - " + item.QueueName +  " - Item Completed");
        }
コード例 #27
0
 /// <summary>
 /// Message hook that's responsible for retrieving the next message.
 /// The base version pulls the next message for the given queue.    
 /// You can override this method to conditionally override this 
 /// behavior such as filter when and how messages are read.
 /// </summary>
 /// <param name="manager">A manager instance that can retrieve</param>
 /// <param name="queueName">The queue to check</param>
 /// <returns></returns>
 protected virtual QueueMessageItem OnGetNextQueueMessage(QueueMessageManager manager, string queueName)
 {            
     return manager.GetNextQueueMessage(queueName);
 }
コード例 #28
0
        protected override void OnExecuteComplete(QueueMessageManager manager)
        {          
            base.OnExecuteComplete(manager);

            LocalDataStoreSlot threadData = Thread.GetNamedDataSlot(STR_STARTTIME_KEY);
            
            var watch = Thread.GetData(threadData);

            int elapsed = 0;
            if (watch != null)
            {
                ((Stopwatch)watch).Stop();
                elapsed = (int) ((Stopwatch)watch).ElapsedMilliseconds;
            }
            watch = null;
            Thread.SetData(threadData, watch);

            int waitingMessages = manager.GetWaitingQueueMessageCount(QueueName);
            
            WriteMessage(manager.Item,elapsed,waitingMessages);
        }
コード例 #29
0
 public QueueMessageManagerSerializationHelper(QueueMessageManager manager)
 {
     Manager = manager;
 }