Skip to content

Make Executor.get_function_and_kwargs the overridable resolution hook. - #46

Merged
TkTech merged 1 commit into
TkTech:26_uxfrom
PaulM5406:enabling-overriding-get_function_and_kwargs-in-executor-subclass
Sep 16, 2026
Merged

TkTech merged 1 commit into
TkTech:26_uxfrom
PaulM5406:enabling-overriding-get_function_and_kwargs-in-executor-subclass

Conversation

@PaulM5406

Copy link
Copy Markdown
Contributor

Hey @TkTech,

I would like to be able to override get_function_and_kwargs in custom executor to be able to dynamically inject other kwargs like it is possible with QueueJob.

Thanks !

@codecov

codecov Bot commented Jul 31, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 71.31%. Comparing base (4026904) to head (acb2407).
⚠️ Report is 11 commits behind head on 24_4.

Files with missing lines Patch % Lines
chancy/executors/sub.py 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             24_4      #46      +/-   ##
==========================================
+ Coverage   71.26%   71.31%   +0.05%     
==========================================
  Files          55       55              
  Lines        2899     2894       -5     
==========================================
- Hits         2066     2064       -2     
+ Misses        833      830       -3     
Flag Coverage Δ
unittests 71.31% <80.00%> (+0.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@TkTech

TkTech commented Aug 6, 2025

Copy link
Copy Markdown
Owner

This one was originally intentional, as significant care has to be taken when crossing process/thread/sub-interpreter barriers. But your use case is definitely valid and this is definitely safe in the async executor. I'll give the others a closer review.

@TkTech
TkTech self-requested a review August 6, 2025 01:03
@TkTech TkTech added the enhancement New feature or request label Aug 6, 2025
@TkTech
TkTech changed the base branch from main to 24_4 August 6, 2025 01:04
@PaulM5406

PaulM5406 commented Aug 28, 2025

Copy link
Copy Markdown
Contributor Author

Hey @TkTech, would you have the time to have another look at this PR ? May it be part of 0.24.4 ?
If not, may you add only the change of the async executor to the 0.24.4 release ?
Do you think you could release it soon ?
Thank you !

@TkTech

TkTech commented Sep 1, 2025

Copy link
Copy Markdown
Owner

#49 will release tomorrow with this supported at least for the async executor.

Could you expand on your use case for this one? Is the kwarg you want to inject related to Chancy itself, like job or queue data, or your own?

@PaulM5406

Copy link
Copy Markdown
Contributor Author

#49 will release tomorrow with this supported at least for the async executor.

Could you expand on your use case for this one? Is the kwarg you want to inject related to Chancy itself, like job or queue data, or your own?

kwargs I want to inject is not part of chancy. There are some other external services, like other DB connections.

@TkTech TkTech added this to the 0.26.0 milestone Oct 29, 2025
luca-montaigut added a commit to PaulM5406/chancy that referenced this pull request Sep 11, 2026
…TkTech#46)

Custom executors need a supported way to inject their own keyword
arguments (database pools, clients, ...) into every job they run. The
built-in executors resolved the function through a private static helper
that ignored subclass overrides, so the public get_function_and_kwargs
was never consulted.

get_function_and_kwargs is now a classmethod holding the resolution
logic, and prepare_job_for_execution goes through it for every executor.
The job-context detection used by co-operative time limits now checks
the resolved kwargs for the job instance instead of a side channel, so
overrides cannot break it.

Co-authored-by: PaulM5406 <ppsmilesi@protonmail.com>
@luca-montaigut
luca-montaigut force-pushed the enabling-overriding-get_function_and_kwargs-in-executor-subclass branch from acb2407 to 4e15556 Compare September 11, 2026 08:18
@PaulM5406
PaulM5406 changed the base branch from 24_4 to 26_ux September 11, 2026 08:39
@PaulM5406 PaulM5406 changed the title In executors, call get_function_and_kwargs from self or cls Make Executor.get_function_and_kwargs the overridable resolution hook. Sep 11, 2026
…TkTech#46)

Custom executors need a supported way to inject their own keyword
arguments (database pools, clients, ...) into every job they run. The
built-in executors resolved the function through a private static helper
that ignored subclass overrides, so the public get_function_and_kwargs
was never consulted.

get_function_and_kwargs is now a classmethod holding the resolution
logic, and prepare_job_for_execution goes through it for every executor.
The job-context detection used by co-operative time limits now checks
the resolved kwargs for the job instance instead of a side channel, so
overrides cannot break it.

Because job_wrapper and prepare_job_for_execution are classmethods, the
override runs on the side that executes the job (event loop, pool
thread, sub-interpreter or child process); nothing crosses that boundary
beyond the executor's importable name. The docstring spells this out and
an end-to-end test checks the injection on every built-in executor.

Co-authored-by: PaulM5406 <ppsmilesi@protonmail.com>
@luca-montaigut
luca-montaigut force-pushed the enabling-overriding-get_function_and_kwargs-in-executor-subclass branch from 4e15556 to 35d5cb2 Compare September 11, 2026 08:44
@luca-montaigut

luca-montaigut commented Sep 11, 2026

Copy link
Copy Markdown

Taking over this PR from @PaulM5406, context in #58 (comment). It is now retargeted to 26_ux since the executors were refactored there.

Use case, as Paul described: a custom executor injecting application-level dependencies (connection pools, API clients) as keyword arguments into every job, without wrapping each job function.

On 26_ux all built-in executors go through prepare_job_for_execution, which resolved the function via a private static helper. The public get_function_and_kwargs was a thin wrapper hardcoded to Executor, so overriding it in a subclass had no effect.

What changes

  • get_function_and_kwargs becomes a classmethod holding the resolution logic, and prepare_job_for_execution calls cls.get_function_and_kwargs. Its docstring names it as the override point and carries the warning about where it runs (event loop, thread, sub-interpreter, child process).
  • The job-context detection used by co-operative time limits now checks the resolved kwargs for the job instance, so an override cannot break it by accident.
  • Tests: a ThreadedExecutor subclass injects a kwarg at the prepare_job_for_execution level, and an end-to-end test checks the injection through a real worker on the process, threaded, async and sub-interpreter executors.
  • Changelog entry under 0.26.0.

@luca-montaigut

luca-montaigut commented Sep 11, 2026

Copy link
Copy Markdown

This one was originally intentional, as significant care has to be taken when crossing process/thread/sub-interpreter barriers. But your use case is definitely valid and this is definitely safe in the async executor. I'll give the others a closer review.

On 26_ux this concern is addressed by your own refactor: job_wrapper and prepare_job_for_execution are classmethods, and every executor submits cls.job_wrapper to its pool. For the process and sub-interpreter pools that bound method is pickled by reference and re-imported on the other side, so an override of get_function_and_kwargs runs where the job runs, never in the worker. Nothing crosses the boundary except the executor's importable name, which is the same rule as on_initialize_worker.

The updated PR only routes the resolution through the public name instead of the private helper. The docstring now spells out where the method runs and what that implies, and test_injected_kwargs_reach_jobs_on_every_executor checks the injection end to end on the process, threaded, async and sub-interpreter executors.

@TkTech
TkTech merged commit b7fe8d0 into TkTech:26_ux Sep 16, 2026
4 of 16 checks passed
TkTech added a commit that referenced this pull request Sep 16, 2026
@TkTech

TkTech commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Merged in #58, with one change to the docstring (async and threaded executors can generally share objects)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants