BatchQueue queue polling question (problem with polling a queue)

BatchQueue queue polling question (problem with polling a queue)

Old forum URL: forums.lhotka.net/forums/t/1100.aspx


lewischris posted on Friday, September 01, 2006

Hi,

Yet another question relating to the CSLA 1.x BatchQueue components!

I have implemented a Windows service to process BatchJobRequests on a transactional MSMQ queue. When I start the service with a message already on the queue, the BatchJobRequest gets picked up and processed as it should (I have implemented a console app to step through the code).

However, if I subsequently send another BatchJobRequest to the queue it just sits there and is never processed. I've looked at the code, and this would seem to be because the Timer is never re-started because of the condition in the code below (in non-bold text) - which means that the MonitorQueue stays in the WaitOne state - it never gets notified by the Timer that it should poll the queue.

I have modified the code in the BatchQueueService.ScanQueue() method as follows (bold text is my added code):

if(nextWake < DateTime.MaxValue && nextWake > DateTime.Now)
{
 // we have at least one entry holding, so set the
 // timer to wake us when it should be run
 _timer.Interval = nextWake.Subtract(DateTime.Now).TotalMilliseconds;
 _timer.Start();
}
else
{
 _timer.Start();
}

And now, unless a nextWake time is specified, the queue is polled continuously every 100 milliseconds (which is the default poll interval).

Does this seem right? Should it be necessary to do this, and have I done this correctly?

As ever, any help is much appreciated.

Chris

 

figuerres replied on Friday, September 01, 2006

generally if I want to setup a service to do stuff I start with a layout kinda like this:

 

While(true && (!_ShutDownFlag)){
   // Do Stuff Here 
   If (X)
      break;
   else
      Thread.Sleep( _SleepTime );
}

this is in a method that init's the loop and is started by using the Threading / start a new thread stuff in .net

the SleepTime and ShutdownFlag are defined in the main code and let other logic control the loop and exit.

where I put "Do STuff" that's generaly a few calls to methods that are only called by that thread to do the work and as they finish the loop keeps going.

if I am using .Net 2.0 I use the backgroundworker as it does most of the setup work.

 

Brad Harrison replied on Sunday, September 10, 2006

Chris,

Here's what I did... Below is first pass (almost hack) and I'll look at it again later. I will be looking at this again because I'm concerned that the batch server will not wake up when something is in the queue with a future run date and something else is added. 

At the end of the Start() routine:

            ' == added
            AddHandler mQueue.PeekCompleted, AddressOf mQueue_PeekCompleted
            mQueue.BeginPeek() ' wait for something to arrive
        End Sub

#Region " Fire when new msg arrives in empty queue"

        Private Shared Sub mQueue_PeekCompleted(ByVal sender As Object, ByVal e As System.Messaging.PeekCompletedEventArgs)
            Try
                mQueue.EndPeek(e.AsyncResult)
                mSync.Set()
                ' mQueue.BeginPeek()
            Catch ex As Exception ' if we are waiting when the program ends, we get an exception
            End Try
        End Sub

#End Region

And at the bottom of the ScanQueue() routine:

            ' -- added
            If nextWake = Date.MaxValue Then
                ' nothing in queue, just wait for something to arrive
                mQueue.BeginPeek()
            End If
     End Sub

It accomplishes the same basic thing, but I didn't want to keep polling to check the queue. When I get back to this, I will fix so that if something is in the queue, I poll ever 5 seconds or so.

Brad

PS: I'm doing this because I built a ReadOnly business object to store jobs directly into the queue without going through the TCP channel.  (Less to configure)

 

Copyright (c) Marimer LLC