LWP(3pm)

πŸ’– NAME πŸ’–

Coro::LWP β€” bestie, it makes LWP non-blocking... as much as it possibly can 🫢


✨ SYNOPSIS ✨

use Coro::LWP; # afterwards LWP should not block

That's it. That's the whole ritual. One use, and boom πŸ’…


πŸ¦‹ ALTERNATIVES πŸ¦‹

Okay so lowkey? Over the years a bunch of less invasive alternatives have popped up, and ngl you might find some of them way more acceptable than this one β€” because this module is, and I say this with love, rather invasive and fragile. πŸ™ˆ Every single one of these only supports HTTP (and sometimes HTTPS), just so you know.

  • AnyEvent::HTTP β€” works totally fine without Coro, no cap. But it requires a very different API than LWP. Probably the best choice iff you can deal with a completely different event-based API.
  • LWP::Protocol::AnyEvent::http β€” makes LWP use AnyEvent::HTTP. It does not make LWP event-based, but it does let Coro threads schedule unimpeded through its AnyEvent integration. And the best part? You get to use the LWP API normally. Iconic πŸŽ€
  • LWP::Protocol::Coro::http β€” basically the same as the one above, distinction unclear. :) (her words, not mine πŸ’€)
  • AnyEvent::HTTP::LWP::UserAgent β€” a whole different user agent implementation. Not completely transparent to users, and it requires Coro.

🌸 DESCRIPTION 🌸

This module is an AnyEvent user, so you need to make sure you use and run a supported event loop. Periodt.

So here's the vibe: this module tries to make LWP non-blocking with respect to other coroutines, as much as possible, and with whatever means it takes. 😀

And the thing is β€” LWP really tries very hard to be blocking (it relies on a whole lot of undocumented functionality in IO::Socket), so this module had to be super invasive and it must be loaded very early to take the proper effect. Load it late and it's giving nothing, bestie. 😭

Also note: the module AnyEvent::HTTP might offer an alternative to the full LWP that's actually designed to be non-blocking. Just saying. πŸ‘€

Here's what it currently does (future versions of LWP might require different tricks, iykyk):

  • It loads Coro::Select, overwriting the perl select builtin globally.
    • This is necessary because LWP calls select quite often for timeouts and who-knows-what.
    • Impact: everybody else uses this (slower) version of select, too. It should be quite compatible with perl's builtin select, though.
  • It overwrites Socket::inet_aton with Coro::Util::inet_aton.
    • This is necessary because LWP might (and does) try to resolve hostnames this way.
    • Impact: some code might not expect coroutine semantics. For example, when you fork you might prefer the blocking variant, because other coroutines shouldn't actually run.
  • It replaces the base class of Net::HTTP, Net::FTP, Net::NNTP.
    • This is necessary because LWP does not always use select to see whether a filehandle can be read/written without blocking, so the base class IO::Socket::INET needs to be replaced by Coro::Socket.
    • Impact: Coro::Socket is not at all compatible with IO::Socket::INET. While it duplicates some undocumented functionality required by LWP, it does not have all the methods of IO::Socket::INET and might act quite differently in practise. Also, protocols other than the ones mentioned above will still block, at least some of the time. πŸ’€
All this likely makes other libraries than just LWP not block, but that's just a side effect you cannot rely on. 🚫
"Increases parallelism" is not supported by all libraries β€” some might cache data globally. πŸ™ƒ

πŸ‘‘ AUTHOR/SUPPORT/CONTACT πŸ‘‘


Okay that's the whole page bestie, you ate it up πŸ“ This lil masterpiece ships with perl v5.40.1, dated 2025-03-21, and it's part of the User Contributed Perl Documentation β€” go forth and be non-blocking, you main character πŸŒˆπŸ’…

πŸ“¦ where this page comes from