portal 3.1.3__tar.gz → 3.1.5__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.1.3/portal.egg-info → portal-3.1.5}/PKG-INFO +1 -1
  2. {portal-3.1.3 → portal-3.1.5}/portal/__init__.py +1 -1
  3. {portal-3.1.3 → portal-3.1.5}/portal/buffers.py +5 -4
  4. {portal-3.1.3 → portal-3.1.5}/portal/client_socket.py +22 -20
  5. {portal-3.1.3 → portal-3.1.5}/portal/contextlib.py +1 -0
  6. {portal-3.1.3 → portal-3.1.5}/portal/server_socket.py +1 -0
  7. {portal-3.1.3 → portal-3.1.5/portal.egg-info}/PKG-INFO +1 -1
  8. {portal-3.1.3 → portal-3.1.5}/LICENSE +0 -0
  9. {portal-3.1.3 → portal-3.1.5}/MANIFEST.in +0 -0
  10. {portal-3.1.3 → portal-3.1.5}/README.md +0 -0
  11. {portal-3.1.3 → portal-3.1.5}/portal/batching.py +0 -0
  12. {portal-3.1.3 → portal-3.1.5}/portal/client.py +0 -0
  13. {portal-3.1.3 → portal-3.1.5}/portal/packlib.py +0 -0
  14. {portal-3.1.3 → portal-3.1.5}/portal/poollib.py +0 -0
  15. {portal-3.1.3 → portal-3.1.5}/portal/process.py +0 -0
  16. {portal-3.1.3 → portal-3.1.5}/portal/server.py +0 -0
  17. {portal-3.1.3 → portal-3.1.5}/portal/sharray.py +0 -0
  18. {portal-3.1.3 → portal-3.1.5}/portal/thread.py +0 -0
  19. {portal-3.1.3 → portal-3.1.5}/portal/utils.py +0 -0
  20. {portal-3.1.3 → portal-3.1.5}/portal.egg-info/SOURCES.txt +0 -0
  21. {portal-3.1.3 → portal-3.1.5}/portal.egg-info/dependency_links.txt +0 -0
  22. {portal-3.1.3 → portal-3.1.5}/portal.egg-info/requires.txt +0 -0
  23. {portal-3.1.3 → portal-3.1.5}/portal.egg-info/top_level.txt +0 -0
  24. {portal-3.1.3 → portal-3.1.5}/pyproject.toml +0 -0
  25. {portal-3.1.3 → portal-3.1.5}/requirements.txt +0 -0
  26. {portal-3.1.3 → portal-3.1.5}/setup.cfg +0 -0
  27. {portal-3.1.3 → portal-3.1.5}/setup.py +0 -0
  28. {portal-3.1.3 → portal-3.1.5}/tests/test_batching.py +0 -0
  29. {portal-3.1.3 → portal-3.1.5}/tests/test_client.py +0 -0
  30. {portal-3.1.3 → portal-3.1.5}/tests/test_errfile.py +0 -0
  31. {portal-3.1.3 → portal-3.1.5}/tests/test_pack.py +0 -0
  32. {portal-3.1.3 → portal-3.1.5}/tests/test_process.py +0 -0
  33. {portal-3.1.3 → portal-3.1.5}/tests/test_server.py +0 -0
  34. {portal-3.1.3 → portal-3.1.5}/tests/test_socket.py +0 -0
  35. {portal-3.1.3 → portal-3.1.5}/tests/test_thread.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.1.3
3
+ Version: 3.1.5
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.1.3'
1
+ __version__ = '3.1.5'
2
2
 
3
3
  import multiprocessing as mp
4
4
  try:
@@ -54,7 +54,7 @@ class RecvBuffer:
54
54
 
55
55
  def __init__(self, maxsize):
56
56
  self.maxsize = maxsize
57
- self.lenbuf = bytearray(4)
57
+ self.lenbuf = b''
58
58
  self.buffer = None
59
59
  self.pos = 0
60
60
 
@@ -64,9 +64,10 @@ class RecvBuffer:
64
64
 
65
65
  def recv(self, sock):
66
66
  if self.buffer is None:
67
- size = sock.recv_into(memoryview(self.lenbuf)[self.pos:])
68
- self.pos += max(0, size)
69
- if self.pos == 4:
67
+ part = sock.recv(4 - len(self.lenbuf))
68
+ self.lenbuf += part
69
+ size = len(part)
70
+ if len(self.lenbuf) == 4:
70
71
  length = int.from_bytes(self.lenbuf, 'little', signed=False)
