How to check if public MSMQ is empty - c#

Is there any way to check if a public MSMQ is empty? For a private MSMQ it's easy:
private bool IsQueueEmpty(string path)
{
bool isQueueEmpty = false;
var myQueue = new MessageQueue(path);
try
{
myQueue.Peek(new TimeSpan(0));
isQueueEmpty = false;
}
catch (MessageQueueException e)
{
if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
{
isQueueEmpty = true;
}
}
return isQueueEmpty;
}
How would I do the same check for a public MSMQ? If I try to check a public MSMQ with the code above it gives me an error on the Peak:
System.ArgumentOutOfRangeException: Length cannot be less than zero.

I just started working with Message Queues but my coworker has this nice way for checking if a queue is empty:
if (MessageQueue.Exists(fullQueuePath))
{
// FYI, GetMessageQueue() is a helper method we use to consolidate the code
using (var messageQueue = GetMessageQueue(fullQueuePath))
{
var queueEnum = messageQueue.GetMessageEnumerator2();
if (queueEnum.MoveNext())
{
// Queue not empty
}
else
{
// Queue empty
}
}
}
The benefit of using this method is that it doesn't throw an exception, and I don't think it requires you to wait for a timeout to occur.

The Peek method is only available on remote machines when you use a direct format name to access the queue. You should be able to use the same code, so long as you're not relying on directory services to get you to the queue.
Direct queue names generally look something like: DIRECT=URLAddressSpecification/QueueName

Leo, you sure about that? You can't use a path name with a remote Peek? The error returned doesn't say invalid format name, which would be expected if that was the case.
In fact the error appears to be on the "isQueueEmpty = false" line - the try/catch doesn't differentiate between the peek and the isQueueEmpty lines.
I bet the isQueueEmpty call is receiving an exception which translates to an negative number.
Now your solution, though, may be correct - a lot of remote calls in MSMQ require format names instead of path names. So if you use a format name for creating myQueue, the isQueueEmpty should work.
Cheers
John Breakwell

To check if the queue is empty the simplest way is to use the method: GetAllMessages(). If there are zero messages, then the queue is empty.
string queueName = ".\private$\testqueue";
if (MessageQueue.Exists(queueName))
{
MessageQueue mq = new MessageQueue(queueName);
var allMessages = mq.GetAllMessages();
if (allMessages.Length > 0)
{
//Queue is not empty
}
else
{
//Queue is empty
}
}
else
{
//Queue does not exist
}

Related

Nservice message field issue

I have implemented Voice call in my code using .net with NServiceBus version 7.
Below is the code snippet to send voice call:
public Task Handle(AddServiceAuto message, IMessageHandlerContext context)
{
try
{
string VoiceCallCode = null;
Guid userID = User.userID;
VoiceCallCode = GetVoiceCallCode(userID);
if (VoiceCallCode != null)
{
publishAddVoiceCallEvent(context, user.caseID, userID.Mobile,
userID.Voicecall, VoiceMessageText, VoiceCallCode);
}
}
}
private void publishAddVoiceCallEvent(IMessageHandlerContext context,
Guid caseID, string mobile, bool voicecall,
string voiceMessageText, string voiceCallCode)
{
AddVoiceCallEvent addVoiceCallEvent = new AddVoiceCallEvent()
{
CaseID = caseID,
Mobile = mobile,
Voicecall = voicecall,
VoiceMessageText = voiceMessageText,
VoiceCallCode = voiceCallCode
};
context.Publish(addVoiceCallEvent).ConfigureAwait(false);
}
public Task Handle(AddVoiceCallEvent message, IMessageHandlerContext context)
{
try
{
Logger.InfoFormat("message.CaseID: {0}", message.CaseID);
Logger.InfoFormat("message.Voicecall= {0}", message.Voicecall);
Logger.InfoFormat("message.Mobile {0}", message.Mobile);
Logger.InfoFormat("message.VoiceCallCode {0}", message.VoiceCallCode);
// The user should satisfy below conditions in order to receive a voice call.
if ((message.Voicecall) && !string.IsNullOrEmpty(message.Mobile) &&
!string.IsNullOrEmpty(message.VoiceMessageText) &&
!string.IsNullOrEmpty(message.VoiceCallCode))
{
Voicecall(message.Mobile, message.Voicecall,
message.VoiceMessageText, message.VoiceCallCode);
}
else
{
Logger.Error("Mobile Value is Empty (OR) Voicecall is False (OR)
+ VoiceMessageText is Empty (OR) VoiceCallCode is Empty");
}
}
}
If condition satisfied it will send voice call, else it will print log.
Problem:
The Voice call is random i.e. sometimes user is receiving voice call and sometimes not(even though with same settings i.e mobile, VoiceCallCode values stored properly in DB and Voicecall is also true)
and the Strange part is, though the values are stored correctly DB, when we look into the logs that we are printing, it shows the value of Mobile, VoiceCallCode is null and Voicecall is false.
Again after 5 mins I tried, it worked.
One more thing is, when voice call is not working.
Logger.InfoFormat("message.CaseID: {0}", message.CaseID); // CaseID printed
For Below, data is not printing even though data is there in available in DB (i.e. printing as null)
Logger.InfoFormat("message.Voicecall= {0}", message.Voicecall);
Logger.InfoFormat("message.Mobile {0}", message.Mobile);
Logger.InfoFormat("message.VoiceCallCode {0}", message.VoiceCallCode);
Strange is that, for CaseID it printed while for others it is not printing.
Why this is happening? Can someone please help on this?
The code you've shared doesn't seem to be a running code (try w/o catch) therefore it would be hard to pinpoint what contributes to the issue. But the random behaviour could be attributed to improper use of async APIs. The handler methods should return a Task or use async/await. So are operations invoked on IMessageHandlerContext.
For example, publishAddVoiceCallEvent should be returning a Task and not void. The code inside it (context.Publish(addVoiceCallEvent).ConfigureAwait(false);) should be either return context.Publish(addVoiceCallEvent); or await context.Publish(addVoiceCallEvent).ConfigureAwait(false);.
NServiceBus comes with a Rozlyn analyzer to help with these issues.

Foreach loop and error that not all code paths return a value: async-await issue?

I am not sure why the "not all code paths return a value" error appears (see commented code below). Is it because the foreach loop is considered as not one path but many, and it's possible that an iteration might not return a value and yet the loop would continue?
[BTW, my goal is to process 100K urls, creating many web requests so they are active simultaneously, and be able to capture the status of each url (alive, moved, timed out) while updating the UI as the set of urls is being processed with real-time information about the number of bad urls found so far and the number or urls processed so far. I've tried Parallel.ForEach approach with synchronous web requests but the UI became unresponsive.]
EDITED to include a test if Rows.Count == 0.
public async Task<UrlInfo> ProcessUrls(DataTable urls)
{
if (urls.Rows.Count == 0)
{
return new UrlInfo();
}
else
{
foreach (DataRow r in urls.Rows)
{
UrlInfo info = new UrlInfo()
{
Url = (string)r["url"],
status = UrlStatusCode.untested,
articleid = (int)r["articleid"]
};
return await Foo(info);
}
}
//return new UrlInfo(); // error unless this line is uncommented
}
public async Task<UrlInfo> Foo(UrlInfo info) {
<snip>
}
The compiler is complaining about the situation where urls.Rows does not contain any elements. In that case, the method will never encounter a return statement.
On a side note, I do not think that method means what you think it means. A method only returns once, so it would only process the first url.

Design pattern for dynamic C# object

I have a queue that processes objects in a while loop. They are added asynchronously somewhere.. like this:
myqueue.pushback(String value);
And they are processed like this:
while(true)
{
String path = queue.pop();
if(process(path))
{
Console.WriteLine("Good!");
}
else
{
queue.pushback(path);
}
}
Now, the thing is that I'd like to modify this to support a TTL-like (time to live) flag, so the file path would be added o more than n times.
How could I do this, while keeping the bool process(String path) function signature? I don't want to modify that.
I thought about holding a map, or a list that counts how many times the process function returned false for a path and drop the path from the list at the n-th return of false. I wonder how can this be done more dynamically, and preferably I'd like the TTL to automatically decrement itself at each new addition to the process. I hope I am not talking trash.
Maybe using something like this
class JobData
{
public string path;
public short ttl;
public static implicit operator String(JobData jobData) {jobData.ttl--; return jobData.path;}
}
I like the idea of a JobData class, but there's already an answer demonstrating that, and the fact that you're working with file paths give you another possible advantage. Certain characters are not valid in file paths, and so you could choose one to use as a delimiter. The advantage here is that the queue type remains a string, and so you would not have to modify any of your existing asynchronous code. You can see a list of reserved path characters here:
http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
For our purposes, I'll use the percent (%) character. Then you can modify your code as follows, and nothing else needs to change:
const int startingTTL = 100;
const string delimiter = "%";
while(true)
{
String[] path = queue.pop().Split(delimiter.ToCharArray());
int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;
if(process(path[0]))
{
Console.WriteLine("Good!");
}
else if (ttl > 0)
{
queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));
}
else
{
Console.WriteLine("TTL expired for path: {0}" path[0]);
}
}
Again, from a pure architecture standpoint, a class with two properties is a better design... but from a practical standpoint, YAGNI: this option means you can avoid going back and changing other asynchronous code that pushes into the queue. That code still only needs to know about the strings, and will work with this unmodified.
One more thing. I want to point out that this is a fairly tight loop, prone to running away with a cpu core. Additionally, if this is the .Net queue type and your tight loop gets ahead of your asynchronous produces to empty the queue, you'll throw an exception, which would break out of the while(true) block. You can solve both issues with code like this:
while(true)
{
try
{
String[] path = queue.pop().Split(delimiter.ToCharArray());
int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;
if(process(path[0]))
{
Console.WriteLine("Good!");
}
else if (ttl > 0)
{
queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));
}
else
{
Console.WriteLine("TTL expired for path: {0}" path[0]);
}
}
catch(InvalidOperationException ex)
{
//Queue.Dequeue throws InvalidOperation if the queue is empty... sleep for a bit before trying again
Thread.Sleep(100);
}
}
If the constraint is that bool process(String path) cannot be touched/changed then put the functionality into myqueue. You can keep its public signatures of void pushback(string path) and string pop(), but internally you can track your TTL. You can either wrap the string paths in a JobData-like class that gets added to the internal queue, or you can have a secondary Dictionary keyed by path. Perhaps even something as simple as saving the last poped path and if the subsequent push is the same path you can assume it was a rejected/failed item. Also, in your pop method you can even discard a path that has been rejected too many time and internally fetch the next path so the calling code is blissfully unaware of the issue.
You could abstract/encapsulate the functionality of the "job manager". Hide the queue and implementation from the caller so you can do whatever you want without the callers caring. Something like this:
public static class JobManager
{
private static Queue<JobData> _queue;
static JobManager() { Task.Factory.StartNew(() => { StartProcessing(); }); }
public static void AddJob(string value)
{
//TODO: validate
_queue.Enqueue(new JobData(value));
}
private static StartProcessing()
{
while (true)
{
if (_queue.Count > 0)
{
JobData data = _queue.Dequeue();
if (!process(data.Path))
{
data.TTL--;
if (data.TTL > 0)
_queue.Enqueue(data);
}
}
else
{
Thread.Sleep(1000);
}
}
}
private class JobData
{
public string Path { get; set; }
public short TTL { get; set; }
public JobData(string value)
{
this.Path = value;
this.TTL = DEFAULT_TTL;
}
}
}
Then your processing loop can handle the TTL value.
Edit - Added a simple processing loop. This code isn't thread safe, but should hopefully give you an idea.

API Design for Timeouts: TimeoutException or boolean return with out parameter?

The scenario is RPC over message queues - since the underlying mechanism is asynchronous, clients should specify how long they want to wait for a response before timing out. As the client, which of these two code snippets would you rather use?
Most importantly: as a user of the GetResponseTo() method, why would you prefer one over the other? How does your choice make your code more extensible, more readable, more testable, etc?
try
{
IEvent response = _eventMgr.GetResponseTo(myRequest, myTimeSpan);
// I have my response!
}
catch(TimeoutException te)
{
// I didn't get a response to 'myRequest' within 'myTimeSpan'
}
OR
IEvent myResponse = null;
if (_eventMgr.GetResponseTo(myRequest, myTimeSpan, out myResponse)
{
// I got a response!
}
else
{
// I didn't get a response... :(
}
For your information, here's the current implementation of GetResponseTo():
public IEvent GetResponseTo(IEvent request, TimeSpan timeout)
{
if (null == request) { throw new ArgumentNullException("request"); }
// create an interceptor for the request
IEventInterceptor interceptor = new EventInterceptor(request, timeout);
// tell the dispatcher to watch for a response to this request
_eventDispatcher.AddInterceptor(interceptor);
// send the request
_queueManager.SendRequest(request);
// block this thread while we wait for a response. If the timeout elapses,
// this will throw a TimeoutException
interceptor.WaitForResponse();
// return the intercepted response
return interceptor.Response;
}
Neither first nor second, I would like to use the Task Parallel Library, which is the recommended way of doing all things asynchronous beginning with .NET 4.5:
Task<IEvent> task = _eventMgr.GetResponseToAsync(myRequest);
if (task.Wait(myTimeSpan))
{
// I got a response!
}
else
{
// I didn't get a response... :(
}
You could look to use AutoResetEvent class this will handle the plumbing for second one.
Try to avoid your first code snippet as exceptions are expensive
Personally i would prefer the exception Version. If i specify some timeout my opinion is that this IS a exception then if i couldn't get a result within the specified timespan. I don't think event based notification is the best decision here. The following Logic depends on the result so it doesn't make Sense for me.
But if you want to provide asynchronous Methods too, the Task thing is a good idea like stated by dtb
Exceptions are heavy and messy, each API method call should be wrapped by try/catch/finally to hanle custom exception. This approach is not developer-friendly so I do not like it.
Considering that GetResponse() call itself is synchronous for API consumer - it is pretty normal to return a value of operation, but I would suggest introducing something more abstract and informative rather than simple bool state, so you can return any state provided by the underlying messaging system, this could be a custom error code, message, or even object. So since this is API - put interface as well:
enum OperationStatus
{
Unknown,
Timeout,
Ok
}
// pretty simple, only message and status code
interface IOperationResult<T>
{
OperationStatus Status { get; }
string Message { get; }
T Item { get; }
}
class GetResponseResult : IOperationResult<IEvent>
{
...
}
class EventManager
{
public IOperationResult<IEvent> GetResponseTo(
IRequest request,
TimeSpan timeInterval)
{
GetResponseResult result;
// wait for async request
// ...
if (timeout)
{
result = new GetResponseResult
{
Status = OperationStatus.Timeout,
Message = underlyingMessagingLib.ErrorMessage
};
}
else
{
result = new GetResponseResult
{
Status = OperationStatus.Ok,
Item = response
};
}
return result;
}
}
I have elected to use the out parameter.
I wanted to mark someone else as the answer, but I am not able to do so. I attempted to implement the TPL-based approach, but was unable to do so, based on the question/answer that I linked in my comments.
I do not want to muddy my event model by introducing even more concepts, as #sll suggests.
And even though #dasheddot prefers the exception Version, #sll has a good point that someone trying to send a bunch of requests and get a bunch of responses in a loop might have to deal with a lot of exceptions.
// potentially 10 exceptions? meh... let's not go down this road.
for(int i=0;i<10;i++)
{
try
{
IEvent response = _eventMgr.GetResponseTo(myRequest, myTimeSpan);
// I have my response!
}
catch(TimeoutException te)
{
// I didn't get a response to 'myRequest' within 'myTimeSpan'
}
}

Is this a good/preferable pattern to Azure Queue construction for a T4 template?

I'm building a T4 template that will help people construct Azure queues in a consistent and simple manner. I'd like to make this self-documenting, and somewhat consistent.
First I made the queue name at the top of the file, the queue names have to be in lowercase so I added ToLower()
The public constructor uses the built-in StorageClient API's to access the connection strings. I've seen many different approaches to this, and would like to get something that works in almost all situations. (ideas? do share)
I dislike the unneeded HTTP requests to check if the queues have been created so I made is a static bool . I didn't implement a Lock(monitorObject) since I don't think one is needed.
Instead of using a string and parsing it with commas (like most MSDN documentation) I'm serializing the object when passing it into the queue.
For further optimization I'm using a JSON serializer extension method to get the most out of the 8k limit. Not sure if an encoding will help optimize this any more
Added retry logic to handle certain scenarios that occur with the queue (see html link)
Q: Is "DataContext" appropriate name for this class?
Q: Is it a poor practice to name the Queue Action Name in the manner I have done?
What additional changes do you think I should make?
public class AgentQueueDataContext
{
// Queue names must always be in lowercase
// Is named like a const, but isn't one because .ToLower won't compile...
static string AGENT_QUEUE_ACTION_NAME = "AgentQueueActions".ToLower();
static bool QueuesWereCreated { get; set; }
DataModel.SecretDataSource secDataSource = null;
CloudStorageAccount cloudStorageAccount = null;
CloudQueueClient cloudQueueClient = null;
CloudQueue queueAgentQueueActions = null;
static AgentQueueDataContext()
{
QueuesWereCreated = false;
}
public AgentQueueDataContext() : this(false)
{
}
public AgentQueueDataContext(bool CreateQueues)
{
// This pattern of setting up queues is from:
// ttp://convective.wordpress.com/2009/11/15/queues-azure-storage-client-v1-0/
//
this.cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
this.cloudQueueClient = cloudStorageAccount.CreateCloudQueueClient();
this.secDataSource = new DataModel.SecretDataSource();
queueAgentQueueActions = cloudQueueClient.GetQueueReference(AGENT_QUEUE_ACTION_NAME);
if (QueuesWereCreated == false || CreateQueues)
{
queueAgentQueueActions.CreateIfNotExist();
QueuesWereCreated = true;
}
}
// This is the method that will be spawned using ThreadStart
public void CheckQueue()
{
while (true)
{
try
{
CloudQueueMessage msg = queueAgentQueueActions.GetMessage();
bool DoRetryDelayLogic = false;
if (msg != null)
{
// Deserialize using JSON (allows more data to be stored)
AgentQueueEntry actionableMessage = msg.AsString.FromJSONString<AgentQueueEntry>();
switch (actionableMessage.ActionType)
{
case AgentQueueActionEnum.EnrollNew:
{
// Add to
break;
}
case AgentQueueActionEnum.LinkToSite:
{
// Link within Agent itself
// Link within Site
break;
}
case AgentQueueActionEnum.DisableKey:
{
// Disable key in site
// Disable key in AgentTable (update modification time)
break;
}
default:
{
break;
}
}
//
// Only delete the message if the requested agent has been missing for
// at least 10 minutes
//
if (DoRetryDelayLogic)
{
if (msg.InsertionTime != null)
if (msg.InsertionTime < DateTime.UtcNow + new TimeSpan(0, 10, 10))
continue;
// ToDo: Log error: AgentID xxx has not been found in table for xxx minutes.
// It is likely the result of a the registratoin host crashing.
// Data is still consistent. Deleting queued message.
}
//
// If execution made it to this point, then we are either fully processed, or
// there is sufficent reason to discard the message.
//
try
{
queueAgentQueueActions.DeleteMessage(msg);
}
catch (StorageClientException ex)
{
// As of July 2010, this is the best way to detect this class of exception
// Description: ttp://blog.smarx.com/posts/deleting-windows-azure-queue-messages-handling-exceptions
if (ex.ExtendedErrorInformation.ErrorCode == "MessageNotFound")
{
// pop receipt must be invalid
// ignore or log (so we can tune the visibility timeout)
}
else
{
// not the error we were expecting
throw;
}
}
}
else
{
// allow control to fall to the bottom, where the sleep timer is...
}
}
catch (Exception e)
{
// Justification: Thread must not fail.
//Todo: Log this exception
// allow control to fall to the bottom, where the sleep timer is...
// Rationale: not doing so may cause queue thrashing on a specific corrupt entry
}
// todo: Thread.Sleep() is bad
// Replace with something better...
Thread.Sleep(9000);
}
Q: Is "DataContext" appropriate name for this class?
In .NET we have a lot of DataContext classes, so in the sense that you want names to appropriately communicate what the class does, I think XyzQueueDataContext properly communicates what the class does - although you can't query from it.
If you want to stay more aligned to accepted pattern languages, Patterns of Enterprise Application Architecture calls any class that encapsulates access to an external system for a Gateway, while more specifically you may want to use the term Channel in the language of Enterprise Integration Patterns - that's what I would do.
Q: Is it a poor practice to name the Queue Action Name in the manner I have done?
Well, it certainly tightly couples the queue name to the class. This means that if you later decide that you want to decouple those, you can't.
As a general comment I think this class might benefit from trying to do less. Using the queue is not the same thing as managing it, so instead of having all of that queue management code there, I'd suggest injecting a CloudQueue into the instance. Here's how I implement my AzureChannel constructor:
private readonly CloudQueue queue;
public AzureChannel(CloudQueue queue)
{
if (queue == null)
{
throw new ArgumentNullException("queue");
}
this.queue = queue;
}
This better fits the Single Responsibility Principle and you can now implement queue management in its own (reusable) class.

Categories