def test_scheduler(): scheduler = Scheduler("scheduler") assert scheduler.get_services_count() == 0 assert scheduler.get_state() == BaseStates.Idle scheduler.start() assert scheduler.get_state() == BaseStates.Starting scheduler.stop() assert scheduler.get_state() == BaseStates.Stopped scheduler.add_service(TestWorker("test-worker-1")) assert scheduler.get_services_count() == 1 scheduler.add_service(TestWorker("test-worker-2")) assert scheduler.get_services_count() == 2
class CannedOS(BaseService): """ OS -> Scheduler -> ServiceManager -> DirectoryService -> UserService There is an operating system defined as OS. The OS runs a scheduler service named Scheduler, which runs core services. An example core service is the ServiceManager. ServiceManager serves to manage services, but interaction with it is through the scheduler. A custom service which is started by the ServiceManager is a service catalogue named DirectoryService. All services are registered with it and other services can find each other with the directory. Starting and stopping of services are done by the ServiceManager. The end user when adding user services uses the OS level method schedule(). Remember that all services are stored with the directory service. User services however are named as a child of the OS, rather than a named child of the fully qualified hierarchy. The only place where a full name hierarchy is retained is with the core services (scheduler, service manager, and directory service). """ def __init__(self, name): BaseService.__init__(self, name) self.scheduler = Scheduler("scheduler", parent_logger=self.log) def bootup(self): """ Boots up the OS and any services which the scheduler has scheduled. :return: """ self.log.info("booting up...") self.scheduler.start() self.set_directory_service_proxy(self.scheduler.get_directory_service_proxy()) self.start() # start self, as an executor service runs one pass and registers as successful def shutdown(self): if self.is_stopping() or self.has_stopped(): self.log.warn("service has already received command to stop, ignoring additional request...") else: self.log.info("shutting down...") self.scheduler.stop() self.stop() def schedule_service(self, service_class, service_meta, error_handlers=[]): """ Take a service and let the instaniation begin here. :param service_class: python class to use :param service_meta: metadata about the service :param error_handlers: a list of error handlers which to execute :return: """ service = service_class(service_meta.alias, parent_logger=self.log) service.add_error_handlers(error_handlers) self.scheduler.add_service_with_meta(service, service_meta) def schedule_provided_service(self, service): """ SOON TO BE DEPRECATED. Take a service and schedules it as-is. Prefer not to use this method. :param service: :return: """ self.scheduler.add_service(service)
class CannedOS(BaseService): """ OS -> Scheduler -> ServiceManager -> DirectoryService -> UserService There is an operating system defined as OS. The OS runs a scheduler service named Scheduler, which runs core services. An example core service is the ServiceManager. ServiceManager serves to manage services, but interaction with it is through the scheduler. A custom service which is started by the ServiceManager is a service catalogue named DirectoryService. All services are registered with it and other services can find each other with the directory. Starting and stopping of services are done by the ServiceManager. The end user when adding user services uses the OS level method schedule(). Remember that all services are stored with the directory service. User services however are named as a child of the OS, rather than a named child of the fully qualified hierarchy. The only place where a full name hierarchy is retained is with the core services (scheduler, service manager, and directory service). """ def __init__(self, name): BaseService.__init__(self, name) self.scheduler = Scheduler("scheduler", parent_logger=self.log) def bootup(self): """ Boots up the OS and any services which the scheduler has scheduled. :return: """ self.log.info("booting up...") self.scheduler.start() self.set_directory_service_proxy( self.scheduler.get_directory_service_proxy()) self.start( ) # start self, as an executor service runs one pass and registers as successful def shutdown(self): if self.is_stopping() or self.has_stopped(): self.log.warn( "service has already received command to stop, ignoring additional request..." ) else: self.log.info("shutting down...") self.scheduler.stop() self.stop() def schedule_service(self, service_class, service_meta, error_handlers=[]): """ Take a service and let the instaniation begin here. :param service_class: python class to use :param service_meta: metadata about the service :param error_handlers: a list of error handlers which to execute :return: """ service = service_class(service_meta.alias, parent_logger=self.log) service.add_error_handlers(error_handlers) self.scheduler.add_service_with_meta(service, service_meta) def schedule_provided_service(self, service): """ SOON TO BE DEPRECATED. Take a service and schedules it as-is. Prefer not to use this method. :param service: :return: """ self.scheduler.add_service(service)
def test_os(): """ At this point we've tested BaseService, so I expect the following to work. Note: It is now prudent to leave this test or slowly invalidate it and instead use the CannedOS. See `v2/services/freezer_services_test.py` as an example :return: """ scheduler = Scheduler("scheduler") # create services test_worker_1 = TestWorker("test-worker-1", worker_interval) test_worker_2 = TestWorker("test-worker-2", worker_interval) mock_queue_service = MockQueuedService() # schedule services scheduler.add_service(test_worker_1) scheduler.add_service(test_worker_2) scheduler.add_service(mock_queue_service) assert scheduler.get_services_count() == 3 # test for existence of a service manager assert scheduler.get_service_manager() is not None # test that a child worker has access to the service_manager proxy test_worker_1_service = scheduler.get_service_manager( ).get_directory_service_proxy().get_service("test-worker-1") assert test_worker_1_service is not None # assert that the service is exactly as what was started assert test_worker_1_service == test_worker_1 # assert that the service has a reference to the directory proxy directory_proxy = test_worker_1.get_directory_service_proxy() assert directory_proxy is not None assert directory_proxy.get_service_count() == 3 # assert all the same all around assert directory_proxy.get_service( "test-worker-1") == test_worker_1_service # direct check to make sure assert directory_proxy._service_manager_directory == scheduler.get_service_manager( ).service_directory # start test timer timer = Timer(scheduler, mock_output_pid=mock_queue_service) # take timing from start to finish t1 = time.time() gevent.joinall([scheduler.start(), timer.start()]) # blocks t2 = time.time() t3 = t2 - t1 assert t3 > scheduler_interval # stop was called, check all states assert scheduler.get_service_manager().get_state() == BaseStates.Stopped assert scheduler.get_state() == BaseStates.Stopped for pid_key, pid in scheduler.get_services(): assert pid.get_state() == BaseStates.Stopped