Skip to content

Commit

Permalink
Merge pull request #847 from ynput/bugfix/default-publish-iterator
Browse files Browse the repository at this point in the history
Publisher: Fix stop of publishing
  • Loading branch information
iLLiCiTiT authored Aug 26, 2024
2 parents e5801be + ded16d5 commit 6a07de6
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 37 deletions.
24 changes: 18 additions & 6 deletions client/ayon_core/tools/publisher/control_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -77,21 +76,32 @@ 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):
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)
)
# 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)
)

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

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(
Expand All @@ -105,4 +115,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)
)
72 changes: 41 additions & 31 deletions client/ayon_core/tools/publisher/models/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -841,7 +841,9 @@ def __init__(self, controller: AbstractPublisherBackend):
)

# Plugin iterator
self._main_thread_iter: Iterable[partial] = []
self._main_thread_iter: collections.abc.Generator[partial] = (
self._default_iterator()
)

def reset(self):
create_context = self._controller.get_create_context()
Expand Down Expand Up @@ -907,29 +909,30 @@ 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
# - 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 (
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
self._publish_has_validated
and (
self._publish_has_validation_errors
or self._publish_up_validation
)
# Any unexpected error happened
# - everything should stop
or self._publish_has_crashed
):
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:
Expand Down Expand Up @@ -1082,6 +1085,19 @@ 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.
Returns:
collections.abc.Generator[partial]: Generator with partial
functions that should 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:
Expand Down Expand Up @@ -1113,22 +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
)

# 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()
not self._publish_has_validated
and plugin.order >= self._validation_order
):
yield partial(self.stop_publish)
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(
Expand Down

0 comments on commit 6a07de6

Please sign in to comment.