private async Task RunEventsAsync(Run run) { var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); IRunnerSettings runnerSettings = config.GetSection(nameof(RunnerSettings)).Get <RunnerSettings>(); Console.WriteLine($"{DateTime.Now} - Warming up thread pool..."); System.Threading.ThreadPool.SetMaxThreads(32767, 32767); System.Threading.ThreadPool.SetMinThreads(32767, 32767); Console.WriteLine($"{DateTime.Now} - Nesting events..."); //Remove any sessions with no events run.Sessions.RemoveAll(s => s.Events.Count == 0); foreach (Session session in run.Sessions) { var nestedEvents = new List <Event>(); Transaction parentTransaction = null; foreach (Event evt in session.Events) { if (parentTransaction != null && evt.TransactionId != "0") { parentTransaction.Events.Add(evt); } else { nestedEvents.Add(evt); } if (evt is Transaction transaction) { switch (transaction.TransactionState) { case "Begin": parentTransaction = transaction; break; case "Commit": case "Rollback": parentTransaction = session.Events .Where(e => ((e as Transaction)?.Events.Contains(parentTransaction)).GetValueOrDefault()) .SingleOrDefault() as Transaction; break; } } } session.Events = nestedEvents; } Console.WriteLine($"{DateTime.Now} - Preparing {runnerSettings.BucketInterval} second buckets of sessions..."); var buckets = run.Sessions.GroupBy(s => { Event firstEvt = s.Events.First(); return(firstEvt.Timestamp.ToString("ddHHmm") + firstEvt.Timestamp.Second / runnerSettings.BucketInterval); }) .OrderBy(g => g.Key) .Select(g => g.OrderBy(s => s.Events.First().Timestamp) .ToList() ).ToList(); // Delay start time to sync across processes var pStartTime = Process.GetCurrentProcess().StartTime; // local time TimeSpan delay = pStartTime.AddMinutes(runnerSettings.StartDelayMinutes) - DateTime.Now; try { await Task.Delay(delay); } catch (ArgumentOutOfRangeException) { Console.WriteLine($"{DateTime.Now} - Syncing delay failed due to negative delay TimeSpan of {delay.TotalMilliseconds} ms. Process Start time: {pStartTime}"); } Console.WriteLine($"{DateTime.Now} - Kicking off executions..."); var tasks = new List <Task>(); var eventExecutor = new EventExecutor(); var replayOrigin = DateTimeOffset.UtcNow; foreach (var bucket in buckets) { var bucketTimestamp = bucket.First().Events.First().Timestamp; TimeSpan timeToDelay = bucketTimestamp.Subtract(run.EventCaptureOrigin).Subtract(DateTimeOffset.UtcNow.Subtract(replayOrigin)); if (timeToDelay.TotalMilliseconds > 0) { await Task.Delay(timeToDelay); } Console.WriteLine($"{DateTime.Now} - Starting bucket: {bucketTimestamp} - timeToDelay = {timeToDelay}"); tasks.Add(eventExecutor.ExecuteSessionEventsAsync(run.EventCaptureOrigin, replayOrigin, bucket, run.ConnectionString, runnerSettings)); Console.WriteLine($"{DateTime.Now} - Finished submitting bucket: {bucketTimestamp}"); } Console.WriteLine($"{DateTime.Now} - Waiting for unfinished executions to complete..."); await Task.WhenAll(tasks); Console.WriteLine($"{DateTime.Now} - Executions complete."); this.Exceptions.AddRange(eventExecutor.Exceptions); }
private async Task RunEventsAsync(Run run) { var config = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .Build(); IRunnerSettings runnerSettings = config.GetSection(nameof(RunnerSettings)).Get <RunnerSettings>(); Console.WriteLine("Warming up thread pool..."); System.Threading.ThreadPool.SetMaxThreads(32767, 32767); System.Threading.ThreadPool.SetMinThreads(32767, 32767); Console.WriteLine("Nesting events..."); //Remove any sessions with no events run.Sessions.RemoveAll(s => s.Events.Count == 0); foreach (Session session in run.Sessions) { var nestedEvents = new List <Event>(); Transaction parentTransaction = null; foreach (Event evt in session.Events) { if (parentTransaction != null && evt.TransactionId != "0") { parentTransaction.Events.Add(evt); } else { nestedEvents.Add(evt); } if (evt is Transaction transaction) { switch (transaction.TransactionState) { case "Begin": parentTransaction = transaction; break; case "Commit": case "Rollback": parentTransaction = session.Events .Where(e => ((e as Transaction)?.Events.Contains(parentTransaction)).GetValueOrDefault()) .SingleOrDefault() as Transaction; break; } } } session.Events = nestedEvents; } Console.WriteLine("Preparing 15 second buckets of sessions..."); var buckets = run.Sessions.GroupBy(s => { Event firstEvt = s.Events.First(); return(firstEvt.Timestamp.ToString("ddhhmm") + firstEvt.Timestamp.Second / runnerSettings.BucketInterval); }) .OrderBy(g => g.Key) .Select(g => g.OrderBy(s => s.Events.First().Timestamp) .ToList() ).ToList(); Console.WriteLine("Kicking off executions..."); var tasks = new List <Task>(); var eventExecutor = new EventExecutor(); var replayOrigin = DateTimeOffset.UtcNow; foreach (var bucket in buckets) { var bucketTimestamp = bucket.First().Events.First().Timestamp; TimeSpan timeToDelay = bucketTimestamp.Subtract(run.EventCaptureOrigin).Subtract(DateTimeOffset.UtcNow.Subtract(replayOrigin)); if (timeToDelay.TotalMilliseconds > 0) { await Task.Delay(timeToDelay); } Console.WriteLine("Starting bucket: " + bucketTimestamp); tasks.Add(eventExecutor.ExecuteSessionEventsAsync(run.EventCaptureOrigin, replayOrigin, bucket, run.ConnectionString, runnerSettings)); Console.WriteLine("Ending Delay: " + bucketTimestamp); } Console.WriteLine("Waiting for unfinished executions to complete..."); await Task.WhenAll(tasks); Console.WriteLine("Executions complete."); this.Exceptions.AddRange(eventExecutor.Exceptions); }