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); } }
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(); } } }