Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document asyncio support #595

Open
ArtemIsmagilov opened this issue Dec 17, 2023 · 4 comments
Open

Document asyncio support #595

ArtemIsmagilov opened this issue Dec 17, 2023 · 4 comments
Labels
beginner friendly Enhancements or issues that are easy for someone to get started on. help wanted

Comments

@ArtemIsmagilov
Copy link

Need add full examples and info about ASYNCIO in dramatiq

@ArtemIsmagilov ArtemIsmagilov changed the title No info about ASYNCIO in dramatiq(documentation, dramatiq --help coomand, examples) No info about ASYNCIO in dramatiq(documentation, dramatiq --help comand, examples) Dec 17, 2023
@Bogdanp Bogdanp changed the title No info about ASYNCIO in dramatiq(documentation, dramatiq --help comand, examples) Document asyncio support Apr 30, 2024
@Bogdanp Bogdanp added help wanted beginner friendly Enhancements or issues that are easy for someone to get started on. labels Apr 30, 2024
@richarddli
Copy link

I'm happy to help with documentation, but I have to admit I'm confused as to how to get it to work. Getting the synchronous example from the homepage example.py works fine. I then made it async:

@dramatiq.actor
async def count_words(url):
    response = await requests.get(url)
    count = len(response.text.split(" "))
    print(f"There are {count} words at {url!r}.")


if __name__ == "__main__":
    count_words.send(sys.argv[1])

Rerunning this results in a RuntimeException:

[2024-05-29 12:39:03,058] [PID 57175] [Thread-7] [dramatiq.worker.WorkerThread] [ERROR] Failed to process message count_words('https://github.com') with unhandled exception.
Traceback (most recent call last):
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/worker.py", line 487, in process_message
    res = actor(*message.args, **message.kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/actor.py", line 182, in __call__
    return self.fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/asyncio.py", line 63, in wrapper
    raise RuntimeError(
RuntimeError: Global event loop thread not set. Have you added the AsyncIO middleware to your middleware stack?

I believe the proximate cause of this is because before_worker_boot in middleware.asyncio.AsyncIO is not being called, which means the event_loop_thread is not set. However, I don't understand enough of the internals as to why that's the case, as I see from the docs that AsyncIO middleware is enabled by default.

@Bogdanp
Copy link
Owner

Bogdanp commented May 30, 2024

I'm happy to help with documentation, but I have to admit I'm confused as to how to get it to work. Getting the synchronous example from the homepage example.py works fine. I then made it async:

@dramatiq.actor
async def count_words(url):
    response = await requests.get(url)
    count = len(response.text.split(" "))
    print(f"There are {count} words at {url!r}.")


if __name__ == "__main__":
    count_words.send(sys.argv[1])

Rerunning this results in a RuntimeException:

[2024-05-29 12:39:03,058] [PID 57175] [Thread-7] [dramatiq.worker.WorkerThread] [ERROR] Failed to process message count_words('https://github.com') with unhandled exception.
Traceback (most recent call last):
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/worker.py", line 487, in process_message
    res = actor(*message.args, **message.kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/actor.py", line 182, in __call__
    return self.fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rdl/miniconda3/envs/bot/lib/python3.12/site-packages/dramatiq/asyncio.py", line 63, in wrapper
    raise RuntimeError(
RuntimeError: Global event loop thread not set. Have you added the AsyncIO middleware to your middleware stack?

I believe the proximate cause of this is because before_worker_boot in middleware.asyncio.AsyncIO is not being called, which means the event_loop_thread is not set. However, I don't understand enough of the internals as to why that's the case, as I see from the docs that AsyncIO middleware is enabled by default.

The aio middleware is not enabled by default. The list of default middleware is here:

Prometheus, AgeLimit, TimeLimit, ShutdownNotifications, Callbacks, Pipelines, Retries

@richarddli
Copy link

Thanks for clarifying! https://dramatiq.io/reference.html#middleware says "The following middleware is enabled by default" and it has a much longer list of middleware.

@Bogdanp
Copy link
Owner

Bogdanp commented May 30, 2024

Thanks, that does look wrong. We probably added new middleware over time and forgot to update that sentence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beginner friendly Enhancements or issues that are easy for someone to get started on. help wanted
Projects
None yet
Development

No branches or pull requests

3 participants