private void SignalNext(BamWorkRequest workRequest, string chrName)
        {
            lock (_sync)
            {
                var remainingWork = _remainingChrByBam[workRequest];
                remainingWork.Remove(chrName);

                if (remainingWork.Any())
                {
                    _throttleSignalsByBamChr[GetThrottleKey(workRequest, remainingWork.First())].Set();
                }
            }
        }
        private void ProcessByBam(BamWorkRequest workRequest, string chrName)
        {
            var bamFileName = workRequest.BamFileName;

            try
            {
                if (ShouldThrottle)
                {
                    AcquireSignal(workRequest, chrName);
                }

                if (_maxChrsProcessingAllowed.HasValue)
                {
                    EnforceChrLimit(chrName);
                }

                var chrReference = GetChrReference(chrName);
                if (chrReference == null)
                {
                    return;  // missing chr, move on
                }
                Logger.WriteToLog(string.Format("{0}: Start processing chr '{1}'.", bamFileName, chrName));
                var startTime = DateTime.UtcNow;

                Process(workRequest, chrReference);

                var processingTime = DateTime.UtcNow.Subtract(startTime).TotalSeconds;
                Logger.WriteToLog(string.Format("{0}: Completed processing chr '{2}' in {1}s", bamFileName, processingTime, chrName));
                TrackTime(workRequest.BamFilePath, processingTime);
            }
            catch (Exception ex)
            {
                var wrappedException = new Exception(string.Format("{1}: Error processing chr '{0}': {2}", chrName, bamFileName, ex.Message), ex);
                Logger.WriteExceptionToLog(wrappedException);

                lock (this)
                    Exceptions.Add(ex);
            }
            finally
            {
                CheckChrComplete(chrName, workRequest);
                if (ShouldThrottle)
                {
                    SignalNext(workRequest, chrName);
                }
            }
        }
        private void CheckChrComplete(string chrName, BamWorkRequest completedWorkRequest)
        {
            lock (_sync)
            {
                var chrWork = _remainingWorkByChr[chrName];

                chrWork.Remove(completedWorkRequest);

                if (!chrWork.Any()) // no more work left
                {
                    if (_currentlyProcessingChrs.ContainsKey(chrName))
                    {
                        _currentlyProcessingChrs[chrName].Sequence = null;
                        _currentlyProcessingChrs.Remove(chrName);
                    }

                    Logger.WriteToLog("Unloaded chromosome '{0}', all jobs complete.", chrName);
                }
            }
        }
 private void AcquireSignal(BamWorkRequest workRequest, string chrName)
 {
     _throttleSignalsByBamChr[GetThrottleKey(workRequest, chrName)].WaitOne();
 }
 private string GetThrottleKey(BamWorkRequest workRequest, string chrName)
 {
     return(workRequest.BamFilePath + "-" + chrName);
 }
 protected abstract void Process(BamWorkRequest workRequest, ChrReference chrReference);