Commit 7d869e62 authored by Ville Hallivuori's avatar Ville Hallivuori
Browse files

XR Network Connection delete concistency enforcement

parent 44eec9ba
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -341,6 +341,53 @@ class CmConnection:

        return get_result

    def apply_delete_consistency(self, href: str, get_fn):
        # Asynchronous, no validation
        if self.__consistency_mode == ConsistencyMode.asynchronous:
            return None

        ts_start = time.perf_counter()
        log_ts = ts_start
        get_result = get_fn()
        valid = False
        while True:
            if not get_result:
                # Object no longer exist, so this is completely successful operation
                valid = True
                break
            else:
                # In delete, treat terminal life cycle state as criteria for ConsistencyMode.synchronous:
                # This is unobvious, but in delete non-existence is stronger guarantee than just lifecycle
                # (so this is exact opposite )
                if get_result.life_cycle_info.is_terminal_state() and self.__consistency_mode == ConsistencyMode.synchronous:
                    valid = True
                    break
                else:
                    ts = time.perf_counter()
                    if ts - log_ts >= self.CONSISTENCY_WAIT_LOG_INTERVAL:
                        log_ts = ts
                        if get_result.life_cycle_info.is_terminal_state():
                            LOGGER.info(f"apply_delete_consistency(): waiting for delete to be reflected in REST API for {get_result}, current life-cycle-state: {str(get_result.life_cycle_info)}, ellapsed time {ts-ts_start} seconds")
                        else:
                            LOGGER.info(f"apply_delete_consistency(): waiting for life cycle state progress for {get_result}, current: {str(get_result.life_cycle_info)}, ellapsed time {ts-ts_start} seconds")

            if time.perf_counter() - ts_start > self.__timeout:
                break
            time.sleep(self.__retry_interval)
            get_result = get_fn()

        duration = time.perf_counter() - ts_start
        if not valid:
            if get_result:
                if not get_result.life_cycle_info.is_terminal_state():
                    LOGGER.info(f"Failed to apply create delete for {get_result}, insufficient life-cycle-state progress ({str(get_result.life_cycle_info)}), duration {duration} seconds")
                else:
                    LOGGER.info(f"Failed to apply delete consistency for {get_result}, REST object did not dissappear, duration {duration} seconds")
        else:
            LOGGER.info(f"Applied delete consistency for {href}, duration {duration} seconds")

        return get_result

    def create_connection(self, connection: Connection) -> Optional[str]:
        # Create wants a list, so wrap connection to list
        cfg = [connection.create_config()]
@@ -416,6 +463,7 @@ class CmConnection:
        #print(resp)
        # Returns empty body
        if resp.is_valid_with_status_ignore_body(202):
            self.apply_delete_consistency(href, lambda: self.get_connection_by_href(href))
            LOGGER.info(f"Deleted connection {href=}")
            return True
        else: