public void WorkerDequeue() { IJob job = new TestJob() { Id = Guid.NewGuid() }; SignalsRecord signals = new SignalsRecord() { QueueNames = "*", WorkerSignal = WorkerSignal.None, WorkingSignal = WorkingSignal.None }; QueueRecord queued = new QueueRecord() { Id = 12, ApplicationName = BlueCollarSection.Section.ApplicationName, Data = JsonConvert.SerializeObject(job), JobName = job.Name, JobType = JobSerializer.GetTypeName(job.GetType()), QueuedOn = DateTime.UtcNow, QueueName = "*", TryNumber = 1 }; var transaction = new Mock<IDbTransaction>(); var repository = new Mock<IRepository>(); repository.Setup(r => r.BeginTransaction()).Returns(transaction.Object); repository.Setup(r => r.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(transaction.Object); repository.Setup(r => r.GetQueued(It.IsAny<string>(), It.IsAny<QueueNameFilters>(), It.IsAny<DateTime>(), It.IsAny<IDbTransaction>())).Returns(queued); repository.Setup(r => r.GetWorkingSignals(It.IsAny<long>(), It.IsAny<long?>(), It.IsAny<IDbTransaction>())).Returns(signals); var factory = new Mock<IRepositoryFactory>(); factory.Setup(f => f.Create()).Returns(repository.Object); var logger = new Mock<ILogger>(); using (Worker worker = new Worker(BlueCollarSection.Section.ApplicationName, 1, "Test Worker", null, 1, false, factory.Object, logger.Object)) { worker.Start(); Thread.Sleep(1500); } repository.Verify(r => r.GetQueued(BlueCollarSection.Section.ApplicationName, It.IsAny<QueueNameFilters>(), It.IsAny<DateTime>(), It.IsAny<IDbTransaction>())); repository.Verify(r => r.DeleteQueued(12, It.IsAny<IDbTransaction>())); repository.Verify(r => r.CreateWorking(It.Is<WorkingRecord>(w => w.ApplicationName == BlueCollarSection.Section.ApplicationName && w.WorkerId == 1), It.IsAny<IDbTransaction>())); }
internal void RefreshWorkers() { List<WorkerRecord> records; using (IRepository repository = this.repositoryFactory.Create()) { records = repository.GetWorkers(this.applicationName, this.address, this.name, null).ToList(); this.logger.Debug( "Machine {0} ({1}) loaded {2} worker records from repository '{3}', using connection string '{4}'.", this.name, this.address, records.Count, repository.GetType().ToString(), repository.ConnectionString); } lock (this) { List<Worker> newWorkers = new List<Worker>(); List<Worker> removeWorkers = new List<Worker>(); // Figure out which of the current workers get to stay alive. foreach (Worker worker in this.workers) { WorkerRecord record = records.Where(r => r.Id == worker.Id).FirstOrDefault(); if (record != null) { newWorkers.Add(worker); records.Remove(record); } else { removeWorkers.Add(worker); } } // Prune orphaned current workers. foreach (Worker worker in removeWorkers) { try { worker.Dispose(); } catch (Exception ex) { this.logger.Error(ex); } } // Create workers for all of the new records. Records corresponding // to existing workers where pruned earlier. foreach (WorkerRecord record in records) { Worker worker = null; try { worker = new Worker( this.applicationName, record.Id.Value, record.Name, QueueNameFilters.Parse(record.QueueNames), this.workerHeartbeat, this.schedulerEnabled, this.repositoryFactory, this.logger); newWorkers.Add(worker); if (record.Status == WorkerStatus.Working || record.Startup == WorkerStartupType.Automatic) { worker.Start(); } } catch (Exception ex) { if (worker != null) { newWorkers.Remove(worker); worker.Dispose(); } this.logger.Error(ex); } } // Ensure a default worker if necessary. if (newWorkers.Count == 0 && this.ensureDefaultWorker) { Worker worker = this.CreateDefaultWorker(); newWorkers.Add(worker); worker.Start(); } this.workers = newWorkers; this.logger.Debug("Machine {0} ({1}) refreshed its worker list and is now tracking {2} workers.", this.name, this.address, this.workers.Count); } }
public void WorkerDispose() { IJob job = new TestJob() { Id = Guid.NewGuid() }; SignalsRecord signals = new SignalsRecord() { QueueNames = "*", WorkerSignal = WorkerSignal.None, WorkingSignal = WorkingSignal.None }; QueueRecord queued = new QueueRecord() { Id = 12, ApplicationName = BlueCollarSection.Section.ApplicationName, Data = JsonConvert.SerializeObject(job), JobName = job.Name, JobType = JobSerializer.GetTypeName(job.GetType()), QueuedOn = DateTime.UtcNow, QueueName = "*", TryNumber = 1 }; var transaction = new Mock<IDbTransaction>(); var repository = new Mock<IRepository>(); repository.Setup(r => r.BeginTransaction()).Returns(transaction.Object); repository.Setup(r => r.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(transaction.Object); repository.Setup(r => r.GetQueued(It.IsAny<string>(), It.IsAny<QueueNameFilters>(), It.IsAny<DateTime>(), It.IsAny<IDbTransaction>())).Returns(queued); repository.Setup(r => r.GetWorkingSignals(It.IsAny<long>(), It.IsAny<long?>(), It.IsAny<IDbTransaction>())).Returns(signals); var factory = new Mock<IRepositoryFactory>(); factory.Setup(f => f.Create()).Returns(repository.Object); var logger = new Mock<ILogger>(); Worker worker = null; try { worker = new Worker(BlueCollarSection.Section.ApplicationName, 1, "Test Worker", null, 1, false, factory.Object, logger.Object); worker.Start(); Thread.Sleep(1500); worker.Stop(false); worker.Dispose(); Assert.IsFalse(worker.LoopThreadsAreAlive); worker = null; } finally { if (worker != null) { worker.Dispose(); } } }
public void WorkerStop() { var transaction = new Mock<IDbTransaction>(); var repository = new Mock<IRepository>(); repository.Setup(r => r.BeginTransaction()).Returns(transaction.Object); repository.Setup(r => r.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(transaction.Object); var factory = new Mock<IRepositoryFactory>(); factory.Setup(f => f.Create()).Returns(repository.Object); var logger = new Mock<ILogger>(); using (Worker worker = new Worker(BlueCollarSection.Section.ApplicationName, 1, "Test Worker", null, 1, false, factory.Object, logger.Object)) { worker.Start(); worker.Stop(false); Thread.Sleep(1); Assert.AreEqual(WorkerStatus.Stopped, worker.Status); } }
public void WorkerRefreshSchedulesWithSignal() { SignalsRecord signals = new SignalsRecord() { QueueNames = "*", WorkerSignal = WorkerSignal.None, WorkingSignal = WorkingSignal.None }; var transaction = new Mock<IDbTransaction>(); var repository = new Mock<IRepository>(); repository.Setup(r => r.BeginTransaction()).Returns(transaction.Object); repository.Setup(r => r.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(transaction.Object); repository.Setup(r => r.GetWorkingSignals(It.IsAny<long>(), It.IsAny<long?>(), It.IsAny<IDbTransaction>())).Returns(signals); var factory = new Mock<IRepositoryFactory>(); factory.Setup(f => f.Create()).Returns(repository.Object); var logger = new Mock<ILogger>(); var scheduler = new Mock<IScheduler>(); using (Worker worker = new Worker(BlueCollarSection.Section.ApplicationName, 1, "Test Worker", null, 1, true, factory.Object, logger.Object, scheduler.Object)) { worker.Start(); signals.WorkerSignal = WorkerSignal.RefreshSchedules; Thread.Sleep(1500); } scheduler.Verify(s => s.RefreshSchedules(), Times.AtLeastOnce()); }
public void WorkerExecuteTimeout() { IJob job = new TestJob() { SleepDuration = 100, Timeout = 10 }; SignalsRecord signals = new SignalsRecord() { QueueNames = "*", WorkerSignal = WorkerSignal.None, WorkingSignal = WorkingSignal.None }; QueueRecord queued = new QueueRecord() { Id = 12, ApplicationName = BlueCollarSection.Section.ApplicationName, Data = JsonConvert.SerializeObject(job), JobName = job.Name, JobType = JobSerializer.GetTypeName(job.GetType()), QueuedOn = DateTime.UtcNow, QueueName = "*", TryNumber = 1 }; WorkingRecord working = Worker.CreateWorking(queued, 1, null, DateTime.UtcNow); working.Id = 13; var transaction = new Mock<IDbTransaction>(); var repository = new Mock<IRepository>(); repository.Setup(r => r.BeginTransaction()).Returns(transaction.Object); repository.Setup(r => r.BeginTransaction(It.IsAny<IsolationLevel>())).Returns(transaction.Object); repository.Setup(r => r.CreateWorking(It.IsAny<WorkingRecord>(), It.IsAny<IDbTransaction>())).Returns(working); repository.Setup(r => r.GetQueued(It.IsAny<string>(), It.IsAny<QueueNameFilters>(), It.IsAny<DateTime>(), It.IsAny<IDbTransaction>())).Returns(queued); repository.Setup(r => r.GetWorkingSignals(It.IsAny<long>(), It.IsAny<long?>(), It.IsAny<IDbTransaction>())).Returns(signals); var factory = new Mock<IRepositoryFactory>(); factory.Setup(f => f.Create()).Returns(repository.Object); var logger = new Mock<ILogger>(); using (Worker worker = new Worker(BlueCollarSection.Section.ApplicationName, 1, "Test Worker", null, 1, false, factory.Object, logger.Object)) { worker.Start(); Thread.Sleep(1500); } repository.Verify(r => r.CreateHistory(It.Is<HistoryRecord>(h => h.Status == HistoryStatus.TimedOut), It.IsAny<IDbTransaction>())); }