async def test_misuse(self): with pytest.raises(ValueError): async for _ in delay(-1): pass with pytest.raises(ValueError): async for _ in interval(-1): pass
async def run(self): async with Scope() as scope: scope.do(self._collect_jobs()) async for _ in interval(self.interval): for job in self.job_queue.copy(): best_match = self._schedule_job(job) if best_match: await best_match.schedule_job(job) self.job_queue.remove(job) await sampling_required.put(self.job_queue) await sampling_required.put(UserDemand(len(self.job_queue))) self.unregister_drone(best_match) left_resources = best_match.theoretical_available_resources left_resources = { key: value - job.resources.get(key, 0) for key, value in left_resources.items() } self._add_drone(best_match, left_resources) if ( not self._collecting and not self.job_queue and self._processing.levels.jobs == 0 ): break await sampling_required.put(self)
async def run(self): """ Pool periodically checks the current demand and provided drones. If demand is higher than the current level, the pool takes care of initialising new drones. Otherwise drones get removed. """ async with Scope() as scope: await self.init_pool(scope=scope, init=self._level) async for _ in interval(1): drones_required = min(self._demand, self._capacity) - self._level while drones_required > 0: drones_required -= 1 # start a new drone drone = self.make_drone(10) scope.do(drone.run()) self._drones.append(drone) self._level += 1 if drones_required < 0: for drone in self.drones: if drone.jobs == 0: drones_required += 1 self._level -= 1 self._drones.remove(drone) scope.do(drone.shutdown()) if drones_required == 0: break
async def test_for_interval(): expected_time = 5 async with until(time == 60): async for _ in interval(5): assert time.now == expected_time expected_time += 5 assert time.now == 60
async def test_interval_exceeded(self): """It is an error to exceed an interval""" try: async for _ in interval(20): await (time + 40) except IntervalExceeded: assert True else: assert False
async def test_interval(self): start, iteration = time.now, 1 async for now in interval(20): await (time + 5) assert time.now - now == 5 assert time.now == start + iteration * 20 + 5 if iteration == 5: break iteration += 1
async def test_interval_exact(self): """It is not an error to exactly match an interval""" try: async for idx, _ in aenumerate(interval(20)): await (time + 20) if idx == 5: break except IntervalExceeded: assert False else: assert True
async def run(self): """ Runs the scheduler's functionality. One executed, the scheduler starts up and begins to add the jobs that are :return: """ async with Scope() as scope: scope.do(self._collect_jobs()) async for _ in interval(self.interval): await self._schedule_jobs() if (not self._collecting and not self.job_queue and self._processing.levels.jobs == 0): break