public bool RefreshUnprocessedQueueItemList() {
_log.Debug("* Refresh Unprocessed Queue Items, " + DateTime.Now.ToString());
if( !_monitorState.MonitorQueueType.Any(mq => mq) || _mgr.MonitorQueues.Length == 0 )
return false;
List<QueueItem> items = new List<QueueItem>();
// TODO: Solve why we can not iterate thru Remote MQ,
// both GetMessageEnumerator2() and GetAllMessages() should be available for
// Remote computer and direct format name, but returns zero (0) messages in some cases
//if( !Tools.IsLocalHost(_serverName) )
// return;
bool changedItemsCount = false;
var monitorStatesWhenFetch = new SbmqmMonitorState(_monitorState.MonitorQueueType);
List<string> unchangedQueues = new List<string>();
// Temp until we have a more proper way to Discover if Error queues are built-in with normal queues
if( !_monitorState.IsMonitoring(QueueType.Error) )
_unprocessedItemsCount[(int)QueueType.Error] = 0;
// Removed as when changing QTs in UI this would change list and throw a modification exception in Manager.
// Creating an array is not as resource efficient, but it works.
//IEnumerable<QueueItem> currentItems = _items.AsEnumerable<QueueItem>();
foreach( QueueType t in _queueTypeValues ) {
if( _monitorState.IsMonitoring(t) ) {
var r = _mgr.GetUnprocessedMessages(new QueueFetchUnprocessedMessagesRequest(t, _items.ToArray(), GetUnprocessedItemsCount(t)));
if( r.Status == QueueFetchResultStatus.ConnectionFailed )
break;
if( r.Status == QueueFetchResultStatus.NotChanged ) {
unchangedQueues.AddRange(_mgr.MonitorQueues.Where(q => q.Type == t).Select(q => q.Name));
continue;
}
items.AddRange(r.Items);
int typeIndex = (int)t;
if( _unprocessedItemsCount[typeIndex] != r.Count )
changedItemsCount = true;
_unprocessedItemsCount[typeIndex] = r.Count;
if( t != QueueType.Error && items.Any(i => i.Queue.Type == QueueType.Error) ) {
_unprocessedItemsCount[(int)QueueType.Error] += (uint)items.Where(i => i.Queue.Type == QueueType.Error).Count();
changedItemsCount = true;
}
}
}
// Oldest first
if( items.Count > 1 )
items.Sort((a, b) => a.ArrivedTime.CompareTo(b.ArrivedTime));
bool changed = false;
lock( _itemsLock ) {
// If changed Monitor Queues while fetching remove then from result.
List<QueueType> removedQueueTypes = new List<QueueType>(4);
foreach( QueueType t in _queueTypeValues ) {
if( !_monitorState.IsMonitoring(t) && monitorStatesWhenFetch.IsMonitoring(t) ) {
removedQueueTypes.Add(t);
}
}
if( removedQueueTypes.Any() )
items = items.Where(i => !removedQueueTypes.Any(x => x == i.Queue.Type)).ToList();
// Add new items
foreach( var itm in items ) {
var existingItems = _items.Where(i => i.Id == itm.Id).ToArray();
if( !existingItems.Any() ) {
_items.Insert(0, new QueueItemViewModel(itm, _mgr.MessagesHasMilliSecondPrecision));
if( !changed )
changed = true;
} else {
foreach( var existingItem in existingItems ) {
if( itm.Queue.Name != existingItem.Queue.Name /*&& !existingItem.Processed*/ ) { // Moved queue
if( !_items.Any(i => i.MessageQueueItemId == itm.MessageQueueItemId) ) {
existingItem.Processed = true;
_items.Insert(0, new QueueItemViewModel(itm, _mgr.MessagesHasMilliSecondPrecision));
if( !changed )
changed = true;
}
} else if( itm.Queue.Name == existingItem.Queue.Name && existingItem.Processed ) {
// It has been retried, move to top
_items.Remove(existingItem);
existingItem.Processed = false;
_items.Insert(0, existingItem);
if( !changed )
changed = true;
} else if( itm.Queue.Name == existingItem.Queue.Name && !existingItem.Processed ) {
// Processed, but not yet been marked as processed
_items.Remove(existingItem);
_items.Insert(0, existingItem);
if( !changed )
changed = true;
} else {
_log.Trace(" **** Unhandled new item state, " + itm.Id);
}
}
}
}
// Mark removed as deleted messages
foreach( var itm in _items )
if( !unchangedQueues.Contains(itm.Queue.Name) )
if( !items.Any(i2 => i2.Id == itm.Id) ) {
if( !itm.Processed ) {
itm.Processed = true;
if( !changed )
changed = true;
}
}
}
return changed || changedItemsCount;
}
public void RetrieveProcessedQueueItems(TimeSpan timeSpan) {