From b2c9ea31258cb763069c89c77726c7471e1dfa74 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:39:22 +0200 Subject: [PATCH 1/8] added default iterator on initialization --- .../ayon_core/tools/publisher/models/publish.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index ef207bfb79..ab8a041414 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -829,7 +829,7 @@ def __init__(self, controller: AbstractPublisherBackend): ) # Plugin iterator - self._main_thread_iter: Iterable[partial] = [] + self._main_thread_iter: Iterable[partial] = self._default_iterator() def reset(self): create_context = self._controller.get_create_context() @@ -900,10 +900,9 @@ def get_next_process_func(self) -> partial: # only in specific cases (e.g. when it happens for a first time) if ( - self._main_thread_iter is None # There are validation errors and validation is passed # - can't do any progree - or ( + ( self._publish_has_validated and self._publish_has_validation_errors ) @@ -1070,6 +1069,18 @@ def _set_publish_error_msg(self, value: Optional[str]): {"value": value} ) + def _default_iterator(self): + """Iterator used on initialization. + + Should be replaced by real iterator when 'reset' is called. + + Yields: + partial: Function that will be called in main thread. + + """ + while True: + yield partial(self.stop_publish) + def _start_publish(self): """Start or continue in publishing.""" if self._publish_is_running: From a39c96ea068463360ffa475f8b7c260262dbedac Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:59:09 +0200 Subject: [PATCH 2/8] move some generic checks from iterator --- .../tools/publisher/models/publish.py | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index ab8a041414..c909fd1ef2 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -829,7 +829,9 @@ def __init__(self, controller: AbstractPublisherBackend): ) # Plugin iterator - self._main_thread_iter: Iterable[partial] = self._default_iterator() + self._main_thread_iter: collections.abc.Generator[partial] = ( + self._default_iterator() + ) def reset(self): create_context = self._controller.get_create_context() @@ -898,17 +900,19 @@ def get_next_process_func(self) -> partial: # Validations of progress before using iterator # - same conditions may be inside iterator but they may be used # only in specific cases (e.g. when it happens for a first time) - if ( - # There are validation errors and validation is passed - # - can't do any progree - ( - self._publish_has_validated - and self._publish_has_validation_errors - ) # Any unexpected error happened # - everything should stop - or self._publish_has_crashed + self._publish_has_crashed + # Stop if validation is over and validation errors happened + # or publishing should stop at validation + or ( + self._publish_has_validated + and ( + self._publish_has_validation_errors + or self._publish_up_validation + ) + ) ): item = partial(self.stop_publish) @@ -1074,8 +1078,9 @@ def _default_iterator(self): Should be replaced by real iterator when 'reset' is called. - Yields: - partial: Function that will be called in main thread. + Returns: + collections.abc.Generator[partial]: Generator with partial + functions that should be called in main thread. """ while True: @@ -1117,18 +1122,6 @@ def _publish_iterator(self) -> Iterable[partial]: plugin.order >= self._validation_order ) - # Stop if plugin is over validation order and process - # should process up to validation. - if self._publish_up_validation and self._publish_has_validated: - yield partial(self.stop_publish) - - # Stop if validation is over and validation errors happened - if ( - self._publish_has_validated - and self.has_validation_errors() - ): - yield partial(self.stop_publish) - # Add plugin to publish report self._publish_report.add_plugin_iter( plugin.id, self._publish_context) From e271b06c9fe50b90275740a38cd162763f6d5b91 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:00:52 +0200 Subject: [PATCH 3/8] simplify clear --- client/ayon_core/tools/publisher/control_qt.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/ayon_core/tools/publisher/control_qt.py b/client/ayon_core/tools/publisher/control_qt.py index b42b9afea3..f769fab91e 100644 --- a/client/ayon_core/tools/publisher/control_qt.py +++ b/client/ayon_core/tools/publisher/control_qt.py @@ -60,9 +60,8 @@ def stop(self): self._timer.stop() def clear(self): - if self._timer.isActive(): - self._timer.stop() self._items_to_process = collections.deque() + self.stop() class QtPublisherController(PublisherController): From 29825b6d0ebaafe900cd55ee05a1ee4fadd19283 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:11:01 +0200 Subject: [PATCH 4/8] more readable code --- .../tools/publisher/models/publish.py | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index c909fd1ef2..c80e49d91f 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -898,29 +898,24 @@ def start_publish(self, wait: Optional[bool] = True): def get_next_process_func(self) -> partial: # Validations of progress before using iterator - # - same conditions may be inside iterator but they may be used - # only in specific cases (e.g. when it happens for a first time) + # Any unexpected error happened + # - everything should stop + if self._publish_has_crashed: + return partial(self.stop_publish) + + # Stop if validation is over and validation errors happened + # or publishing should stop at validation if ( - # Any unexpected error happened - # - everything should stop - self._publish_has_crashed - # Stop if validation is over and validation errors happened - # or publishing should stop at validation - or ( - self._publish_has_validated - and ( - self._publish_has_validation_errors - or self._publish_up_validation - ) + self._publish_has_validated + and ( + self._publish_has_validation_errors + or self._publish_up_validation ) ): - item = partial(self.stop_publish) + return partial(self.stop_publish) # Everything is ok so try to get new processing item - else: - item = next(self._main_thread_iter) - - return item + return next(self._main_thread_iter) def stop_publish(self): if self._publish_is_running: From 4041d7b8705879df0a8d9667c5d6143af1c617de Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 19 Aug 2024 17:11:27 +0200 Subject: [PATCH 5/8] raise error when 'get_next_process_func' is called and publishing did not start --- client/ayon_core/tools/publisher/models/publish.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index c80e49d91f..3bd6b33f49 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -897,6 +897,11 @@ def start_publish(self, wait: Optional[bool] = True): func() def get_next_process_func(self) -> partial: + # Raise error if this function is called when publishing + # is not running + if not self._publish_is_running: + raise ValueError("Publish is not running") + # Validations of progress before using iterator # Any unexpected error happened # - everything should stop From 4344b032306d412d7e777574e1aaffb328e71d8e Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:25:19 +0200 Subject: [PATCH 6/8] fix validation stop check --- client/ayon_core/tools/publisher/models/publish.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/tools/publisher/models/publish.py b/client/ayon_core/tools/publisher/models/publish.py index a73997c302..a60ef69fac 100644 --- a/client/ayon_core/tools/publisher/models/publish.py +++ b/client/ayon_core/tools/publisher/models/publish.py @@ -1129,10 +1129,16 @@ def _publish_iterator(self) -> Iterable[partial]: self._publish_progress = idx # Check if plugin is over validation order - if not self._publish_has_validated: - self._set_has_validated( - plugin.order >= self._validation_order - ) + if ( + not self._publish_has_validated + and plugin.order >= self._validation_order + ): + self._set_has_validated(True) + if ( + self._publish_up_validation + or self._publish_has_validation_errors + ): + yield partial(self.stop_publish) # Add plugin to publish report self._publish_report.add_plugin_iter( From 4632d22275099045d2c1da0d757b92e7aacc37ec Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Sun, 25 Aug 2024 11:30:51 +0200 Subject: [PATCH 7/8] make sure only one loop is running Make sure loop of '_next_publish_item_process' is in processor only once --- client/ayon_core/tools/publisher/control_qt.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/tools/publisher/control_qt.py b/client/ayon_core/tools/publisher/control_qt.py index f769fab91e..e87d546333 100644 --- a/client/ayon_core/tools/publisher/control_qt.py +++ b/client/ayon_core/tools/publisher/control_qt.py @@ -76,21 +76,27 @@ def __init__(self, *args, **kwargs): self.register_event_callback( "publish.process.stopped", self._qt_on_publish_stop ) + self._item_process_in_loop = False def reset(self): self._main_thread_processor.clear() + self._item_process_in_loop = False super().reset() def _start_publish(self, up_validation): self._publish_model.set_publish_up_validation(up_validation) self._publish_model.start_publish(wait=False) - self._process_main_thread_item( - MainThreadItem(self._next_publish_item_process) - ) + if not self._item_process_in_loop: + self._process_main_thread_item( + MainThreadItem(self._next_publish_item_process) + ) def _next_publish_item_process(self): if not self._publish_model.is_running(): + self._item_process_in_loop = False return + + self._item_process_in_loop = True func = self._publish_model.get_next_process_func() self._process_main_thread_item(MainThreadItem(func)) self._process_main_thread_item( @@ -104,4 +110,6 @@ def _qt_on_publish_start(self): self._main_thread_processor.start() def _qt_on_publish_stop(self): - self._main_thread_processor.stop() + self._process_main_thread_item( + MainThreadItem(self._main_thread_processor.stop) + ) From 570b0c8b7038db3dac39e8dd0f61b85f273ae898 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 26 Aug 2024 11:45:01 +0200 Subject: [PATCH 8/8] added some comments --- client/ayon_core/tools/publisher/control_qt.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/ayon_core/tools/publisher/control_qt.py b/client/ayon_core/tools/publisher/control_qt.py index e87d546333..7d1c661603 100644 --- a/client/ayon_core/tools/publisher/control_qt.py +++ b/client/ayon_core/tools/publisher/control_qt.py @@ -76,6 +76,8 @@ def __init__(self, *args, **kwargs): self.register_event_callback( "publish.process.stopped", self._qt_on_publish_stop ) + # Capture if '_next_publish_item_process' is in + # '_main_thread_processor' loop self._item_process_in_loop = False def reset(self): @@ -86,6 +88,8 @@ def reset(self): def _start_publish(self, up_validation): self._publish_model.set_publish_up_validation(up_validation) self._publish_model.start_publish(wait=False) + # Make sure '_next_publish_item_process' is only once in + # the '_main_thread_processor' loop if not self._item_process_in_loop: self._process_main_thread_item( MainThreadItem(self._next_publish_item_process) @@ -93,6 +97,7 @@ def _start_publish(self, up_validation): def _next_publish_item_process(self): if not self._publish_model.is_running(): + # This removes '_next_publish_item_process' from loop self._item_process_in_loop = False return