71
72
  assert 1 <= length <= self.maxsize, (1, length, self.maxsize)
72
73
  # We use Numpy to allocate uninitialized memory because Python's
@@ -1,7 +1,7 @@
1
1
  import collections
2
2
  import dataclasses
3
3
  import queue
4
- import selectors
4
+ import select
5
5
  import socket
6
6
  import sys
7
7
  import threading
@@ -109,40 +109,41 @@ class ClientSocket:
109
109
 
110
110
  def _loop(self):
111
111
  recvbuf = buffers.RecvBuffer(maxsize=self.options.max_msg_size)
112
- sel = selectors.DefaultSelector()
113
112
  sock = None
113
+ isconn = False # Local mirror of self.isconn without the lock.
114
114
 
115
- while self.running or (self.sendq and self.isconn.is_set()):
115
+ while self.running or (self.sendq and isconn):
116
116
 
117
- if not self.isconn.is_set():
117
+ if not isconn:
118
118
  if not self.options.autoconn and not self.wantconn.wait(timeout=0.2):
119
119
  continue
120
120
  sock = self._connect()
121
121
  if not sock:
122
122
  break
123
- sel.register(sock, selectors.EVENT_READ | selectors.EVENT_WRITE)
124
123
  self.isconn.set()
124
+ isconn = True
125
125
  if not self.options.autoconn:
126
126
  self.wantconn.clear()
127
127
  [x() for x in self.callbacks_conn]
128
128
 
129
129
  try:
130
130
 
131
- sel.select(timeout=0.2)
131
+ readable, writable, _ = select.select([sock], [sock], [], 0.2)
132
132
 
133
- try:
134
- recvbuf.recv(sock)
135
- if recvbuf.done():
136
- if self.recvq.qsize() > self.options.max_recv_queue:
137
- raise RuntimeError('Too many incoming messages enqueued')
138
- msg = recvbuf.result()
139
- self.recvq.put(msg)
140
- [x(msg) for x in self.callbacks_recv]
141
- recvbuf = buffers.RecvBuffer(maxsize=self.options.max_msg_size)
142
- except BlockingIOError:
143
- pass
144
-
145
- if self.sendq:
133
+ if readable:
134
+ try:
135
+ recvbuf.recv(sock)
136
+ if recvbuf.done():
137
+ if self.recvq.qsize() > self.options.max_recv_queue:
138
+ raise RuntimeError('Too many incoming messages enqueued')
139
+ msg = recvbuf.result()
140
+ self.recvq.put(msg)
141
+ [x(msg) for x in self.callbacks_recv]
142
+ recvbuf = buffers.RecvBuffer(maxsize=self.options.max_msg_size)
143
+ except BlockingIOError:
144
+ pass
145
+
146
+ if self.sendq and writable:
146
147
  try:
147
148
  self.sendq[0].send(sock)
148
149
  if self.sendq[0].done():
@@ -155,7 +156,7 @@ class ClientSocket:
155
156
  detail = f'{detail}: {e}' if str(e) else detail
156
157
  self._log(f'Connection to server lost ({detail})')
157
158
  self.isconn.clear()
158
- sel.unregister(sock)
159
+ isconn = False
159
160
  sock.close()
160
161
  # Clear message queue on disconnect. There is no meaningful concept of
161
162
  # sucessful delivery of a message at this level. For example, the
@@ -206,6 +207,7 @@ class ClientSocket:
206
207
  else:
207
208
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
208
209
  addr = self.addr
210
+ # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
209
211
  after = self.options.keepalive_after
210
212
  every = self.options.keepalive_every
211
213
  fails = self.options.keepalive_fails
@@ -147,6 +147,7 @@ class Context:
147
147
  if self.errfile and self.errfile.exists():
148
148
  print(f'Shutting down due to error file: {self.errfile}')
149
149
  self.shutdown(2)
150
+ break
150
151
  if self.done.wait(self.interval):
151
152
  break
152
153
 
@@ -47,6 +47,7 @@ class ServerSocket:
47
47
  self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
48
48
  self.addr = (self.options.host, port)
49
49
  self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
50
+ # self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
50
51
  self.sock.bind(self.addr)
51
52
  self.sock.setblocking(False)
52
53
  self.sock.listen()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.1.3
3
+ Version: 3.1.5
4
4
  Summary: Fast and reliable distributed systems in Python
5
5
  Home-page: http://github.com/danijar/portal
6
6
  Author: Danijar Hafner
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
File without changes