protected async Task <List <ExecutionHistoryEntry> > ExecuteExecutionHistoryEntryQuery(string query, Action <NpgsqlCommand> sqlCommandModifier = null) { if (query == null) { throw new ArgumentNullException(nameof(query)); } using (var sqlConnection = new NpgsqlConnection(ConnectionString)) { await sqlConnection.OpenAsync(); using (var sqlCommand = new NpgsqlCommand(query, sqlConnection)) { sqlCommandModifier?.Invoke(sqlCommand); using (var sqlDataReader = await sqlCommand.ExecuteReaderAsync()) { var entries = new List <ExecutionHistoryEntry>(); while (await sqlDataReader.ReadAsync()) { var entry = new ExecutionHistoryEntry(); await HydrateExecutionHistoryEntry(sqlDataReader, entry); entries.Add(entry); } return(entries); } } } }
public async void GetsEntry() { var store = CreateStore(); await store.ClearSchedulerData(); var newEntry = new ExecutionHistoryEntry { ActualFireTimeUtc = DateTime.UtcNow.AddMinutes(1), ScheduledFireTimeUtc = DateTime.UtcNow, FinishedTimeUtc = DateTime.UtcNow.AddMinutes(2), ExceptionMessage = Guid.NewGuid().ToString(), Vetoed = true, Recovering = true, FireInstanceId = Guid.NewGuid().ToString(), Job = Guid.NewGuid().ToString(), SchedulerInstanceId = Guid.NewGuid().ToString(), SchedulerName = SchedulerName, Trigger = Guid.NewGuid().ToString() }; await store.Save(newEntry); var fetchedEntry = await store.Get(newEntry.FireInstanceId); Assert.NotNull(fetchedEntry); Assert.NotEqual(newEntry, fetchedEntry); }
public async Task Save(ExecutionHistoryEntry entry) { if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (_nextPurgeTime < DateTime.UtcNow) { _nextPurgeTime = DateTime.UtcNow.AddMinutes(PurgeIntervalInMinutes); await Purge(); } using (var sqlConnection = new NpgsqlConnection(ConnectionString)) { await sqlConnection.OpenAsync(); string query = $"MERGE {GetTableName(C.TableExecutionHistoryEntries)} AS [Target] \n" + $"USING (SELECT @FireInstanceId AS {C.ColumnFireInstanceId}) AS [Source] \n" + $"ON [Source].{C.ColumnFireInstanceId} = [Target].{C.ColumnFireInstanceId} \n" + $"WHEN MATCHED THEN UPDATE SET \n" + $"{C.ColumnFireInstanceId} = @FireInstanceId, {C.ColumnSchedulerInstanceId} = @SchedulerInstanceId, {C.ColumnSchedulerName} = @SchedulerName, \n" + $"{C.ColumnJob} = @Job, {C.ColumnTrigger} = @Trigger, {C.ColumnScheduledFireTimeUtc} = @ScheduledFireTimeUtc, {C.ColumnActualFireTimeUtc} = @ActualFireTimeUtc, \n" + $"{C.ColumnRecovering} = @Recovering, {C.ColumnVetoed} = @Vetoed, {C.ColumnFinishedTimeUtc} = @FinishedTimeUtc, {C.ColumnExceptionMessage} = @ExceptionMessage \n" + $"WHEN NOT MATCHED THEN INSERT \n" + $"({C.ColumnFireInstanceId}, {C.ColumnSchedulerInstanceId}, {C.ColumnSchedulerName}, \n" + $"{C.ColumnJob}, {C.ColumnTrigger}, {C.ColumnScheduledFireTimeUtc}, {C.ColumnActualFireTimeUtc}, \n" + $"{C.ColumnRecovering}, {C.ColumnVetoed}, {C.ColumnFinishedTimeUtc}, {C.ColumnExceptionMessage}) \n" + $"VALUES (@FireInstanceId, @SchedulerInstanceId, @SchedulerName, @Job, @Trigger, @ScheduledFireTimeUtc, \n" + $"@ActualFireTimeUtc, @Recovering, @Vetoed, @FinishedTimeUtc, @ExceptionMessage);"; using (var sqlCommand = new NpgsqlCommand(query, sqlConnection)) { sqlCommand.Parameters.AddWithValue("@FireInstanceId", entry.FireInstanceId); sqlCommand.Parameters.AddWithValue("@SchedulerInstanceId", entry.SchedulerInstanceId); sqlCommand.Parameters.AddWithValue("@SchedulerName", entry.SchedulerName); sqlCommand.Parameters.AddWithValue("@Job", entry.Job); sqlCommand.Parameters.AddWithValue("@Trigger", entry.Trigger); sqlCommand.Parameters.AddWithValue("@ScheduledFireTimeUtc", entry.ScheduledFireTimeUtc != null ? (object)entry.ScheduledFireTimeUtc : DBNull.Value); sqlCommand.Parameters.AddWithValue("@ActualFireTimeUtc", entry.ActualFireTimeUtc); sqlCommand.Parameters.AddWithValue("@Recovering", entry.Recovering); sqlCommand.Parameters.AddWithValue("@Vetoed", entry.Vetoed); sqlCommand.Parameters.AddWithValue("@FinishedTimeUtc", entry.FinishedTimeUtc != null ? (object)entry.FinishedTimeUtc : DBNull.Value); sqlCommand.Parameters.AddWithValue("@ExceptionMessage", entry.ExceptionMessage != null ? (object)entry.ExceptionMessage : DBNull.Value); await sqlCommand.ExecuteNonQueryAsync(); } } }
public async Task Save(ExecutionHistoryEntry entry) { _updatesFromLastPurge++; if (_updatesFromLastPurge >= 10 || _nextPurgeTime < DateTime.UtcNow) { _nextPurgeTime = DateTime.UtcNow.AddMinutes(1); _updatesFromLastPurge = 0; await Purge(); } lock (_data) { _data[entry.FireInstanceId] = entry; } }
public async void Purges() { var sched = await SetupScheduler(); try { var jobName = "JB" + Guid.NewGuid(); await ScheduleTestJob(sched, jobName : jobName, jobGroup : "TEST"); sched.ListenerManager.AddJobListener(new TestJobListener(), EverythingMatcher <JobKey> .AllJobs()); var resetEvent = new ManualResetEventSlim(); TestJobListener.JobWasExecutedCallback = (c, e) => { resetEvent.Set(); }; var store = CreateStore(); await store.ClearSchedulerData(); var entryToBePurged = new ExecutionHistoryEntry { ActualFireTimeUtc = DateTime.UtcNow.Subtract(TimeSpan.FromDays(100)), FireInstanceId = Guid.NewGuid().ToString(), Job = "TEST.PurgeMe", SchedulerInstanceId = Guid.NewGuid().ToString(), SchedulerName = SchedulerName, Trigger = Guid.NewGuid().ToString() }; await store.Save(entryToBePurged); var lastJobs = await store.FilterLast(2); Assert.Contains(lastJobs, j => j.FireInstanceId == entryToBePurged.FireInstanceId); await sched.Start(); resetEvent.Wait(3 * 1000); Assert.True(resetEvent.IsSet); var newLastJobs = await store.FilterLast(2); Assert.DoesNotContain(newLastJobs, j => j.FireInstanceId == entryToBePurged.FireInstanceId); } finally { await sched.Shutdown(false); } }
public async Task Save(ExecutionHistoryEntry entry) { //_updatesFromLastPurge++; //if (_updatesFromLastPurge >= 10 || _nextPurgeTime < DateTime.UtcNow) //{ // _nextPurgeTime = DateTime.UtcNow.AddMinutes(1); // _updatesFromLastPurge = 0; // await Purge(); //} lock (_data) { _data[entry.FireInstanceId] = entry; } await Task.FromResult(0); }
private void UpdateExecutionHistory() { ushort address = m_execution_control.TVC.CPU.Registers.PC; Z80DisassemblerInstruction instruction; Z80Disassembler disassembler = new Z80Disassembler(); for (int i = 0; i < 2; i++) { ExecutionHistoryEntry history = m_execution_control.ExecutionHistory[i]; if (history.TCycle > 0) { disassembler.ReadByte = history.ReadMemory; instruction = disassembler.Disassemble(history.PC); instruction.TStates = history.TCycle; instruction.TStates2 = 0; } else { instruction = null; } UpdateAddress(instruction, 1 - i); UpdateBytes(instruction, 1 - i); UpdateMnemonics(instruction, 1 - i); UpdateOperand1(instruction, 1 - i); UpdateOperand2(instruction, 1 - i); UpdateTCycle(instruction, 1 - i); } for (int i = 2; i < 5; i++) { instruction = m_disassembler.Disassemble(address); UpdateAddress(instruction, i); UpdateBytes(instruction, i); UpdateMnemonics(instruction, i); UpdateOperand1(instruction, i); UpdateOperand2(instruction, i); UpdateTCycle(instruction, i); address += instruction.Length; } }
private async Task HydrateExecutionHistoryEntry(SqlDataReader sqlDataReader, ExecutionHistoryEntry entry) { var r = sqlDataReader; entry.ActualFireTimeUtc = r.GetDateTime(r.GetOrdinal(C.ColumnActualFireTimeUtc)); entry.ExceptionMessage = await r.IsDBNullAsync(r.GetOrdinal(C.ColumnExceptionMessage)) ? null : r.GetString(r.GetOrdinal(C.ColumnExceptionMessage)); entry.FinishedTimeUtc = await r.IsDBNullAsync(r.GetOrdinal(C.ColumnFinishedTimeUtc)) ? (DateTime?)null : r.GetDateTime(r.GetOrdinal(C.ColumnFinishedTimeUtc)); entry.FireInstanceId = r.GetString(r.GetOrdinal(C.ColumnFireInstanceId)); entry.Job = r.GetString(r.GetOrdinal(C.ColumnJob)); entry.Recovering = r.GetBoolean(r.GetOrdinal(C.ColumnRecovering)); entry.ScheduledFireTimeUtc = await r.IsDBNullAsync(r.GetOrdinal(C.ColumnScheduledFireTimeUtc)) ? (DateTime?)null : r.GetDateTime(r.GetOrdinal(C.ColumnScheduledFireTimeUtc)); entry.SchedulerInstanceId = r.GetString(r.GetOrdinal(C.ColumnSchedulerInstanceId)); entry.SchedulerName = r.GetString(r.GetOrdinal(C.ColumnSchedulerName)); entry.Trigger = r.GetString(r.GetOrdinal(C.ColumnTrigger)); entry.Vetoed = r.GetBoolean(r.GetOrdinal(C.ColumnVetoed)); }
public async void FiltersLast() { var store = CreateStore(); await store.ClearSchedulerData(); var trigger1 = Guid.NewGuid().ToString(); for (int i = 0; i < 5; i++) { var newEntry = new ExecutionHistoryEntry { ActualFireTimeUtc = DateTime.UtcNow.AddMinutes(5 + 4 - i), ScheduledFireTimeUtc = DateTime.UtcNow, FinishedTimeUtc = DateTime.UtcNow.AddMinutes(5), ExceptionMessage = i.ToString(), Vetoed = true, Recovering = true, FireInstanceId = Guid.NewGuid().ToString(), Job = Guid.NewGuid().ToString(), SchedulerInstanceId = Guid.NewGuid().ToString(), SchedulerName = SchedulerName, Trigger = trigger1 }; await store.Save(newEntry); } var trigger2 = Guid.NewGuid().ToString(); for (int i = 0; i < 5; i++) { var newEntry = new ExecutionHistoryEntry { ActualFireTimeUtc = DateTime.UtcNow.AddMinutes(4 - i), ScheduledFireTimeUtc = DateTime.UtcNow, FinishedTimeUtc = DateTime.UtcNow.AddMinutes(5), ExceptionMessage = i.ToString(), Vetoed = true, Recovering = true, FireInstanceId = Guid.NewGuid().ToString(), Job = Guid.NewGuid().ToString(), SchedulerInstanceId = Guid.NewGuid().ToString(), SchedulerName = SchedulerName, Trigger = trigger2 }; await store.Save(newEntry); } var allEntries = await store.FilterLast(8); var trigger1Entries = allEntries .Where(f => f.Trigger == trigger1) .ToList(); Assert.Equal(5, trigger1Entries.Count); Assert.Equal("0", trigger1Entries[0].ExceptionMessage); Assert.Equal("1", trigger1Entries[1].ExceptionMessage); Assert.Equal("2", trigger1Entries[2].ExceptionMessage); Assert.Equal("3", trigger1Entries[3].ExceptionMessage); Assert.Equal("4", trigger1Entries[4].ExceptionMessage); var trigger2Entries = allEntries .Where(f => f.Trigger == trigger2) .ToList(); Assert.Equal(3, trigger2Entries.Count); Assert.Equal("0", trigger2Entries[0].ExceptionMessage); Assert.Equal("1", trigger2Entries[1].ExceptionMessage); Assert.Equal("2", trigger2Entries[2].ExceptionMessage); }
public Task Save(ExecutionHistoryEntry entry) { _histories.Upsert(entry); return(Task.FromResult(0)); }