public static MemcachedQueueEnqueueResult Enqueue(string queueName, object data, int generation = 0, uint maxRetryTimes = 2) { if (maxRetryTimes < 0) { maxRetryTimes = 0; } if (string.IsNullOrWhiteSpace(queueName)) { throw new ArgumentNullException("queueName"); } queueName = queueName.Trim(); string localCacheKey = "MemQ.Id|" + queueName; bool rst = false; var client = MemcachedCacheHelper.GetClientInstance(); ulong? index; string queueId; bool notReadFromLocalCache = false; do { queueId = GetOrCreateQueueId(queueName, notReadFromLocalCache); index = client.Increment(BuildIndexKey(queueId, MemcachedQueueIndexType.Enqueue), 1); if (index == null) // 有可能本地缓存读取的id已经过期试下了,需要在下次循环执行时,不走本地缓存重新获取 { notReadFromLocalCache = true; } }while (index == null); // 程序执行到这里,EnqueueIndex已经被增长上去了,但此index处的数据还未Set写入,那么此时并发的Dequeue操作则有可能读取到此index的,但获取数据是获取不到的 // 所以在Dequeue方法里有针对这种极端并发的处理代码,结合这里的代码注释就容易理解了 string itemKey = BuildItemIndexKey(queueId, index.Value); var item = new MemcachedQueueItem { Data = data, Generation = generation }; rst = client.Set(itemKey, item); // 程序执行到这里才真正开始将此index的数据写入 int retryTime = 0; while (rst == false) // 如果写入失败,则重试 { if (retryTime >= maxRetryTimes) // 重试次数达到最大重试次数,则不再重试 { break; } Thread.Sleep(10); // 等待10ms再试 rst = client.Set(itemKey, item); retryTime++; } return(new MemcachedQueueEnqueueResult(queueName, rst, index.Value)); }
public static MemcachedQueueItem[] GetAllItems(string queueName) { if (string.IsNullOrWhiteSpace(queueName)) { throw new ArgumentNullException("queueName"); } queueName = queueName.Trim(); string queueId = GetQueueId(queueName); if (string.IsNullOrWhiteSpace(queueId)) // 队列列表里未找到指定名称的队列 { return(new MemcachedQueueItem[0]); } var ary = GetIndexById(queueId, MemcachedQueueIndexType.Dequeue, MemcachedQueueIndexType.Enqueue); ulong de_index = ary == null || ary.Length <= 0 ? 0 : ary[0]; ulong en_index = ary == null || ary.Length <= 1 ? 0 : ary[1]; if (en_index <= de_index) // 说明队列是空的 { return(new MemcachedQueueItem[0]); } ulong len = en_index - de_index; MemcachedQueueItem[] rstList = new MemcachedQueueItem[len]; const ulong maxBatchSize = 100; ulong itemIndex = de_index; int index = 0; var client = MemcachedCacheHelper.GetClientInstance(); while (itemIndex < en_index) { ulong leftItemCount = en_index - itemIndex; uint batchSize = (uint)(leftItemCount < maxBatchSize ? leftItemCount : maxBatchSize); string[] keys = new string[batchSize]; for (uint i = 0; i < batchSize; i++) { itemIndex++; keys[i] = BuildItemIndexKey(queueId, itemIndex); } var objs = client.Get(keys); for (uint i = 0; i < batchSize; i++) { var obj = (objs == null || i >= objs.Length) ? null : objs[i]; rstList[index] = obj as MemcachedQueueItem; index++; } } return(rstList); }
public static MemcachedQueueItem GetItemWithProcessResult(string queueName, long index, out MemcachedQueueItemProcessResult processResult) { if (string.IsNullOrWhiteSpace(queueName)) { throw new ArgumentNullException("queueName"); } if (index <= 0) { processResult = null; return(null); } queueName = queueName.Trim(); var queueId = GetQueueId(queueName); if (string.IsNullOrWhiteSpace(queueId)) { processResult = null; return(null); } string itemKey = BuildItemIndexKey(queueId, (ulong)index); string itemProcessdResultKey = BuildItemIndexKeyForProcessResult(queueId, (ulong)index); var client = MemcachedCacheHelper.GetClientInstance(); var objs = client.Get(new string[] { itemKey, itemProcessdResultKey }); MemcachedQueueItem item = null; processResult = null; if (objs != null) { if (objs.Length > 0) { item = objs[0] as MemcachedQueueItem; } if (objs.Length > 1) { processResult = objs[1] as MemcachedQueueItemProcessResult; } } return(item); }
public static MemcachedQueueItem[] GetItem(string queueName, long[] indexs) { if (string.IsNullOrWhiteSpace(queueName)) { throw new ArgumentNullException("queueName"); } if (indexs == null || indexs.Length <= 0) { return(new MemcachedQueueItem[0]); } queueName = queueName.Trim(); var queueId = GetQueueId(queueName); if (string.IsNullOrWhiteSpace(queueId)) { return(new MemcachedQueueItem[indexs.Length]); } string[] itemKeys = new string[indexs.Length]; for (var i = 0; i < indexs.Length; i++) { itemKeys[i] = BuildItemIndexKey(queueId, indexs[i] <= 0 ? 0 : (ulong)indexs[i]); } var client = MemcachedCacheHelper.GetClientInstance(); var list = client.Get(itemKeys); if (list == null || list.Length <= 0) { return(new MemcachedQueueItem[indexs.Length]); } MemcachedQueueItem[] rstList = new MemcachedQueueItem[indexs.Length]; for (uint i = 0; i < indexs.Length; i++) { var obj = (list == null || i >= list.Length) ? null : list[i]; rstList[i] = obj as MemcachedQueueItem; } return(rstList); }