Skip to content

Makes ewoksorange.gui.owwidgets.thread returning TaskFuture#406

Open
payno wants to merge 35 commits into
mainfrom
387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4
Open

Makes ewoksorange.gui.owwidgets.thread returning TaskFuture#406
payno wants to merge 35 commits into
mainfrom
387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4

Conversation

@payno

@payno payno commented Jun 30, 2026

Copy link
Copy Markdown
Member

This PR benefits from the ewoksorange.gui.concurrency.executor module.

#405 to be merged first.

  • widgets from ewoksorange.gui.concurrency.threaded now use the executors from ewoksorange.gui.concurrency.executor
  • execute_ewoks_task API now return a ̀TaskFuture ̀ that we can cancel or abort.

Note to reviewers: as the ewoksorange.gui.owwidgets.threaded module contains a lot of modification this is probably simpler to look at the existing code today than on the diff.

Note on AI: spend some time to force Claude do what I wanted 😇 .

@payno payno self-assigned this Jun 30, 2026
@payno
payno changed the base branch from main to 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-3 June 30, 2026 11:43
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4 branch from e1b9c68 to b3938f0 Compare June 30, 2026 11:46
@@ -0,0 +1,9 @@
class CompletedWorker:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This worker has been added for the specific use case of the OWEwoksWidgetNoThread and in order to propose an homogeneous API (_execute_ewoks_task return a TaskFuture whenever possible)

Comment on lines +49 to +53
exception = e
_logger.error(f"task failed: {e}", exc_info=True)
else:
exception = None

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception is needed to fill the '_CompletedWorker' downstream.

Comment on lines +61 to +66
raw_future = _ConcurrentFuture()
if exception is not None:
raw_future.set_exception(exception)
else:
raw_future.set_result(self.__task_executor.output_variables)
return TaskFuture(raw_future, _CompletedWorker())

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build a dummy TaskFuture to make sure we have a coherent API.

class OWEwoksWidgetOneThread(_OWEwoksThreadedBaseWidget, **ow_build_opts):
"""
Single persistent background thread for task execution.
class _OWEwoksExecutorWidget(_OWEwoksThreadedBaseWidget, **ow_build_opts):

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the main advantage of using the executor into a dedicated module is that we can have a widget that can be generalized and from which only the "executor" is changed.

Comment on lines +88 to +93
# Note: all the following variable to be removed since executor refactoring
self.__current_task_future: Optional[TaskFuture] = None
self.__last_output_variables: dict = {}
self.__last_task_succeeded: Optional[bool] = None
self.__last_task_done: Optional[bool] = None
self.__last_task_exception: Optional[Exception] = None

@payno payno Jun 30, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new design I think at one point we could get rid of those. It would simplify things and is more aligned with "expectation".

I started to reduce usage but this is not that straightforward so I just added a warning for future.

Comment on lines +141 to +172
def task_succeeded(self) -> Optional[bool]:
warnings.warn(
f"'task_succeeded' is deprecated since 6.0 Please use directly the future provided during task submission.",
DeprecationWarning,
stacklevel=2,
)
return self.__last_task_succeeded

@property
def task_done(self) -> Optional[bool]:
warnings.warn(
f"'task_done' is deprecated since 6.0 Please use directly the future provided during task submission.",
DeprecationWarning,
stacklevel=2,
)
return self.__last_task_done

@property
def task_exception(self) -> Optional[Exception]:
warnings.warn(
f"'task_exception' is deprecated since 6.0 Please use directly the future provided during task submission.",
DeprecationWarning,
stacklevel=2,
)
return self.__last_task_exception

def _get_task_outputs(self) -> dict:
"""Return the last finished task's outputs."""
warnings.warn(
f"'cancel_running_task' is deprecated since 6.0 Please use directly the future provided during task submission.",
DeprecationWarning,
stacklevel=2,
)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are using internally one of the following variables that we would like to remove in the future:

  • __current_task_future
  • __last_output_variables
  • __last_task_succeeded
  • __last_task_done
  • __last_task_exception

The best would be to able to deprecate them all and use the ̀TaskFuture ̀ instead but this is not that direct so I only reduce usage of it when this was direct.
To be considered in the future.

super().__init__(*args, **kwargs)
self.__task_executor_queue = TaskExecutorQueue(
ewokstaskclass=self.ewokstaskclass
def cancel_running_task(self) -> None:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should now use future. Internally we are only using it for test that will be removed once TaskExecutorQueue class is removed.

@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4 branch from c7cbe0b to a78a7ff Compare June 30, 2026 13:27

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replaced by test_executor (from previous PR)

@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4 branch 2 times, most recently from 8b58459 to b2edd60 Compare June 30, 2026 15:02

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed as all the classes it was testing are now deprecated. It also avoid having some modifications of the .github/workflows/test.yml to ignore deprecation warning. A bit violent but way simpler.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test for OWEwoksWidgetNoThread that were not existing. Simple test to make sure the new API using future is working for this widget.

Comment on lines +68 to +69
# wait for the future to be started. Should be done through a QtEvent
sleep(0.2)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering using an Event but this is probably overkilled.

Comment thread pyproject.toml
[project]
name = "ewoksorange"
version = "5.0.1"
version = "6.0.0"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to minimize API break but this is huge modification. So for sure it will break existing behavior under the hood. More honest to consider this will part of a major release.

@payno payno changed the title Draft: 387 owewokswidgetwithtaskstack provide api to cancel a task 4 Makes ewoksorange.gui.owwidgets.thread returning TaskFuture Jun 30, 2026
@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-3 branch from 57e77b8 to e9d5528 Compare July 1, 2026 15:25
@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4 branch 5 times, most recently from f70b3e2 to 18977fd Compare July 2, 2026 11:41
payno and others added 10 commits July 17, 2026 15:27
# Conflicts:
#	src/ewoksorange/gui/concurrency/executor/_EwoksProcessWorker.py

# Conflicts:
#	src/ewoksorange/gui/concurrency/executor/_EwoksProcessWorker.py

# Conflicts:
#	src/ewoksorange/gui/concurrency/executor/_EwoksProcessHandle.py
…ead submission.

# Conflicts:
#	src/ewoksorange/gui/concurrency/executor/EwoksExecutor.py
payno added 25 commits July 17, 2026 15:27
…sed when aborted

# Conflicts:
#	src/ewoksorange/gui/owwidgets/threaded.py
…inside the try / finally. This is not the purpose of this PR
…WEwoksWidgetWithTaskStack' under the generic '_OWEwoksExecutorWidget'
…ne', 'task_exception', '_get_task_outputs' and 'cancel_running_task'
…_done', 'task_exception', '_get_task_outputs'
@payno
payno force-pushed the 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-4 branch from 18977fd to 00e253a Compare July 17, 2026 13:27
@payno
payno changed the base branch from 387-owewokswidgetwithtaskstack-provide-api-to-cancel-a-task-3 to main July 17, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant