private void RunThreadTask(ThreadTask threadTask) { try { threadTask.Duration = Stopwatch.StartNew(); try { if (threadTask.Database?.Disposed == true) { logger.Warn($"Ignoring request to run threadTask because the database ({threadTask.Database.Name}) is been disposed."); return; } _runningTasks.TryAdd(threadTask, null); threadTask.Action(); } finally { if (threadTask.BatchStats != null) { Interlocked.Increment(ref threadTask.BatchStats.Completed); } threadTask.Duration.Stop(); object _; _runningTasks.TryRemove(threadTask, out _); } } catch (Exception e) { logger.ErrorException( $"Error occured while executing RavenThreadPool task ; Database name: {threadTask?.Database?.Name} ; " + $"Task queued at: {threadTask?.QueuedAt} ; Task Description: {threadTask?.Description}", e); } }
private void ExecuteSingleBatchSynchronously <T>(IList <T> src, Action <T> action, string description, DocumentDatabase database) { var threadTask = new ThreadTask { Action = () => { action(src[0]); }, BatchStats = new BatchStatistics { Total = 1, Completed = 0 }, EarlyBreak = false, QueuedAt = DateTime.UtcNow, Description = new OperationDescription { From = 1, To = 1, Total = 1, PlainText = description }, Database = database }; try { _runningTasks.TryAdd(threadTask, null); if (database?.Disposed == true) { logger.Warn($"Ignoring request to run a single batch because the database ({database.Name}) is been disposed."); return; } threadTask.Action(); threadTask.BatchStats.Completed++; } catch (Exception e) { if (logger.IsDebugEnabled) { logger.DebugException( "Error occured while executing RavenThreadPool task ; " + $"Database name: {threadTask.Database?.Name} ; Task queued at: {threadTask.QueuedAt} ; " + $"Task Description: {threadTask.Description}", e); } throw; } finally { object _; _runningTasks.TryRemove(threadTask, out _); } }
private void ExecuteSingleBatchSynchronously <T>(IList <T> src, Action <IEnumerator <T> > action, string description) { using (var enumerator = src.GetEnumerator()) { var threadTask = new ThreadTask { Action = () => { action(enumerator); }, BatchStats = new BatchStatistics { Total = src.Count, Completed = 0 }, EarlyBreak = false, QueuedAt = DateTime.UtcNow, Description = new OperationDescription { From = 1, To = src.Count, Total = src.Count, PlainText = description } }; try { threadTask.Action(); threadTask.BatchStats.Completed++; _runningTasks.TryAdd(threadTask, null); } catch (Exception e) { if (logger.IsDebugEnabled) { logger.DebugException( $"Error occured while executing RavenThreadPool task ; ThreadPool name: {Name} ; " + $"Task queued at: {threadTask.QueuedAt} ; Task Description: {threadTask.Description}", e); } throw; } finally { object _; _runningTasks.TryRemove(threadTask, out _); } } }
private void ExecuteWorkOnce(bool shouldWaitForWork = true) { ThreadTask threadTask = null; if (!shouldWaitForWork && _tasks.TryTake(out threadTask) == false) { return; } if (threadTask == null) { threadTask = GetNextTask(); } if (threadTask == null) { return; } try { threadTask.Duration = Stopwatch.StartNew(); try { _runningTasks.TryAdd(threadTask, null); threadTask.Action(); } finally { if (threadTask.BatchStats != null) { Interlocked.Increment(ref threadTask.BatchStats.Completed); } threadTask.Duration.Stop(); object _; _runningTasks.TryRemove(threadTask, out _); } } catch (Exception e) { logger.ErrorException( string.Format( "Error occured while executing RavenThreadPool task; ThreadPool name :{0} ; Task queued at: {1} ; Task Description: {2} ", Name, threadTask.QueuedAt, threadTask.Description), e); } }
private void ExecuteSingleBatchSynchroniously <T>(IList <T> src, Action <IEnumerator <T> > action, string description) { using (var enumerator = src.GetEnumerator()) { var threadTask = new ThreadTask { Action = () => { action(enumerator); }, BatchStats = new BatchStatistics { Total = src.Count, Completed = 0 }, EarlyBreak = false, Description = new OperationDescription { From = 1, To = src.Count, Total = src.Count, PlainText = description } }; object _; try { threadTask.Action(); threadTask.BatchStats.Completed++; _runningTasks.TryAdd(threadTask, null); } catch (Exception e) { logger.ErrorException( string.Format( "Error occured while executing RavenThreadPool task; ThreadPool name :{0} ; Task queued at: {1} ; Task Description: {2} ", Name, threadTask.QueuedAt, threadTask.Description), e); } finally { _runningTasks.TryRemove(threadTask, out _); } } }
public void ExecuteBatch <T>(IList <T> src, Action <T> action, string description = null, bool allowPartialBatchResumption = false, int completedMultiplier = 2, int freeThreadsMultiplier = 2, int maxWaitMultiplier = 1) { if (src.Count == 0) { return; } if (allowPartialBatchResumption && src.Count == 1) { var threadTask = new ThreadTask { Action = () => { action(src[0]); }, BatchStats = new BatchStatistics { Total = 1, Completed = 0 }, EarlyBreak = false, Description = new OperationDescription { From = 1, To = 1, Total = 1, PlainText = description } }; object _; try { threadTask.Action(); threadTask.BatchStats.Completed++; _runningTasks.TryAdd(threadTask, null); } catch (Exception e) { logger.ErrorException( string.Format( "Error occured while executing RavenThreadPool task; ThreadPool name :{0} ; Task queued at: {1} ; Task Description: {2} ", Name, threadTask.QueuedAt, threadTask.Description), e); } finally { _runningTasks.TryRemove(threadTask, out _); } return; } var now = DateTime.UtcNow; CountdownEvent lastEvent; var itemsCount = 0; var batch = new BatchStatistics { Total = src.Count, Completed = 0 }; if (_concurrentEvents.TryDequeue(out lastEvent) == false) { lastEvent = new CountdownEvent(src.Count); } else { lastEvent.Reset(src.Count); } for (; itemsCount < src.Count && _ct.IsCancellationRequested == false; itemsCount++) { var copy = itemsCount; var threadTask = new ThreadTask { Action = () => { try { action(src[copy]); } finally { lastEvent.Signal(); } }, Description = new OperationDescription { Type = OperationDescription.OpeartionType.Atomic, PlainText = description, From = itemsCount + 1, To = itemsCount + 1, Total = src.Count }, BatchStats = batch, EarlyBreak = allowPartialBatchResumption, QueuedAt = now, DoneEvent = lastEvent }; _tasks.Add(threadTask, _ct); } if (!allowPartialBatchResumption) { WaitForBatchToCompletion(lastEvent); return; } WaitForBatchAllowingPartialBatchResumption(lastEvent, batch, completedMultiplier, freeThreadsMultiplier, maxWaitMultiplier); }