def sync_pending_row(self, exit_after_run=False): # Block until all pending rows are processed session = neutron_db_api.get_session() while not self.event.is_set(): self.event.wait() # Clear the event and go back to waiting after # the sync block exits self.event.clear() while True: LOG.debug("Thread walking database") row = db.get_oldest_pending_db_row_with_lock(session) if not row: LOG.debug("No rows to sync") break # Validate the operation validate_func = db.VALIDATION_MAP[row.object_type] valid = validate_func(session, row.object_uuid, row.operation, row.data) if not valid: LOG.info( _LI("%(operation)s %(type)s %(uuid)s is not a " "valid operation yet, skipping for now"), {"operation": row.operation, "type": row.object_type, "uuid": row.object_uuid}, ) continue LOG.info( _LI("Syncing %(operation)s %(type)s %(uuid)s"), {"operation": row.operation, "type": row.object_type, "uuid": row.object_uuid}, ) # Add code to sync this to ODL method, urlpath, to_send = self._json_data(row) try: self.client.sendjson(method, urlpath, to_send) db.update_processing_db_row_passed(session, row) except exceptions.ConnectionError as e: # Don't raise the retry count, just log an error LOG.error(_LE("Cannot connect to the Opendaylight " "Controller")) # Set row back to pending db.update_db_row_pending(session, row) # Break our of the loop and retry with the next # timer interval break except Exception as e: LOG.error( _LE("Error syncing %(type)s %(operation)s," " id %(uuid)s Error: %(error)s"), { "type": row.object_type, "uuid": row.object_uuid, "operation": row.operation, "error": e.message, }, ) db.update_pending_db_row_retry(session, row, self._row_retry_count) LOG.debug("Clearing sync thread event") if exit_after_run: # Permanently waiting thread model breaks unit tests # Adding this arg to exit here only for unit tests break
def _sync_pending_rows(self, session, exit_after_run): while True: LOG.debug("Thread walking database") row = db.get_oldest_pending_db_row_with_lock(session) if not row: LOG.debug("No rows to sync") break # Validate the operation validate_func = ( dependency_validations.VALIDATION_MAP[row.object_type]) valid = validate_func(session, row) if not valid: LOG.info( _LI("%(operation)s %(type)s %(uuid)s is not a " "valid operation yet, skipping for now"), { 'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid }) # Set row back to pending. db.update_db_row_state(session, row, odl_const.PENDING) if exit_after_run: break continue LOG.info( _LI("Syncing %(operation)s %(type)s %(uuid)s"), { 'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid }) # Add code to sync this to ODL method, urlpath, to_send = self._json_data(row) try: self.client.sendjson(method, urlpath, to_send) db.update_db_row_state(session, row, odl_const.COMPLETED) except exceptions.ConnectionError as e: # Don't raise the retry count, just log an error LOG.error(_LE("Cannot connect to the Opendaylight Controller")) # Set row back to pending db.update_db_row_state(session, row, odl_const.PENDING) # Break our of the loop and retry with the next # timer interval break except Exception as e: LOG.error( _LE("Error syncing %(type)s %(operation)s," " id %(uuid)s Error: %(error)s"), { 'type': row.object_type, 'uuid': row.object_uuid, 'operation': row.operation, 'error': e.message }) db.update_pending_db_row_retry(session, row, self._row_retry_count)
def _sync_pending_rows(self, session, exit_after_run): while True: LOG.debug("Thread walking database") row = db.get_oldest_pending_db_row_with_lock(session) if not row: LOG.debug("No rows to sync") break # Validate the operation validate_func = (dependency_validations. VALIDATION_MAP[row.object_type]) valid = validate_func(session, row) if not valid: LOG.info(_LI("%(operation)s %(type)s %(uuid)s is not a " "valid operation yet, skipping for now"), {'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid}) # Set row back to pending. db.update_db_row_state(session, row, odl_const.PENDING) if exit_after_run: break continue LOG.info(_LI("Syncing %(operation)s %(type)s %(uuid)s"), {'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid}) # Add code to sync this to ODL method, urlpath, to_send = self._json_data(row) try: self.client.sendjson(method, urlpath, to_send) db.update_db_row_state(session, row, odl_const.COMPLETED) except exceptions.ConnectionError as e: # Don't raise the retry count, just log an error LOG.error(_LE("Cannot connect to the Opendaylight Controller")) # Set row back to pending db.update_db_row_state(session, row, odl_const.PENDING) # Break our of the loop and retry with the next # timer interval break except Exception as e: LOG.error(_LE("Error syncing %(type)s %(operation)s," " id %(uuid)s Error: %(error)s"), {'type': row.object_type, 'uuid': row.object_uuid, 'operation': row.operation, 'error': e.message}) db.update_pending_db_row_retry(session, row, self._row_retry_count)
def _test_retry_count(self, retry_num, max_retry, expected_retry_count, expected_state): # add new pending row db.create_pending_row(self.db_session, *self.UPDATE_ROW) # update the row with the requested retry_num row = db.get_all_db_rows(self.db_session)[0] row.retry_count = retry_num - 1 db.update_pending_db_row_retry(self.db_session, row, max_retry) # validate the state and the retry_count of the row row = db.get_all_db_rows(self.db_session)[0] self.assertEqual(expected_state, row.state) self.assertEqual(expected_retry_count, row.retry_count)
def _test_retry_count(self, retry_num, max_retry, expected_retry_count, expected_state): # add new pending row db.create_pending_row(self.db_context, *self.UPDATE_ROW) # update the row with the requested retry_num row = db.get_all_db_rows(self.db_context)[0] row.retry_count = retry_num - 1 db.update_pending_db_row_retry(self.db_context, row, max_retry) # validate the state and the retry_count of the row row = db.get_all_db_rows(self.db_context)[0] self.assertEqual(expected_state, row.state) self.assertEqual(expected_retry_count, row.retry_count)
def _sync_pending_entries(self, session, exit_after_run): LOG.debug("Start processing journal entries") entry = db.get_oldest_pending_db_row_with_lock(session) if entry is None: LOG.debug("No journal entries to process") return while entry is not None: log_dict = { 'op': entry.operation, 'type': entry.object_type, 'id': entry.object_uuid } valid = dependency_validations.validate(session, entry) if not valid: db.update_db_row_state(session, entry, odl_const.PENDING) LOG.info( "Skipping %(op)s %(type)s %(id)s due to " "unprocessed dependencies.", log_dict) if exit_after_run: break continue LOG.info("Processing - %(op)s %(type)s %(id)s", log_dict) method, urlpath, to_send = self._json_data(entry) try: self.client.sendjson(method, urlpath, to_send) db.update_db_row_state(session, entry, odl_const.COMPLETED) except exceptions.ConnectionError as e: # Don't raise the retry count, just log an error & break db.update_db_row_state(session, entry, odl_const.PENDING) LOG.error("Cannot connect to the OpenDaylight Controller," " will not process additional entries") break except Exception as e: log_dict['error'] = e.message LOG.error( "Error while processing %(op)s %(type)s %(id)s;" " Error: %(error)s", log_dict) db.update_pending_db_row_retry(session, entry, self._max_retry_count) entry = db.get_oldest_pending_db_row_with_lock(session) LOG.debug("Finished processing journal entries")
def _sync_entry(self, context, entry): log_dict = { 'op': entry.operation, 'type': entry.object_type, 'id': entry.object_uuid } LOG.info("Processing - %(op)s %(type)s %(id)s", log_dict) method, urlpath, to_send = self._json_data(entry) session = context.session try: self.client.sendjson(method, urlpath, to_send) registry.notify(entry.object_type, odl_const.BEFORE_COMPLETE, self, context=context, operation=entry.operation, row=entry) with session.begin(): db.update_db_row_state(session, entry, odl_const.COMPLETED) db.delete_dependency(session, entry) self._retry_reset() except exceptions.ConnectionError: # Don't raise the retry count, just log an error & break db.update_db_row_state(session, entry, odl_const.PENDING) LOG.error("Cannot connect to the OpenDaylight Controller," " will not process additional entries") self._retry_sleep() return True except Exception: LOG.error("Error while processing %(op)s %(type)s %(id)s", log_dict, exc_info=True) db.update_pending_db_row_retry(session, entry, self._max_retry_count) self._retry_sleep() return False
def sync_pending_row(self, exit_after_run=False): # Block until all pending rows are processed session = neutron_db_api.get_session() while not self.event.is_set(): self.event.wait() # Clear the event and go back to waiting after # the sync block exits self.event.clear() while True: LOG.debug("Thread walking database") row = db.get_oldest_pending_db_row_with_lock(session) if not row: LOG.debug("No rows to sync") break # Validate the operation validate_func = db.VALIDATION_MAP[row.object_type] valid = validate_func(session, row.object_uuid, row.operation, row.data) if not valid: LOG.info( _LI("%(operation)s %(type)s %(uuid)s is not a " "valid operation yet, skipping for now"), { 'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid }) continue LOG.info( _LI("Syncing %(operation)s %(type)s %(uuid)s"), { 'operation': row.operation, 'type': row.object_type, 'uuid': row.object_uuid }) # Add code to sync this to ODL method, urlpath, to_send = self._json_data(row) try: self.client.sendjson(method, urlpath, to_send) db.update_processing_db_row_passed(session, row) except exceptions.ConnectionError as e: # Don't raise the retry count, just log an error LOG.error( _LE("Cannot connect to the Opendaylight " "Controller")) # Set row back to pending db.update_db_row_pending(session, row) # Break our of the loop and retry with the next # timer interval break except Exception as e: LOG.error( _LE("Error syncing %(type)s %(operation)s," " id %(uuid)s Error: %(error)s"), { 'type': row.object_type, 'uuid': row.object_uuid, 'operation': row.operation, 'error': e.message }) db.update_pending_db_row_retry(session, row, self._row_retry_count) LOG.debug("Clearing sync thread event") if exit_after_run: # Permanently waiting thread model breaks unit tests # Adding this arg to exit here only for unit tests break
def entry_update_state_by_retry_count(context, entry, retry_count): session = context.session with db_api.autonested_transaction(session): db.update_pending_db_row_retry(session, entry, retry_count)
def entry_update_state_by_retry_count(context, entry, retry_count): db.update_pending_db_row_retry(context, entry, retry_count)