def __init__(self, vpn_service, host): super(VyattaIPSecDriver, self).__init__(vpn_service, host) self.vpn_service = vpn_service self.host = host # register RPC endpoint conn = n_rpc.create_connection() node_topic = '%s.%s' % (topics.BROCADE_IPSEC_AGENT_TOPIC, self.host) endpoints = [self.rpc_endpoint_factory(self)] conn.create_consumer(node_topic, endpoints, fanout=False) conn.consume_in_threads() # initialize agent to server RPC link self.server_api = NeutronServerAPI( topics.BROCADE_IPSEC_DRIVER_TOPIC) # initialize VPN service cache (to keep service state) self._svc_cache = list() self._router_resources_cache = dict() # setup periodic task. All periodic task require fully configured # device driver. It will be called asynchronously, and soon, so it # should be last, when all configuration is done. self._periodic_tasks = periodic = _VyattaPeriodicTasks(self) loop = loopingcall.DynamicLoopingCall(periodic) loop.start(initial_delay=5)
def _start_recover_consuming_task(self): """Start async job for checking connection to the broker.""" if self._recover_loopingcall is None and self._started: self._recover_loopingcall = (loopingcall.DynamicLoopingCall( self._try_recover_consuming)) LOG.info("Starting recover consuming job for listener: %s", self) self._recover_loopingcall.start()
def test_initial_delay(self, sleep_mock): self.num_runs = 1 timer = loopingcall.DynamicLoopingCall(self._wait_for_zero) timer.start(initial_delay=3).wait() sleep_mock.assert_has_calls([mock.call(3), mock.call(1)])
def test_timeout_task_without_return(self, sleep_mock): self.num_runs = 1 timer = loopingcall.DynamicLoopingCall( self._timeout_task_without_return_but_with_done ) timer.start(periodic_interval_max=5).wait() sleep_mock.assert_has_calls([mock.call(5)])
def test_interval_adjustment(self, sleep_mock): self.num_runs = 2 timer = loopingcall.DynamicLoopingCall(self._wait_for_zero) timer.start(periodic_interval_max=5).wait() sleep_mock.assert_has_calls([mock.call(5), mock.call(1)])
def add_dynamic_timer(self, callback, initial_delay=None, periodic_interval_max=None, *args, **kwargs): timer = loopingcall.DynamicLoopingCall(callback, *args, **kwargs) timer.start(initial_delay=initial_delay, periodic_interval_max=periodic_interval_max) self.timers.append(timer) return timer
def test_monotonic_timer(self): def _raise_it(): clock = eventlet.hubs.get_hub().clock ok = (clock == oslo_service._monotonic) raise loopingcall.LoopingCallDone(ok) timer = loopingcall.DynamicLoopingCall(_raise_it) self.assertTrue(timer.start().wait())
def _init_endpoints(self, providers, min_conns_per_pool, max_conns_per_pool): LOG.debug("Initializing API endpoints") def _create_conn(p): def _conn(): # called when a pool needs to create a new connection try: return self._http_provider.new_connection(self, p) except Exception as e: if self._http_provider.is_conn_open_exception(e): LOG.warning( "Timeout while trying to open a " "connection with %s", p) return _conn self._endpoints = {} for provider in providers: pool = pools.Pool(min_size=min_conns_per_pool, max_size=max_conns_per_pool, order_as_stack=True, create=_create_conn(provider)) endpoint = Endpoint(provider, pool) self._endpoints[provider.id] = endpoint # service requests using round robin self._endpoint_schedule = itertools.cycle(self._endpoints.values()) # duck type to proxy http invocations for method in ClusteredAPI._HTTP_VERBS: setattr(self, method, self._proxy_stub(method)) conns = greenpool.GreenPool() for endpoint in self._endpoints.values(): conns.spawn(self._validate, endpoint) eventlet.sleep(0) while conns.running(): if (self.health == ClusterHealth.GREEN or self.health == ClusterHealth.ORANGE): # only wait for 1 or more endpoints to reduce init time break eventlet.sleep(0.5) for endpoint in self._endpoints.values(): # dynamic loop for each endpoint to ensure connectivity loop = loopingcall.DynamicLoopingCall(self._endpoint_keepalive, endpoint) loop.start(initial_delay=self._keepalive_interval, periodic_interval_max=self._keepalive_interval, stop_on_exception=False) LOG.debug( "Done initializing API endpoint(s). " "API cluster health: %s", self.health)
def _start_loopingcall(min_chunk_size, state_sync_interval, func, initial_delay=5): """Start a loopingcall for the synchronization task.""" # Start a looping call to synchronize operational status # for neutron resources if not state_sync_interval: # do not start the looping call if specified # sync interval is 0 return state_synchronizer = loopingcall.DynamicLoopingCall( func, sp=SyncParameters(min_chunk_size)) state_synchronizer.start( initial_delay=initial_delay, periodic_interval_max=state_sync_interval) return state_synchronizer
def test_no_double_start(self): wait_ev = greenthreading.Event() def _run_forever_until_set(): if wait_ev.is_set(): raise loopingcall.LoopingCallDone(True) else: return 0.01 timer = loopingcall.DynamicLoopingCall(_run_forever_until_set) timer.start() self.assertRaises(RuntimeError, timer.start) wait_ev.set() timer.wait()
def add_dynamic_timer_args(self, callback, args=None, kwargs=None, initial_delay=None, periodic_interval_max=None, stop_on_exception=True): """Add a timer that controls its own period dynamically. The period of each iteration of the timer is controlled by the return value of the callback function on the previous iteration. :param callback: The callback function to run when the timer is triggered. :param args: A list of positional args to the callback function. :param kwargs: A dict of keyword args to the callback function. :param initial_delay: The delay in seconds before first triggering the timer. If not set, the timer is liable to be scheduled immediately. :param periodic_interval_max: The maximum interval in seconds to allow the callback function to request. If provided, this is also used as the default delay if None is returned by the callback function. :param stop_on_exception: Pass ``False`` to have the timer continue running even if the callback function raises an exception. :returns: an :class:`oslo_service.loopingcall.DynamicLoopingCall` instance """ args = args or [] kwargs = kwargs or {} timer = loopingcall.DynamicLoopingCall(callback, *args, **kwargs) timer.start(initial_delay=initial_delay, periodic_interval_max=periodic_interval_max, stop_on_exception=stop_on_exception) self.timers.append(timer) return timer
def test_terminate_on_exception(self): def _raise_it(): raise RuntimeError() timer = loopingcall.DynamicLoopingCall(_raise_it) self.assertRaises(RuntimeError, timer.start().wait)
def __init__(self, api_nb, listener): self.api_nb = api_nb self.listener = listener # We delay a random time to avoid a periodical peak of network # throughput and pressure for df-db in a big scale self._loopingcall = loopingcall.DynamicLoopingCall(self.run)
def test_timeout_task_without_return_and_max_periodic(self): timer = loopingcall.DynamicLoopingCall( self._timeout_task_without_any_return ) self.assertRaises(RuntimeError, timer.start().wait)
def test_repeat(self): self.num_runs = 2 timer = loopingcall.DynamicLoopingCall(self._wait_for_zero) self.assertFalse(timer.start().wait())
def test_do_not_stop_on_exception(self): self.num_runs = 2 timer = loopingcall.DynamicLoopingCall(self._raise_and_then_done) timer.start(stop_on_exception=False).wait()
def test_return_false(self): def _raise_it(): raise loopingcall.LoopingCallDone(False) timer = loopingcall.DynamicLoopingCall(_raise_it) self.assertFalse(timer.start().wait())
def _set_and_wait(target_state, driver_info): """Helper function for DynamicLoopingCall. This method changes the power state and polls the BMCuntil the desired power state is reached, or CONF.ipmi.retry_timeout would be exceeded by the next iteration. This method assumes the caller knows the current power state and does not check it prior to changing the power state. Most BMCs should be fine, but if a driver is concerned, the state should be checked prior to calling this method. :param target_state: desired power state :param driver_info: the ipmitool parameters for accessing a node. :returns: one of ironic.common.states """ if target_state == states.POWER_ON: state_name = "on" elif target_state == states.POWER_OFF: state_name = "off" def _wait(mutable): try: # Only issue power change command once if mutable['iter'] < 0: _exec_ipmitool(driver_info, "power %s" % state_name) else: mutable['power'] = _power_status(driver_info) except (exception.PasswordFileFailedToCreate, processutils.ProcessExecutionError, exception.IPMIFailure): # Log failures but keep trying LOG.warning(_LW("IPMI power %(state)s failed for node %(node)s."), { 'state': state_name, 'node': driver_info['uuid'] }) finally: mutable['iter'] += 1 if mutable['power'] == target_state: raise loopingcall.LoopingCallDone() sleep_time = _sleep_time(mutable['iter']) if (sleep_time + mutable['total_time']) > CONF.ipmi.retry_timeout: # Stop if the next loop would exceed maximum retry_timeout LOG.error( _LE('IPMI power %(state)s timed out after ' '%(tries)s retries on node %(node_id)s.'), { 'state': state_name, 'tries': mutable['iter'], 'node_id': driver_info['uuid'] }) mutable['power'] = states.ERROR raise loopingcall.LoopingCallDone() else: mutable['total_time'] += sleep_time return sleep_time # Use mutable objects so the looped method can change them. # Start 'iter' from -1 so that the first two checks are one second apart. status = {'power': None, 'iter': -1, 'total_time': 0} timer = loopingcall.DynamicLoopingCall(_wait, status) timer.start().wait() return status['power']