Skip to content

Commit

Permalink
Merge pull request #849 from ynput/enhancement/process-context-is-ret…
Browse files Browse the repository at this point in the history
…urned

Prepare process: Enhancements
  • Loading branch information
iLLiCiTiT authored Aug 21, 2024
2 parents eaf05a0 + c1d7bb8 commit f87a433
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 31 deletions.
38 changes: 22 additions & 16 deletions client/ayon_core/addon/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
Logger,
is_dev_mode_enabled,
get_launcher_storage_dir,
is_headless_mode_enabled,
)
from ayon_core.settings import get_studio_settings

Expand Down Expand Up @@ -80,36 +81,41 @@ class ProcessPreparationError(Exception):


class ProcessContext:
"""Context of child process.
"""Hold context of process that is going to be started.
Notes:
This class is used to pass context to child process. It can be used
to use different behavior of addon based on information in
the context.
The context can be enhanced in future versions.
Right now the context is simple, having information about addon that wants
to trigger preparation and possibly project name for which it should
happen.
Preparation for process can be required for ayon-core or any other addon.
It can be, change of environment variables, or request login to
a project management.
At the moment of creation is 'ProcessContext' only data holder, but that
might change in future if there will be need.
Args:
addon_name (Optional[str]): Addon name which triggered process.
addon_version (Optional[str]): Addon version which triggered process.
addon_name (str): Addon name which triggered process.
addon_version (str): Addon version which triggered process.
project_name (Optional[str]): Project name. Can be filled in case
process is triggered for specific project. Some addons can have
different behavior based on project.
headless (Optional[bool]): Is process running in headless mode.
different behavior based on project. Value is NOT autofilled.
headless (Optional[bool]): Is process running in headless mode. Value
is filled with value based on state set in AYON launcher.
"""
def __init__(
self,
addon_name: Optional[str] = None,
addon_version: Optional[str] = None,
addon_name: str,
addon_version: str,
project_name: Optional[str] = None,
headless: Optional[bool] = None,
**kwargs,
):
if headless is None:
# TODO use lib function to get headless mode
headless = os.getenv("AYON_HEADLESS_MODE") == "1"
self.addon_name: Optional[str] = addon_name
self.addon_version: Optional[str] = addon_version
headless = is_headless_mode_enabled()
self.addon_name: str = addon_name
self.addon_version: str = addon_version
self.project_name: Optional[str] = project_name
self.headless: bool = headless

Expand Down
47 changes: 32 additions & 15 deletions client/ayon_core/addon/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,17 @@ def ensure_addons_are_process_context_ready(
process_context: ProcessContext,
addons_manager: Optional[AddonsManager] = None,
exit_on_failure: bool = True,
) -> Optional[Exception]:
) -> bool:
"""Ensure all enabled addons are ready to be used in the given context.
Call this method only in AYON launcher process and as first thing
to avoid possible clashes with preparation. For example 'QApplication'
should not be created.
Todos:
Run all preparations and allow to "ignore" failed preparations.
Right now single addon can block using certain actions.
Args:
process_context (ProcessContext): The context in which the
addons should be prepared.
Expand All @@ -88,14 +92,12 @@ def ensure_addons_are_process_context_ready(
if an error occurs. Defaults to True.
Returns:
Optional[Exception]: The exception that occurred during the
preparation, if any.
bool: True if all addons are ready, False otherwise.
"""
if addons_manager is None:
addons_manager = AddonsManager()

exception = None
message = None
failed = False
use_detail = False
Expand All @@ -112,13 +114,11 @@ def ensure_addons_are_process_context_ready(
addon.ensure_is_process_ready(process_context)
addon_failed = False
except ProcessPreparationError as exc:
exception = exc
message = str(exc)
print(f"Addon preparation failed: '{addon.name}'")
print(message)

except BaseException as exc:
exception = exc
except BaseException:
use_detail = True
message = "An unexpected error occurred."
formatted_traceback = "".join(traceback.format_exception(
Expand All @@ -140,7 +140,7 @@ def ensure_addons_are_process_context_ready(
if not failed:
if not process_context.headless:
_start_tray()
return None
return True

detail = None
if use_detail:
Expand All @@ -150,35 +150,52 @@ def ensure_addons_are_process_context_ready(
detail = output_str

_handle_error(process_context, message, detail)
if not exit_on_failure:
return exception
sys.exit(1)
if exit_on_failure:
sys.exit(1)
return False


def ensure_addons_are_process_ready(
addon_name: str,
addon_version: str,
project_name: Optional[str] = None,
headless: Optional[bool] = None,
*,
addons_manager: Optional[AddonsManager] = None,
exit_on_failure: bool = True,
**kwargs,
) -> Optional[Exception]:
) -> bool:
"""Ensure all enabled addons are ready to be used in the given context.
Call this method only in AYON launcher process and as first thing
to avoid possible clashes with preparation. For example 'QApplication'
should not be created.
Args:
addon_name (str): Addon name which triggered process.
addon_version (str): Addon version which triggered process.
project_name (Optional[str]): Project name. Can be filled in case
process is triggered for specific project. Some addons can have
different behavior based on project. Value is NOT autofilled.
headless (Optional[bool]): Is process running in headless mode. Value
is filled with value based on state set in AYON launcher.
addons_manager (Optional[AddonsManager]): The addons
manager to use. If not provided, a new one will be created.
exit_on_failure (bool, optional): If True, the process will exit
if an error occurs. Defaults to True.
kwargs: The keyword arguments to pass to the ProcessContext.
Returns:
Optional[Exception]: The exception that occurred during the
preparation, if any.
bool: True if all addons are ready, False otherwise.
"""
context: ProcessContext = ProcessContext(**kwargs)
context: ProcessContext = ProcessContext(
addon_name,
addon_version,
project_name,
headless,
**kwargs
)
return ensure_addons_are_process_context_ready(
context, addons_manager, exit_on_failure
)
2 changes: 2 additions & 0 deletions client/ayon_core/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
is_in_ayon_launcher_process,
is_running_from_build,
is_using_ayon_console,
is_headless_mode_enabled,
is_staging_enabled,
is_dev_mode_enabled,
is_in_tests,
Expand Down Expand Up @@ -245,6 +246,7 @@
"is_in_ayon_launcher_process",
"is_running_from_build",
"is_using_ayon_console",
"is_headless_mode_enabled",
"is_staging_enabled",
"is_dev_mode_enabled",
"is_in_tests",
Expand Down
4 changes: 4 additions & 0 deletions client/ayon_core/lib/ayon_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def is_using_ayon_console():
return "ayon_console" in executable_filename


def is_headless_mode_enabled():
return os.getenv("AYON_HEADLESS_MODE") == "1"


def is_staging_enabled():
return os.getenv("AYON_USE_STAGING") == "1"

Expand Down

0 comments on commit f87a433

Please sign in to comment.