ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/LWP.pm
Revision: 1.102
Committed: Mon Mar 16 11:12:52 2020 UTC (4 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-6_57, HEAD
Changes since 1.101: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Coro::LWP - make LWP non-blocking - as much as possible
4
5 =head1 SYNOPSIS
6
7 use Coro::LWP; # afterwards LWP should not block
8
9 =head1 ALTERNATIVES
10
11 Over the years, a number of less-invasive alternatives have popped up,
12 which you might find more acceptable than this rather invasive and fragile
13 module. All of them only support HTTP (and sometimes HTTPS).
14
15 =over 4
16
17 =item L<AnyEvent::HTTP>
18
19 Works fine without Coro. Requires using a very different API than
20 LWP. Probably the best choice I<iff> you can do with a completely
21 different event-based API.
22
23 =item L<LWP::Protocol::AnyEvent::http>
24
25 Makes LWP use L<AnyEvent::HTTP>. Does not make LWP event-based, but allows
26 Coro threads to schedule unimpeded through its AnyEvent integration.
27
28 Lets you use the LWP API normally.
29
30 =item L<LWP::Protocol::Coro::http>
31
32 Basically the same as above, distinction unclear. :)
33
34 =item L<AnyEvent::HTTP::LWP::UserAgent>
35
36 A different user agent implementation, not completely transparent to
37 users, requires Coro.
38
39 =back
40
41 =head1 DESCRIPTION
42
43 This module is an L<AnyEvent> user, you need to make sure that you use and
44 run a supported event loop.
45
46 This module tries to make L<LWP|LWP> non-blocking with respect to other
47 coroutines as much as possible, and with whatever means it takes.
48
49 LWP really tries very hard to be blocking (and relies on a lot of
50 undocumented functionality in IO::Socket), so this module had to be very
51 invasive and must be loaded very early to take the proper effect.
52
53 Note that the module L<AnyEvent::HTTP> might offer an alternative to the
54 full L<LWP> that is designed to be non-blocking.
55
56 Here is what it currently does (future versions of LWP might require
57 different tricks):
58
59 =over 4
60
61 =item It loads Coro::Select, overwriting the perl C<select> builtin I<globally>.
62
63 This is necessary because LWP calls select quite often for timeouts and
64 who-knows-what.
65
66 Impact: everybody else uses this (slower) version of select, too. It should be quite
67 compatible to perls builtin select, though.
68
69 =item It overwrites Socket::inet_aton with Coro::Util::inet_aton.
70
71 This is necessary because LWP might (and does) try to resolve hostnames
72 this way.
73
74 Impact: some code might not expect coroutine semantics, for example, when
75 you fork you might prefer the blocking variant because other coroutines
76 shouldn't actually run.
77
78 =item It replaces the base class of Net::HTTP, Net::FTP, Net::NNTP.
79
80 This is necessary because LWP does not always use select to see whether
81 a filehandle can be read/written without blocking, so the base class
82 C<IO::Socket::INET> needs to be replaced by C<Coro::Socket>.
83
84 Impact: Coro::Socket is not at all compatible to IO::Socket::INET. While
85 it duplicates some undocumented functionality required by LWP, it does not
86 have all the methods of IO::Socket::INET and might act quite differently
87 in practise. Also, protocols other than the above mentioned will still block,
88 at least some of the time.
89
90 =back
91
92 All this likely makes other libraries than just LWP not block, but that's
93 just a side effect you cannot rely on.
94
95 Increases parallelism is not supported by all libraries, some might cache
96 data globally.
97
98 =cut
99
100 package Coro::LWP;
101
102 use common::sense;
103
104 BEGIN {
105 # suppress warnings
106 local $^W = 0;
107 require Net::Config;
108 }
109
110 # do it as early as possible
111 use Coro::Select;
112
113 # import these so they can grab Socket::inet_aton
114 use AnyEvent::Util ();
115 use AnyEvent::DNS ();
116
117 use Coro::Util ();
118 use Coro::Socket ();
119 use Coro::AnyEvent ();
120
121 use Socket ();
122
123 use IO::Socket::INET ();
124
125 use Net::HTTP ();
126 use Net::FTP ();
127 use Net::NNTP ();
128
129 our $VERSION = 6.57;
130
131 *Socket::inet_aton = \&Coro::Util::inet_aton;
132
133 for (@Net::HTTP::ISA, @Net::FTP::ISA, @Net::NTTP::ISA) {
134 $_ = Coro::LWP::Socket:: if $_ eq IO::Socket::INET::;
135 }
136
137 package Coro::LWP::Socket;
138
139 no warnings;
140
141 use base Coro::Socket::;
142
143 sub new {
144 my $self = shift;
145
146 $self->SUPER::new (@_, partial => 1)
147 }
148
149 1;
150
151 =head1 AUTHOR/SUPPORT/CONTACT
152
153 Marc A. Lehmann <schmorp@schmorp.de>
154 http://software.schmorp.de/pkg/Coro.html
155
156 =cut
157
158