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