portal 3.2.1__tar.gz → 3.2.3__tar.gz

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.
Files changed (35) hide show
  1. {portal-3.2.1/portal.egg-info → portal-3.2.3}/PKG-INFO +1 -1
  2. {portal-3.2.1 → portal-3.2.3}/portal/__init__.py +1 -1
  3. {portal-3.2.1 → portal-3.2.3}/portal/client_socket.py +13 -12
  4. {portal-3.2.1 → portal-3.2.3}/portal/contextlib.py +7 -1
  5. {portal-3.2.1 → portal-3.2.3}/portal/utils.py +8 -2
  6. {portal-3.2.1 → portal-3.2.3/portal.egg-info}/PKG-INFO +1 -1
  7. {portal-3.2.1 → portal-3.2.3}/tests/test_client.py +17 -0
  8. {portal-3.2.1 → portal-3.2.3}/tests/test_server.py +2 -2
  9. {portal-3.2.1 → portal-3.2.3}/LICENSE +0 -0
  10. {portal-3.2.1 → portal-3.2.3}/MANIFEST.in +0 -0
  11. {portal-3.2.1 → portal-3.2.3}/README.md +0 -0
  12. {portal-3.2.1 → portal-3.2.3}/portal/batching.py +0 -0
  13. {portal-3.2.1 → portal-3.2.3}/portal/buffers.py +0 -0
  14. {portal-3.2.1 → portal-3.2.3}/portal/client.py +0 -0
  15. {portal-3.2.1 → portal-3.2.3}/portal/packlib.py +0 -0
  16. {portal-3.2.1 → portal-3.2.3}/portal/poollib.py +0 -0
  17. {portal-3.2.1 → portal-3.2.3}/portal/process.py +0 -0
  18. {portal-3.2.1 → portal-3.2.3}/portal/server.py +0 -0
  19. {portal-3.2.1 → portal-3.2.3}/portal/server_socket.py +0 -0
  20. {portal-3.2.1 → portal-3.2.3}/portal/sharray.py +0 -0
  21. {portal-3.2.1 → portal-3.2.3}/portal/thread.py +0 -0
  22. {portal-3.2.1 → portal-3.2.3}/portal.egg-info/SOURCES.txt +0 -0
  23. {portal-3.2.1 → portal-3.2.3}/portal.egg-info/dependency_links.txt +0 -0
  24. {portal-3.2.1 → portal-3.2.3}/portal.egg-info/requires.txt +0 -0
  25. {portal-3.2.1 → portal-3.2.3}/portal.egg-info/top_level.txt +0 -0
  26. {portal-3.2.1 → portal-3.2.3}/pyproject.toml +0 -0
  27. {portal-3.2.1 → portal-3.2.3}/requirements.txt +0 -0
  28. {portal-3.2.1 → portal-3.2.3}/setup.cfg +0 -0
  29. {portal-3.2.1 → portal-3.2.3}/setup.py +0 -0
  30. {portal-3.2.1 → portal-3.2.3}/tests/test_batching.py +0 -0
  31. {portal-3.2.1 → portal-3.2.3}/tests/test_errfile.py +0 -0
  32. {portal-3.2.1 → portal-3.2.3}/tests/test_pack.py +0 -0
  33. {portal-3.2.1 → portal-3.2.3}/tests/test_process.py +0 -0
  34. {portal-3.2.1 → portal-3.2.3}/tests/test_socket.py +0 -0
  35. {portal-3.2.1 → portal-3.2.3}/tests/test_thread.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.2.1
3
+ Version: 3.2.3
4
4
  Summary: Fast and reliable distributed systems in Python
5
5
  Home-page: http://github.com/danijar/portal
6
6
  Author: Danijar Hafner
@@ -1,4 +1,4 @@
1
- __version__ = '3.2.1'
1
+ __version__ = '3.2.3'
2
2
 
3
3
  import multiprocessing as mp
4
4
  try:
@@ -34,11 +34,11 @@ class Options:
34
34
  class ClientSocket:
35
35
 
36
36
  def __init__(self, host, port=None, name='Client', start=True, **kwargs):
37
- assert (port or ':' in host) and '://' not in host, host
37
+ assert port or ':' in host, (host, port)
38
+ assert '://' not in host, (host, port)
38
39
  if port is None:
39
40
  host, port = host.rsplit(':', 1)
40
- port = int(port)
41
- assert host, host
41
+ assert host and port, (host, port)
42
42
  self.addr = (host, port)
43
43
  self.name = name
44
44
  self.options = Options(**{**contextlib.context.clientkw, **kwargs})
@@ -179,16 +179,19 @@ class ClientSocket:
179
179
  sock.close()
180
180
 
181
181
  def _connect(self):
182
- host, port = self.addr
183
- self._log(f'Connecting to {host}:{port}')
182
+ self._log(f'Connecting to {self.addr[0]}:{self.addr[1]}')
184
183
  once = True
