class Service(SimulatedEntity): def __init__(self, name, environment): super().__init__(name, environment) self.environment.define(Symbols.SELF, self) self.environment.define(Symbols.SERVICE, self) self.tasks = self.environment.look_up(Symbols.QUEUE) self.workers = WorkerPool([self._new_worker(id) for id in range(1, 2)]) def _new_worker(self, identifier): environment = self.environment.create_local_environment() environment.define(Symbols.SERVICE, self) return Worker(identifier, environment) @property def worker_count(self): return self.workers.capacity def set_worker_count(self, capacity): error = self.workers.capacity - capacity if error < 0: new_workers = [self._new_worker(id) for id in range(-error)] self.workers.add_workers(new_workers) elif error > 0: self.workers.shutdown(error) @property def utilisation(self): return self.workers.utilisation def process(self, request): self.listener.arrival_of(request) task = Task(request) if self.workers.are_available: request.accept() worker = self.workers.acquire_one() worker.assign(task) else: self.tasks.put(task) def release(self, worker): if self.tasks.are_pending: task = self.tasks.take() worker.assign(task) else: self.workers.release(worker) def activate(self, task): if self.workers.are_available: worker = self.workers.acquire_one() self.tasks.intercept(task) worker.assign(task) else: self.tasks.activate(task) def pause(self, task): self.tasks.pause(task)
def test_utilisation(self): pool = WorkerPool(["w1", "w2", "w3", "w4"]) self.assertAlmostEqual(pool.utilisation, float(0)) wA = pool.acquire_one() wB = pool.acquire_one() self.assertAlmostEqual(pool.utilisation, float(100 * 2 / 4)) pool.add_workers(["w5", "w6"]) self.assertAlmostEqual(pool.utilisation, float(100 * 2 / 6)) pool.release(wB) self.assertAlmostEqual(pool.utilisation, float(100 * 1 / 6)) pool.shutdown(4) self.assertAlmostEqual(pool.utilisation, float(100 * 1 / 2))
def test_shutting_down_busy_workers(self): pool = WorkerPool(["w1", "w2", "w3", "w4"]) w1 = pool.acquire_one() w2 = pool.acquire_one() # pool.idle = ["w3", "w4" ] ; capacity = 4 pool.shutdown(3) self.assertEqual(0, pool.idle_worker_count) self.assertEqual(1, pool.capacity) self.assertTrue(w1 in pool.stopped_workers) pool.release(w1) self.assertEqual(0, pool.idle_worker_count) self.assertEqual(1, pool.capacity) pool.release(w2) self.assertEqual(1, pool.idle_worker_count) self.assertEqual(1, pool.capacity)
def test_shutting_down_only_idle_workers(self): pool = WorkerPool(["w1", "w2", "w3", "w4"]) pool.shutdown(3) self.assertEqual(1, pool.capacity) self.assertEqual(1, pool.idle_worker_count)