ominfra 0.0.0.dev129__py3-none-any.whl → 0.0.0.dev130__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ominfra/deploy/_executor.py +15 -0
- ominfra/pyremote/_runcommands.py +15 -0
- ominfra/scripts/journald2aws.py +112 -0
- ominfra/scripts/supervisor.py +1233 -484
- ominfra/supervisor/dispatchers.py +7 -6
- ominfra/supervisor/dispatchersimpl.py +3 -7
- ominfra/supervisor/groups.py +16 -1
- ominfra/supervisor/http.py +130 -0
- ominfra/supervisor/inject.py +44 -5
- ominfra/supervisor/io.py +39 -24
- ominfra/supervisor/processimpl.py +3 -4
- ominfra/supervisor/spawningimpl.py +2 -2
- ominfra/supervisor/supervisor.py +5 -2
- ominfra/supervisor/types.py +6 -56
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/RECORD +20 -20
- ominfra/supervisor/poller.py +0 -240
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev129.dist-info → ominfra-0.0.0.dev130.dist-info}/top_level.txt +0 -0
@@ -22,7 +22,7 @@ ominfra/clouds/aws/journald2aws/poster.py,sha256=hz1XuctW8GtLmfjhRvCFY6py52D4BzX
|
|
22
22
|
ominfra/clouds/gcp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
ominfra/clouds/gcp/auth.py,sha256=3PyfRJNgajjMqJFem3SKui0CqGeHEsZlvbRhuxFcZG8,1348
|
24
24
|
ominfra/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
-
ominfra/deploy/_executor.py,sha256=
|
25
|
+
ominfra/deploy/_executor.py,sha256=3h7ViDW9WtF__sI_qK88SUgldalqdnpf5AlJGbCF9TY,35361
|
26
26
|
ominfra/deploy/configs.py,sha256=qi0kwT7G2NH7dXLOQic-u6R3yeadup_QtvrjwWIggbM,435
|
27
27
|
ominfra/deploy/remote.py,sha256=6ACmpXU1uBdyGs3Xsp97ktKFq30cJlzN9LRWNUWlGY4,2144
|
28
28
|
ominfra/deploy/executor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
@@ -56,38 +56,38 @@ ominfra/journald/tailer.py,sha256=5abcFMfgi7fnY9ZEQe2ZVobaJxjQkeu6d9Kagw33a1w,33
|
|
56
56
|
ominfra/manage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
57
|
ominfra/manage/manage.py,sha256=BttL8LFEknHZE_h2Pt5dAqbfUkv6qy43WI0raXBZ1a8,151
|
58
58
|
ominfra/pyremote/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
ominfra/pyremote/_runcommands.py,sha256=
|
59
|
+
ominfra/pyremote/_runcommands.py,sha256=TfO2cwXbw_1T-c_NDM7K8gWYJbU20Y3k9qEIOM3S6BI,29194
|
60
60
|
ominfra/pyremote/bootstrap.py,sha256=RvMO3YGaN1E4sgUi1JEtiPak8cjvqtc_vRCq1yqbeZg,3370
|
61
61
|
ominfra/pyremote/runcommands.py,sha256=bviS0_TDIoZVAe4h-_iavbvJtVSFu8lnk7fQ5iasCWE,1571
|
62
62
|
ominfra/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
63
|
-
ominfra/scripts/journald2aws.py,sha256=
|
64
|
-
ominfra/scripts/supervisor.py,sha256=
|
63
|
+
ominfra/scripts/journald2aws.py,sha256=FmjNwUPQDCOmIbUxwkN7mNHATf_lXf1uwp0ST71IHFA,131405
|
64
|
+
ominfra/scripts/supervisor.py,sha256=DHvE1h2s57IvHEIZnqsmhx7BrrO20Qbd21IwkQGasmM,242622
|
65
65
|
ominfra/supervisor/LICENSE.txt,sha256=yvqaMNsDhWxziHa9ien6qCW1SkZv-DQlAg96XjfSee8,1746
|
66
66
|
ominfra/supervisor/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
67
67
|
ominfra/supervisor/__main__.py,sha256=I0yFw-C08OOiZ3BF6lF1Oiv789EQXu-_j6whDhQUTEA,66
|
68
68
|
ominfra/supervisor/configs.py,sha256=AhBlbifwDXc0acEhcbdv9jphJL-SBFODFDAWDVckzAE,3945
|
69
|
-
ominfra/supervisor/dispatchers.py,sha256=
|
70
|
-
ominfra/supervisor/dispatchersimpl.py,sha256=
|
69
|
+
ominfra/supervisor/dispatchers.py,sha256=dfjog5PyVAJaFzgFI0tpy38ZgDiFrewMjVi21ksrlAg,1007
|
70
|
+
ominfra/supervisor/dispatchersimpl.py,sha256=k86MSDxIHInOBopYehNuCDcSM_QsxrrGuME0UjnSs_o,11249
|
71
71
|
ominfra/supervisor/events.py,sha256=w3HQFrq-SuroYWoQfNFYeU1phnTvHTgsAqA6TGtAafI,6593
|
72
72
|
ominfra/supervisor/exceptions.py,sha256=Qbu211H3CLlSmi9LsSikOwrcL5HgJP9ugvcKWlGTAoI,750
|
73
|
-
ominfra/supervisor/groups.py,sha256=
|
73
|
+
ominfra/supervisor/groups.py,sha256=MBbsbt8Zh_WEYkGOr1KXa82gnPVw9wPB2lAnqhugXSc,2457
|
74
74
|
ominfra/supervisor/groupsimpl.py,sha256=nIrW4SmB0W6c2jOR_HhkfVcH4eHyLZnG1FJ0MCzc6mQ,2292
|
75
|
-
ominfra/supervisor/
|
76
|
-
ominfra/supervisor/
|
75
|
+
ominfra/supervisor/http.py,sha256=y0tos6zbb4k-WvNQXlgAeK1qi5mKXkyXO9bVJt4OXew,3227
|
76
|
+
ominfra/supervisor/inject.py,sha256=onKUudx5eBbNuXwEqeiaVIIA3ZbpUSDiEAKg9GBiWG8,4514
|
77
|
+
ominfra/supervisor/io.py,sha256=2NO4BYC-PznIrJpTFxN8UEAhd_codfNm_HI424gYQ3c,3294
|
77
78
|
ominfra/supervisor/main.py,sha256=ebe7skFPfwXV2meMVRndhuLZmz-LiuHH1x1CgiarR0o,4132
|
78
79
|
ominfra/supervisor/pipes.py,sha256=XrJ9lD04tPdzZD3xhhYKxpBKHWhZ0Ii315E78bgj7ws,2233
|
79
|
-
ominfra/supervisor/poller.py,sha256=LnQVttPCm8a1UtnDvsho6zLw8NP-2_2VUiNM-d0w_FU,7776
|
80
80
|
ominfra/supervisor/privileges.py,sha256=bO7rJGT7cMOBALK_4D4NiQnOS5dOYb14Sz66R-ymG24,2071
|
81
81
|
ominfra/supervisor/process.py,sha256=UaubVxsxVqDnbuWVpTH0DTGbJGLO0vGJ9mNcvy2kCXM,217
|
82
|
-
ominfra/supervisor/processimpl.py,sha256=
|
82
|
+
ominfra/supervisor/processimpl.py,sha256=vpyRVOYV8_AW5eCtgAa2LKWyW9FiqA5bKmBqF1KYE5c,18715
|
83
83
|
ominfra/supervisor/setup.py,sha256=7HwwwI-WT_Z0WjZ9_l5Orr4K298nKKhQ1f_ZgGsi9TU,622
|
84
84
|
ominfra/supervisor/setupimpl.py,sha256=S_YgCH3XzLsFIAriJROvDMUDh7OzVVJoxzEzCkbb4g4,9648
|
85
85
|
ominfra/supervisor/signals.py,sha256=jY52naUifcAjd6nICTP1ZW3IQSPsHB4cvbsJo8_QV_U,2196
|
86
86
|
ominfra/supervisor/spawning.py,sha256=i1k3tmqWyU-KIN7kel-JVxTVGnLiTIVmZzlstJSZpjM,622
|
87
|
-
ominfra/supervisor/spawningimpl.py,sha256=
|
87
|
+
ominfra/supervisor/spawningimpl.py,sha256=Med8UJH7vP3IaihTJIaqfndhB5mD5wht6Feim674HKs,11161
|
88
88
|
ominfra/supervisor/states.py,sha256=9yoNOSwalRcKEnCP9zG6tVS0oivo5tCeuH6AaaW7Jpc,890
|
89
|
-
ominfra/supervisor/supervisor.py,sha256=
|
90
|
-
ominfra/supervisor/types.py,sha256=
|
89
|
+
ominfra/supervisor/supervisor.py,sha256=XiLVq8qMLKGR50yTgW5njtqVkZCupf-cXDjmh7bJtXQ,9515
|
90
|
+
ominfra/supervisor/types.py,sha256=RamAYEF3fISfKwlIMRleLOFuKVWrxjQJGI6p76jK03c,3959
|
91
91
|
ominfra/supervisor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
92
92
|
ominfra/supervisor/utils/collections.py,sha256=vcfmVYS4QngMdtEI1DvdRIcubmy55Wj40NCzW27_rIY,1361
|
93
93
|
ominfra/supervisor/utils/diag.py,sha256=ujz4gkW7p3wmbaKFM8Hz5eHEwpoUkbB8JeDvcHilCz0,705
|
@@ -103,9 +103,9 @@ ominfra/tailscale/api.py,sha256=C5-t_b6jZXUWcy5k8bXm7CFnk73pSdrlMOgGDeGVrpw,1370
|
|
103
103
|
ominfra/tailscale/cli.py,sha256=DSGp4hn5xwOW-l_u_InKlSF6kIobxtUtVssf_73STs0,3567
|
104
104
|
ominfra/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
105
105
|
ominfra/tools/listresources.py,sha256=4qVg5txsb10EHhvqXXeM6gJ2jx9LbroEnPydDv1uXs0,6176
|
106
|
-
ominfra-0.0.0.
|
107
|
-
ominfra-0.0.0.
|
108
|
-
ominfra-0.0.0.
|
109
|
-
ominfra-0.0.0.
|
110
|
-
ominfra-0.0.0.
|
111
|
-
ominfra-0.0.0.
|
106
|
+
ominfra-0.0.0.dev130.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
107
|
+
ominfra-0.0.0.dev130.dist-info/METADATA,sha256=PjbMdzNCdOt4JYdmoDTM92oJu056qJOvTng2oncmCIU,731
|
108
|
+
ominfra-0.0.0.dev130.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
109
|
+
ominfra-0.0.0.dev130.dist-info/entry_points.txt,sha256=kgecQ2MgGrM9qK744BoKS3tMesaC3yjLnl9pa5CRczg,37
|
110
|
+
ominfra-0.0.0.dev130.dist-info/top_level.txt,sha256=E-b2OHkk_AOBLXHYZQ2EOFKl-_6uOGd8EjeG-Zy6h_w,8
|
111
|
+
ominfra-0.0.0.dev130.dist-info/RECORD,,
|
ominfra/supervisor/poller.py
DELETED
@@ -1,240 +0,0 @@
|
|
1
|
-
# ruff: noqa: UP006 UP007
|
2
|
-
import abc
|
3
|
-
import errno
|
4
|
-
import select
|
5
|
-
import sys
|
6
|
-
import typing as ta
|
7
|
-
|
8
|
-
from omlish.lite.logs import log
|
9
|
-
|
10
|
-
from .setup import DaemonizeListener
|
11
|
-
from .utils.ostypes import Fd
|
12
|
-
|
13
|
-
|
14
|
-
class Poller(DaemonizeListener, abc.ABC):
|
15
|
-
def __init__(self) -> None:
|
16
|
-
super().__init__()
|
17
|
-
|
18
|
-
@abc.abstractmethod
|
19
|
-
def register_readable(self, fd: Fd) -> None:
|
20
|
-
raise NotImplementedError
|
21
|
-
|
22
|
-
@abc.abstractmethod
|
23
|
-
def register_writable(self, fd: Fd) -> None:
|
24
|
-
raise NotImplementedError
|
25
|
-
|
26
|
-
@abc.abstractmethod
|
27
|
-
def unregister_readable(self, fd: Fd) -> None:
|
28
|
-
raise NotImplementedError
|
29
|
-
|
30
|
-
@abc.abstractmethod
|
31
|
-
def unregister_writable(self, fd: Fd) -> None:
|
32
|
-
raise NotImplementedError
|
33
|
-
|
34
|
-
@abc.abstractmethod
|
35
|
-
def poll(self, timeout: ta.Optional[float]) -> ta.Tuple[ta.List[Fd], ta.List[Fd]]:
|
36
|
-
raise NotImplementedError
|
37
|
-
|
38
|
-
def before_daemonize(self) -> None: # noqa
|
39
|
-
pass
|
40
|
-
|
41
|
-
def after_daemonize(self) -> None: # noqa
|
42
|
-
pass
|
43
|
-
|
44
|
-
def close(self) -> None: # noqa
|
45
|
-
pass
|
46
|
-
|
47
|
-
|
48
|
-
class SelectPoller(Poller):
|
49
|
-
def __init__(self) -> None:
|
50
|
-
super().__init__()
|
51
|
-
|
52
|
-
self._readable: ta.Set[Fd] = set()
|
53
|
-
self._writable: ta.Set[Fd] = set()
|
54
|
-
|
55
|
-
def register_readable(self, fd: Fd) -> None:
|
56
|
-
self._readable.add(fd)
|
57
|
-
|
58
|
-
def register_writable(self, fd: Fd) -> None:
|
59
|
-
self._writable.add(fd)
|
60
|
-
|
61
|
-
def unregister_readable(self, fd: Fd) -> None:
|
62
|
-
self._readable.discard(fd)
|
63
|
-
|
64
|
-
def unregister_writable(self, fd: Fd) -> None:
|
65
|
-
self._writable.discard(fd)
|
66
|
-
|
67
|
-
def unregister_all(self) -> None:
|
68
|
-
self._readable.clear()
|
69
|
-
self._writable.clear()
|
70
|
-
|
71
|
-
def poll(self, timeout: ta.Optional[float]) -> ta.Tuple[ta.List[Fd], ta.List[Fd]]:
|
72
|
-
try:
|
73
|
-
r, w, x = select.select(
|
74
|
-
self._readable,
|
75
|
-
self._writable,
|
76
|
-
[], timeout,
|
77
|
-
)
|
78
|
-
except OSError as exc:
|
79
|
-
if exc.args[0] == errno.EINTR:
|
80
|
-
log.debug('EINTR encountered in poll')
|
81
|
-
return [], []
|
82
|
-
if exc.args[0] == errno.EBADF:
|
83
|
-
log.debug('EBADF encountered in poll')
|
84
|
-
self.unregister_all()
|
85
|
-
return [], []
|
86
|
-
raise
|
87
|
-
return r, w
|
88
|
-
|
89
|
-
|
90
|
-
class PollPoller(Poller):
|
91
|
-
_READ = select.POLLIN | select.POLLPRI | select.POLLHUP
|
92
|
-
_WRITE = select.POLLOUT
|
93
|
-
|
94
|
-
def __init__(self) -> None:
|
95
|
-
super().__init__()
|
96
|
-
|
97
|
-
self._poller = select.poll()
|
98
|
-
self._readable: set[Fd] = set()
|
99
|
-
self._writable: set[Fd] = set()
|
100
|
-
|
101
|
-
def register_readable(self, fd: Fd) -> None:
|
102
|
-
self._poller.register(fd, self._READ)
|
103
|
-
self._readable.add(fd)
|
104
|
-
|
105
|
-
def register_writable(self, fd: Fd) -> None:
|
106
|
-
self._poller.register(fd, self._WRITE)
|
107
|
-
self._writable.add(fd)
|
108
|
-
|
109
|
-
def unregister_readable(self, fd: Fd) -> None:
|
110
|
-
self._readable.discard(fd)
|
111
|
-
self._poller.unregister(fd)
|
112
|
-
if fd in self._writable:
|
113
|
-
self._poller.register(fd, self._WRITE)
|
114
|
-
|
115
|
-
def unregister_writable(self, fd: Fd) -> None:
|
116
|
-
self._writable.discard(fd)
|
117
|
-
self._poller.unregister(fd)
|
118
|
-
if fd in self._readable:
|
119
|
-
self._poller.register(fd, self._READ)
|
120
|
-
|
121
|
-
def poll(self, timeout: ta.Optional[float]) -> ta.Tuple[ta.List[Fd], ta.List[Fd]]:
|
122
|
-
fds = self._poll_fds(timeout) # type: ignore
|
123
|
-
readable, writable = [], []
|
124
|
-
for fd, eventmask in fds:
|
125
|
-
if self._ignore_invalid(fd, eventmask):
|
126
|
-
continue
|
127
|
-
if eventmask & self._READ:
|
128
|
-
readable.append(fd)
|
129
|
-
if eventmask & self._WRITE:
|
130
|
-
writable.append(fd)
|
131
|
-
return readable, writable
|
132
|
-
|
133
|
-
def _poll_fds(self, timeout: float) -> ta.List[ta.Tuple[Fd, Fd]]:
|
134
|
-
try:
|
135
|
-
return self._poller.poll(timeout * 1000) # type: ignore
|
136
|
-
except OSError as exc:
|
137
|
-
if exc.args[0] == errno.EINTR:
|
138
|
-
log.debug('EINTR encountered in poll')
|
139
|
-
return []
|
140
|
-
raise
|
141
|
-
|
142
|
-
def _ignore_invalid(self, fd: Fd, eventmask: int) -> bool:
|
143
|
-
if eventmask & select.POLLNVAL:
|
144
|
-
# POLLNVAL means `fd` value is invalid, not open. When a process quits it's `fd`s are closed so there is no
|
145
|
-
# more reason to keep this `fd` registered If the process restarts it's `fd`s are registered again.
|
146
|
-
self._poller.unregister(fd)
|
147
|
-
self._readable.discard(fd)
|
148
|
-
self._writable.discard(fd)
|
149
|
-
return True
|
150
|
-
return False
|
151
|
-
|
152
|
-
|
153
|
-
if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
|
154
|
-
class KqueuePoller(Poller):
|
155
|
-
max_events = 1000
|
156
|
-
|
157
|
-
def __init__(self) -> None:
|
158
|
-
super().__init__()
|
159
|
-
|
160
|
-
self._kqueue: ta.Optional[ta.Any] = select.kqueue()
|
161
|
-
self._readable: set[Fd] = set()
|
162
|
-
self._writable: set[Fd] = set()
|
163
|
-
|
164
|
-
def register_readable(self, fd: Fd) -> None:
|
165
|
-
self._readable.add(fd)
|
166
|
-
kevent = select.kevent(fd, filter=select.KQ_FILTER_READ, flags=select.KQ_EV_ADD)
|
167
|
-
self._kqueue_control(fd, kevent)
|
168
|
-
|
169
|
-
def register_writable(self, fd: Fd) -> None:
|
170
|
-
self._writable.add(fd)
|
171
|
-
kevent = select.kevent(fd, filter=select.KQ_FILTER_WRITE, flags=select.KQ_EV_ADD)
|
172
|
-
self._kqueue_control(fd, kevent)
|
173
|
-
|
174
|
-
def unregister_readable(self, fd: Fd) -> None:
|
175
|
-
kevent = select.kevent(fd, filter=select.KQ_FILTER_READ, flags=select.KQ_EV_DELETE)
|
176
|
-
self._readable.discard(fd)
|
177
|
-
self._kqueue_control(fd, kevent)
|
178
|
-
|
179
|
-
def unregister_writable(self, fd: Fd) -> None:
|
180
|
-
kevent = select.kevent(fd, filter=select.KQ_FILTER_WRITE, flags=select.KQ_EV_DELETE)
|
181
|
-
self._writable.discard(fd)
|
182
|
-
self._kqueue_control(fd, kevent)
|
183
|
-
|
184
|
-
def _kqueue_control(self, fd: Fd, kevent: 'select.kevent') -> None:
|
185
|
-
try:
|
186
|
-
self._kqueue.control([kevent], 0) # type: ignore
|
187
|
-
except OSError as error:
|
188
|
-
if error.errno == errno.EBADF:
|
189
|
-
log.debug('EBADF encountered in kqueue. Invalid file descriptor %s', fd)
|
190
|
-
else:
|
191
|
-
raise
|
192
|
-
|
193
|
-
def poll(self, timeout: ta.Optional[float]) -> ta.Tuple[ta.List[Fd], ta.List[Fd]]:
|
194
|
-
readable, writable = [], [] # type: ignore
|
195
|
-
|
196
|
-
try:
|
197
|
-
kevents = self._kqueue.control(None, self.max_events, timeout) # type: ignore
|
198
|
-
except OSError as error:
|
199
|
-
if error.errno == errno.EINTR:
|
200
|
-
log.debug('EINTR encountered in poll')
|
201
|
-
return readable, writable
|
202
|
-
raise
|
203
|
-
|
204
|
-
for kevent in kevents:
|
205
|
-
if kevent.filter == select.KQ_FILTER_READ:
|
206
|
-
readable.append(kevent.ident)
|
207
|
-
if kevent.filter == select.KQ_FILTER_WRITE:
|
208
|
-
writable.append(kevent.ident)
|
209
|
-
|
210
|
-
return readable, writable
|
211
|
-
|
212
|
-
def before_daemonize(self) -> None:
|
213
|
-
self.close()
|
214
|
-
|
215
|
-
def after_daemonize(self) -> None:
|
216
|
-
self._kqueue = select.kqueue()
|
217
|
-
for fd in self._readable:
|
218
|
-
self.register_readable(fd)
|
219
|
-
for fd in self._writable:
|
220
|
-
self.register_writable(fd)
|
221
|
-
|
222
|
-
def close(self) -> None:
|
223
|
-
self._kqueue.close() # type: ignore
|
224
|
-
self._kqueue = None
|
225
|
-
|
226
|
-
else:
|
227
|
-
KqueuePoller = None
|
228
|
-
|
229
|
-
|
230
|
-
def get_poller_impl() -> ta.Type[Poller]:
|
231
|
-
if (
|
232
|
-
(sys.platform == 'darwin' or sys.platform.startswith('freebsd')) and
|
233
|
-
hasattr(select, 'kqueue') and
|
234
|
-
KqueuePoller is not None
|
235
|
-
):
|
236
|
-
return KqueuePoller
|
237
|
-
elif hasattr(select, 'poll'):
|
238
|
-
return PollPoller
|
239
|
-
else:
|
240
|
-
return SelectPoller
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|