I'm in the middle of a project that was built around Microsoft's Message Queue service. During development all of our machines are on a domain and we were able to create a public queue accessible from the server and client.
When moving this to our test server, I discovered that both the test server and production servers are running in workgroup mode, no public queues available.
I'm experimenting with creating a webservice broker backed by a MemoryCache. Here is what I've got so far. Each key is posted into a FIFO queue due to the needs of the project.
Has anyone else done something similar? What about concurrency? Any other gotchas I should be concerned about?
UPDATED: Added suggested changes, and handled differences resulting from use of ConcurrentQueue and Lazy instantiation.
[WebMethod]
public bool Push(string key, string value)
{
if (String.IsNullOrWhiteSpace(key) || String.IsNullOrWhiteSpace(value)) return false;
// input validation removed for brevity
var queue = GetQueue(key);
queue.Enqueue(value);
return true;
}
[WebMethod]
public string Pop(string key)
{
var queue = GetQueue(key);
string result = "";
if (queue.TryDequeue(out result))
{
return result;
}
return null;
}
[WebMethod]
public List<string> RemoveAll(string key)
{
var queue = GetQueue(key);
var list = queue.ToList();
queue.Clear();
return list;
}
private ConcurrentQueue<string> GetQueue(string key)
{
var cache = MemoryCache.Default;
var queue = (Lazy<ConcurrentQueue<string>>) (cache.AddOrGetExisting(key.ToLowerInvariant(),new Lazy<ConcurrentQueue<string>>() , new CacheItemPolicy
{
AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
SlidingExpiration = TimeSpan.FromMinutes(5)
}) ?? cache[key.ToLowerInvariant()]);
return queue.Value;
}
I also added an extension for the ConcurrentQueue to clear it.
public static class ConcurrentQueueExtensions
{
public static void Clear<T>(this ConcurrentQueue<T> queue)
{
T item;
while (queue.TryDequeue(out item))
{
// do nothing
}
}
}