private static int RunUnderLogging(AppOptions options, DateTime start) { IRunnerSettings settings = (RunnerSettings)options; using (var logger = new Logger()) using (var rollingFileLogSink = new RollingFileLogSink(settings.FileLoggerSettings)) { try { logger.AddLogSink(rollingFileLogSink); SendLogFilePathToExchange(logger, rollingFileLogSink, options); var runner = new Runner(settings, logger); return((int)runner.Go()); } catch (Exception ex) { logger.PostException(ex); throw ex; } finally { logger.PostEntryNoTimestamp("Elapsed time {0}", DateTime.UtcNow - start); logger.CompleteAllAsync().Wait(new TimeSpan(0, 0, 3)); } } }
public void Configure( string assemblyLocation, IRunnerSettings runnerSettings) { _assemblyLocation = assemblyLocation; _runnerSettings = runnerSettings; }
public void Configure(string assemblyLocation, IRunnerSettings runnerSettings) { _assemblyLocation = assemblyLocation; _runnerSettings = runnerSettings; _outputPath = runnerSettings.OutputBasePath; if (!Directory.Exists(_outputPath)) Directory.CreateDirectory(_outputPath); }
public Runner(IRunnerSettings settings, ILogger logger = null) { if (settings == null) throw new ArgumentNullException("settings"); _settings = settings; _logger = logger ?? new NullLogger(); var configPath = Path.Combine(Directory.GetCurrentDirectory(), "config.json"); using (var reader = new FileInfo(configPath).OpenText()) _config = JsonConvert.DeserializeObject<ScriptDeployerConfig>(reader.ReadToEnd()); }
public Runner(IRunnerSettings settings, ILogger logger = null) { if (settings == null) { throw new ArgumentNullException("settings"); } _settings = settings; _logger = logger ?? new NullLogger(); var configPath = Path.Combine(Directory.GetCurrentDirectory(), "config.json"); using (var reader = new FileInfo(configPath).OpenText()) _config = JsonConvert.DeserializeObject <ScriptDeployerConfig>(reader.ReadToEnd()); }
private async Task ExecuteTransactionEventsAsync(DateTimeOffset eventCaptureOrigin, DateTimeOffset replayOrigin, Transaction transaction, string connectionString, IRunnerSettings runnerSettings) { foreach (var evt in transaction.Events) { TimeSpan timeToDelay = evt.Timestamp.Subtract(eventCaptureOrigin).Subtract(DateTimeOffset.UtcNow.Subtract(replayOrigin)); if (timeToDelay.TotalMilliseconds > 0) { await Task.Delay(timeToDelay); } if (evt is Transaction nestedTransaction) { if (nestedTransaction.TransactionState == "Begin") { using (var nestedTransactionScope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = TimeSpan.FromSeconds(runnerSettings.TransactionScopeTimeout) }, TransactionScopeAsyncFlowOption.Enabled)) { await ExecuteTransactionEventsAsync(eventCaptureOrigin, replayOrigin, nestedTransaction, connectionString, runnerSettings); nestedTransactionScope.Complete(); } } else if (nestedTransaction.TransactionState == "Rollback") { throw new TransactionAbortedException(); } } else if (evt is Rpc rpc) { string commandText; CommandType commandType; if (!string.IsNullOrWhiteSpace(rpc.Procedure)) { commandText = rpc.Procedure; commandType = CommandType.StoredProcedure; } else { commandText = rpc.Statement; commandType = CommandType.Text; } await RetryDeadlock(async() => { using (var sqlConnection = new SqlConnection(connectionString)) { await sqlConnection.OpenAsync(); using (var sqlCommand = new SqlCommand(commandText, sqlConnection) { CommandType = commandType, CommandTimeout = runnerSettings.SqlCommandTimeout }) { SetupSqlCommandParameters(sqlCommand, rpc); await sqlCommand.ExecuteNonQueryAsync(); } } }); } else if (evt is BulkInsert bulkInsert) { if (bulkInsert.Rows.Count == 0) { continue; } var dataTable = new DataTable(); foreach (var column in bulkInsert.Columns) { dataTable.Columns.Add(GetDataColumn(column)); } for (var rowIndex = 0; rowIndex < bulkInsert.Rows.Count; rowIndex++) { DataRow dataRow = dataTable.NewRow(); for (var columIndex = 0; columIndex < bulkInsert.Columns.Count; columIndex++) { dataRow[columIndex] = bulkInsert.Rows[rowIndex][columIndex]; } dataTable.Rows.Add(dataRow); } SqlBulkCopyOptions options; if (bulkInsert.CheckConstraints && bulkInsert.FireTriggers) { options = SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers; } else if (bulkInsert.CheckConstraints) { options = SqlBulkCopyOptions.CheckConstraints; } else if (bulkInsert.FireTriggers) { options = SqlBulkCopyOptions.FireTriggers; } else { options = SqlBulkCopyOptions.Default; } await RetryDeadlock(async() => { using (var sqlConnection = new SqlConnection(connectionString)) { await sqlConnection.OpenAsync(); using (var bulkCopy = new SqlBulkCopy(sqlConnection, options, null) { BulkCopyTimeout = runnerSettings.BulkCopyTimeout }) { bulkCopy.DestinationTableName = bulkInsert.Table; foreach (DataColumn column in dataTable.Columns) { bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(column.ColumnName, column.ColumnName)); } await bulkCopy.WriteToServerAsync(dataTable); } } }); } } }
public async Task ExecuteSessionEventsAsync(DateTimeOffset eventCaptureOrigin, DateTimeOffset replayOrigin, IEnumerable <Session> sessions, string connectionString, IRunnerSettings runnerSettings) { List <Task> sessionTasks = new List <Task>(); foreach (var session in sessions) { sessionTasks.Add(Task.Run(async() => { List <Task> evtTasks = new List <Task>(); foreach (var evt in session.Events) { evtTasks.Add(Task.Run(async() => { TimeSpan timeToDelay = evt.Timestamp.Subtract(eventCaptureOrigin).Subtract(DateTimeOffset.UtcNow.Subtract(replayOrigin)); if (timeToDelay.TotalMilliseconds > 0) { await Task.Delay(timeToDelay); } if (evt is Transaction transaction) { //Only pay attention to Begin as any Rollback at this level would not have a corresponding Begin if (transaction.TransactionState == "Begin") { try { using (var transactionScope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions() { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted, Timeout = TimeSpan.FromSeconds(runnerSettings.TransactionScopeTimeout) }, TransactionScopeAsyncFlowOption.Enabled)) { await ExecuteTransactionEventsAsync(eventCaptureOrigin, replayOrigin, transaction, connectionString, runnerSettings); transactionScope.Complete(); } } catch (TransactionAbortedException) { //These are simply rollbacks, no need to log } catch (Exception ex) { this.Exceptions.Add(ex); } } } else if (evt is Rpc rpc) { string commandText; CommandType commandType; if (!string.IsNullOrWhiteSpace(rpc.Procedure)) { commandText = rpc.Procedure; commandType = CommandType.StoredProcedure; } else { commandText = rpc.Statement; commandType = CommandType.Text; } try { await RetryDeadlock(async() => { using (var sqlConnection = new SqlConnection(connectionString)) { await sqlConnection.OpenAsync(); using (var sqlCommand = new SqlCommand(commandText, sqlConnection) { CommandType = commandType, CommandTimeout = runnerSettings.SqlCommandTimeout }) { SetupSqlCommandParameters(sqlCommand, rpc); await sqlCommand.ExecuteNonQueryAsync(); } } }); } catch (Exception ex) { this.Exceptions.Add(ex); } } else if (evt is BulkInsert bulkInsert) { if (bulkInsert.Rows.Count == 0) { return; } var dataTable = new DataTable(); foreach (var column in bulkInsert.Columns) { dataTable.Columns.Add(GetDataColumn(column)); } for (var rowIndex = 0; rowIndex < bulkInsert.Rows.Count; rowIndex++) { DataRow dataRow = dataTable.NewRow(); for (var columIndex = 0; columIndex < bulkInsert.Columns.Count; columIndex++) { dataRow[columIndex] = bulkInsert.Rows[rowIndex][columIndex]; } dataTable.Rows.Add(dataRow); } SqlBulkCopyOptions options; if (bulkInsert.CheckConstraints && bulkInsert.FireTriggers) { options = SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers; } else if (bulkInsert.CheckConstraints) { options = SqlBulkCopyOptions.CheckConstraints; } else if (bulkInsert.FireTriggers) { options = SqlBulkCopyOptions.FireTriggers; } else { options = SqlBulkCopyOptions.Default; } try { await RetryDeadlock(async() => { using (var sqlConnection = new SqlConnection(connectionString)) { await sqlConnection.OpenAsync(); using (var bulkCopy = new SqlBulkCopy(sqlConnection, options, null) { BulkCopyTimeout = runnerSettings.BulkCopyTimeout }) { bulkCopy.DestinationTableName = bulkInsert.Table; foreach (DataColumn column in dataTable.Columns) { bulkCopy.ColumnMappings.Add( new SqlBulkCopyColumnMapping(column.ColumnName, column.ColumnName)); } await bulkCopy.WriteToServerAsync(dataTable); } } }); } catch (Exception ex) { this.Exceptions.Add(ex); } } })); await Task.WhenAll(evtTasks); } })); } await Task.WhenAll(sessionTasks); Console.WriteLine("Ending bucket: " + sessions.First().Events.First().Timestamp); }
public SettingsBasedServiceFactory(IRunnerSettings runnerSettings) { _runnerSettings = runnerSettings; }
public Runner(IRunnerSettings runnerSettings) { replacements = runnerSettings.Replacements ?? new Dictionary<int, Replacement>(); }
public ResultsStatsWriter(IRunnerSettings settings, IHtmlGanttChart ganttChartBuilder) { _settings = settings; _ganttChartBuilder = ganttChartBuilder; }
public ResultsStatsWriter(IRunnerSettings settings) { _settings = settings; }
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); }
public ResultsStatsTemplateWriter(IRunnerSettings settings, IResultsTemplateWriter templateWriter) { _settings = settings; _templateWriter = templateWriter; }
public ResultsOrderService(IRunnerSettings settings, IRunStatsCollectionVersioning statsCollectionVersioning) { _settings = settings; _statsCollectionVersioning = statsCollectionVersioning; }
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); }