Skip to content

Feature: asyncio support#284

Merged
psrok1 merged 13 commits intomasterfrom
feature/asyncio
Jun 24, 2025
Merged

Feature: asyncio support#284
psrok1 merged 13 commits intomasterfrom
feature/asyncio

Conversation

@psrok1
Copy link
Member

@psrok1 psrok1 commented Jun 9, 2025

Here I'm making a PoC for asyncio support in Karton. Changes improving code reusability between sync/async parts will be isolated into separate PRs.

Changes in core:

  • separated some non-I/O code into mixins/bases to reuse them in async code
  • global reference to current_task is kept in contextvar. It is used for automagical binding with current task in logging/Producer.send_task. Theoretically this change may sync code as well because Context Variables are also thread-local, so e.g. thread workers trying to access self.current_task from closure will see None, but I hope nobody does such thing.
  • implemented karton.core.asyncio.backend.KartonAsyncBackend with asyncio reimplementation of backend methods needed by Producers and Consumers. Non-I/O parts of code that are common for KartonBackend and KartonAsyncBackend were moved into KartonBackendBase. KartonAsyncBackend works a bit differently than KartonBackend:
    • KartonAsyncBackend needs explicit initialization by calling await KartonAsyncBackend.connect() method.
    • KartonAsyncBackend.s3 returns a ClientCreatorContext instead of Client (needs async with self.s3 as client to get the client object)
  • added KartonBind.is_async attribute to indicate that consumer is asyncio-based, which may be visualized in karton-dashboard.
  • Task.unserialize accepts resource_unserializer Resource factory as an argument to move the creation of RemoteResource objects to the KartonBackend. backend argument is marked as deprecated.
  • asyncio.RemoteResource.content raises RuntimeError when resource was not explicitly downloaded into memory before by calling a download() method.
  • Removed KartonLogHandler.set_task method, current task is always got from task.get_current_task that is using a ContextVar. Generalized KartonBase.log_handler type to generic logging.Handler. Actually we may consider supporting any log_handler as a KartonBase argument in case someone wants to customize the logging (out of scope for this PR)

@psrok1 psrok1 marked this pull request as ready for review June 18, 2025 18:23
Copy link
Member

@nazywam nazywam left a comment

Choose a reason for hiding this comment

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

Few possible issues raised internally, other than that LGTM

@psrok1 psrok1 merged commit 2a2ab27 into master Jun 24, 2025
7 checks passed
@psrok1 psrok1 deleted the feature/asyncio branch June 24, 2025 09:32
@rakovskij-stanislav
Copy link
Contributor

@psrok1, @nazywam Hello! I wonder why you decided to add support of async in karton. What measurable profit did you found with asyncs?

For me, I see only disadvantages:

  • async code is harder to maintain.
  • new features are required to be implemented in both async and sync stacks.

For the second case, it could be better to make sync code as a wrapper of async code, but I am not an expert in these case :)

@psrok1
Copy link
Member Author

psrok1 commented Jul 31, 2025

@rakovskij-stanislav motivation is in the feature documentation: https://karton-core.readthedocs.io/en/latest/asyncio.html.

  • “auto-scalable” Consumers that are waiting for external job to be done for most of the time (e.g. sandbox executors)
  • Producers in asyncio-based projects

it could be better to make sync code as a wrapper of async code, but I am not an expert in these case :)

It's a good strategy if you write async-first code that additionally supports sync operations, but Karton was not that case. The code is less of a problem than the interface: it's easier to use conventions made for async code in sync code than the other way.

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.

3 participants