-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NEXMANAGE-737] Sota cancel mode with threading event method (#567)
* [NEXMANAGE-737] Enable sota cancel mode. This PR implements the sota cancel mode using a threading event flag. When the thread is created, it will be added to a thread list. When the dispatcher receives the sota cancel request, it checks the current running thread and retrieves its sota type. If it is a download-only sota, the dispatcher sets the event flag to issue a cancel request. Please note that the first inbc command should be terminated before sending inbc cancel command as they will be sharing the same mqtt connection. Signed-off-by: yengliong <[email protected]> * Cancel request in the middle of download * Fix unit test * Add unit tests to increase coverage * Add timeout in thread.join --------- Signed-off-by: yengliong <[email protected]>
- Loading branch information
1 parent
4bfbbd0
commit 5426e6c
Showing
16 changed files
with
497 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
""" | ||
Method to handle cancel request | ||
Copyright (C) 2017-2024 Intel Corporation | ||
SPDX-License-Identifier: Apache-2.0 | ||
""" | ||
|
||
import logging | ||
from typing import Optional | ||
from threading import Event | ||
from inbm_lib.xmlhandler import XmlHandler | ||
from threading import Thread | ||
from .constants import SOTA_CACHE | ||
from ..constants import OtaType | ||
from dispatcher.dispatcher_exception import DispatcherException | ||
from dispatcher.packagemanager.local_repo import DirectoryRepo | ||
from dispatcher.dispatcher_broker import DispatcherBroker | ||
from dispatcher.common.result_constants import Result, CODE_OK, CODE_BAD_REQUEST | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def cancel_thread(type_of_manifest: str, parsed_head: XmlHandler, thread_list: list[Thread], | ||
type_of_active_manifest: Optional[str], active_thread_parsed_head: Optional[XmlHandler], | ||
dispatcher_broker: DispatcherBroker, cancel_event: Event) -> bool: | ||
""" | ||
Cancel the current active thread by sending the terminate signal. | ||
@param type_of_manifest: type of the request | ||
@param parsed_head: The root parsed xml | ||
@param thread_list: List of the active thread | ||
@param type_of_active_manifest: type of the request on running thread | ||
@param active_thread_parsed_head: The root parsed xml of running thread | ||
@param dispatcher_broker: DispatcherBroker object used to communicate with other INBM services | ||
@param cancel_event: Event used to stop the downloading process | ||
@return: True if the request has been processed; False if no request has been handled. | ||
""" | ||
if type_of_manifest == 'ota': | ||
header = parsed_head.get_children('ota/header') | ||
ota_type = header['type'] | ||
resource = parsed_head.get_children(f'ota/type/{ota_type}') | ||
if ota_type == OtaType.SOTA.name.lower(): | ||
sota_mode = resource.get('mode', None) | ||
if sota_mode == 'cancel': | ||
logger.debug(f"Receive sota cancel request.") | ||
# If the active thread is not SOTA download-only, forbid the cancel request. | ||
if type_of_active_manifest and active_thread_parsed_head: | ||
if not is_active_ota_sota_download_only(type_of_active_manifest, active_thread_parsed_head): | ||
dispatcher_broker.send_result( | ||
str(Result(CODE_BAD_REQUEST, "Current thread is not SOTA download-only. " | ||
"Cannot proceed with the cancel request."))) | ||
return True | ||
else: | ||
dispatcher_broker.send_result(str(Result(CODE_BAD_REQUEST, "Running thread manifest not found."))) | ||
return True | ||
|
||
# The list should only contain one OTA process. | ||
for thread in thread_list: | ||
if thread.is_alive(): | ||
cancel_event.set() | ||
# Wait thread to gracefully exit | ||
logger.debug(f"Waiting thread to exit...") | ||
thread.join(timeout=300) | ||
logger.debug(f"Request cancel complete.") | ||
# Reset the event flag | ||
cancel_event.clear() | ||
return True | ||
return False | ||
|
||
|
||
def is_active_ota_sota_download_only(type_of_active_manifest: str, active_parsed_head: XmlHandler) -> bool: | ||
""" | ||
Check whether the current active thread is SOTA download-only mode. | ||
@param type_of_active_manifest: type of the request | ||
@param active_parsed_head: The root parsed xml | ||
@return: True if it is SOTA download-only; False if not. | ||
""" | ||
logger.debug("") | ||
if type_of_active_manifest == 'ota': | ||
header = active_parsed_head.get_children('ota/header') | ||
ota_type = header['type'] | ||
resource = active_parsed_head.get_children(f'ota/type/{ota_type}') | ||
if ota_type == OtaType.SOTA.name.lower(): | ||
sota_mode = resource.get('mode', None) | ||
if sota_mode == 'download-only': | ||
return True | ||
return False |
Oops, something went wrong.