See if item exists in queue

Hello,

I have a bot which adds items to a queue. The code I inherited functions using the following psuedo-code.

foreach (item in queueItemsToAdd)
{
    try
    {
        AddItemToQueue(item, "QueueName");
        Log("Item added to queue.");
    }
    catch (exception)
    {
        Log("Item could not be added to queue.");
    }
}

This is an abuse of the exception handling system and it’s slow (timeout * number of items already in the queue, which can be 10 or 20 sometimes). Normally, one would be able to perform a Contains() check if it were a collection or a Find() if it were an EF DbSet, but no equivalent seems to exist here. I can use the Get Queue Items activity, but according to the documentation, it only returns “a list of up to 100 queue transactions…” When I’m working with queues of 250 items or more, this proves problematic.

Is there a way to get a Queue object reference and make a function call on that or will I need to build a custom activity and call the Orchestrator API directly to get a boolean based on whether the item exists or not?

End goal is to rewrite this section so it reads more like this psuedo-code:

foreach (item in queueItemsToAdd)
{
    var queue = GetQueue("QueueName");
    if (!queue.Contains(item))
    {
        queue.AddItem(item);
        Log("Item added to queue.");
        continue;
    }
    
    Log("Item could not be added to the queue.");
}
2 Likes

Ok, there are a couple of approaches here.

A simple one would be to use the Reference property of the Get Queue Items. Then, using queueItems.Count > 0, you can check if it matched with the reference.

To get around the 100 items limit, you can use a Do While loop (if this is even needed). If you use the unique reference, then you wouldn’t need to do this:


The above example is how I was getting around the limit to get all pending queue items.
EDIT: the reason for the Retry scope, was because server to Orchestrator sometimes failed in my environments.

But, like I said, you can use the Reference property if it is unique to get the items that match. If the .Count > 0, then it found a match.

Regards.

4 Likes

Also, with more than one queue item in this enumerable, you would need to iterate using .net linq:
queueItems.Where(Function(q) q.SpecialContent("valuekey") = "value").Count > 0
There’s a lot more that you can do with this enumerable too, if you want to explore, such as look at the reference or any of the fields for the queue items.

I ended up building a quick sequence to handle this. It accepts the item Id and the QueueName as input parameters and an Exists boolean as an output parameter.

Inside the sequence there are two activities - the Get Queue Items activity with the queue name and reference parameters set accordingly (and FilterStrategy set to Equals). The second one is an assign where I set the value of the Exists boolean to queueItems.Any().

Any() is faster because Count() enumerates the entire collection whereas Any() short circuits as soon as it finds a single record.

I’ll give the code a test and see how it works. Thanks for the help.

3 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.