185
184
  while self.running:
186
- sock, addr = self._create()
185
+ # We need to resolve the address regularly.
186
+ host, port = self.addr
187
+ if contextlib.context.resolver:
188
+ host, port = contextlib.context.resolver((host, port))
189
+ assert isinstance(host, str), (host, port)
190
+ assert isinstance(port, int), (host, port)
191
+ addr = (host, port, 0, 0) if self.options.ipv6 else (host, port)
192
+ sock = self._create()
187
193
  error = None
188
194
  try:
189
- # We need to resolve the address regularly.
190
- if contextlib.context.resolver:
191
- addr = contextlib.context.resolver(addr)
192
195
  sock.settimeout(10)
193
196
  sock.connect(addr)
194
197
  sock.settimeout(0)
@@ -210,10 +213,8 @@ class ClientSocket:
210
213
  def _create(self):
211
214
  if self.options.ipv6:
212
215
  sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
213
- addr = (*self.addr, 0, 0)
214
216
  else:
215
217
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
216
- addr = self.addr
217
218
  # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
218
219
  after = self.options.keepalive_after
219
220
  every = self.options.keepalive_every
@@ -231,7 +232,7 @@ class ClientSocket:
231
232
  sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPALIVE, every)
232
233
  if sys.platform == 'win32':
233
234
  sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, after * 1000, every * 1000))
234
- return sock, addr
235
+ return sock
235
236
 
236
237
  def _log(self, *args):
237
238
  if not self.options.logging:
@@ -4,6 +4,7 @@ import pathlib
4
4
  import sys
5
5
  import threading
6
6
  import traceback
7
+ import warnings
7
8
 
8
9
  import cloudpickle
9
10
  import psutil
@@ -143,7 +144,12 @@ class Context:
143
144
  return
144
145
  if hasattr(worker, 'thread'):
145
146
  assert current != worker.thread
146
- current.children.append(worker)
147
+ try:
148
+ current.children.append(worker)
149
+ except AttributeError:
150
+ warnings.warn(
151
+ 'Using Portal from plain Python threads is discouraged because ' +
152
+ 'they can cause hangs during shutdown.')
147
153
 
148
154
  def children(self, thread):
149
155
  current = thread or threading.current_thread()
@@ -8,6 +8,8 @@ import time
8
8
 
9
9
  import psutil
10
10
 
11
+ from . import contextlib
12
+
11
13
 
12
14
  def run(workers, duration=None):
13
15
  [None if x.started else x.start() for x in workers]
@@ -96,9 +98,13 @@ def free_port():
96
98
  # Return a port that is currently free. This function is not thread or
97
99
  # process safe, because there is no way to guarantee that the port will still
98
100
  # be free at the time it will be used.
99
- sock = socket.socket()
101
+ if contextlib.context.serverkw.get('ipv6', False):
102
+ family, addr = socket.AF_INET6, ('localhost', 0, 0, 0)
103
+ else:
104
+ family, addr = socket.AF_INET, ('localhost', 0)
105
+ sock = socket.socket(family, socket.SOCK_STREAM)
100
106
  sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
101
- sock.bind(('localhost', 0))
107
+ sock.bind(addr)
102
108
  port = sock.getsockname()[1]
103
109
  sock.close()
104
110
  return port
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.2.1
3
+ Version: 3.2.3
4
4
  Summary: Fast and reliable distributed systems in Python
5
5
  Home-page: http://github.com/danijar/portal
6
6
  Author: Danijar Hafner
@@ -321,3 +321,20 @@ class TestClient:
321
321
  portal.Thread(server),
322
322
  portal.Thread(client),
323
323
  ])
324
+
325
+ def test_resolver(self):
326
+ portnum = portal.free_port()
327
+
328
+ def client(portnum):
329
+ def resolver(host, portstr):
330
+ assert portstr == 'name'
331
+ return host, portnum
332
+ portal.setup(resolver=resolver)
333
+ client = portal.Client('localhost:name')
334
+ assert client.fn(42).result() == 42
335
+
336
+ server = portal.Server(portnum)
337
+ server.bind('fn', lambda x: x)
338
+ server.start(block=False)
339
+ portal.Process(client, portnum, start=True).join()
340
+ server.close()
@@ -199,7 +199,7 @@ class TestServer:
199
199
  def test_shared_pool(self, repeat, Server):
200
200
 
201
201
  def slow(x):
202
- time.sleep(0.2)
202
+ time.sleep(0.5)
203
203
  return x
204
204
 
205
205
  def fast(x):
@@ -226,7 +226,7 @@ class TestServer:
226
226
  def test_separate_pools(self, repeat, Server):
227
227
 
228
228
  def slow(x):
229
- time.sleep(0.1)
229
+ time.sleep(0.5)
230
230
  return x
231
231
 
232
232
  def fast(x):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes