portal 3.1.2__tar.gz → 3.1.4__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.2/portal.egg-info → portal-3.1.4}/PKG-INFO +1 -1
  2. {portal-3.1.2 → portal-3.1.4}/portal/__init__.py +1 -1
  3. {portal-3.1.2 → portal-3.1.4}/portal/buffers.py +5 -4
  4. {portal-3.1.2 → portal-3.1.4}/portal/client.py +2 -5
  5. {portal-3.1.2 → portal-3.1.4}/portal/client_socket.py +23 -16
  6. {portal-3.1.2 → portal-3.1.4/portal.egg-info}/PKG-INFO +1 -1
  7. {portal-3.1.2 → portal-3.1.4}/LICENSE +0 -0
  8. {portal-3.1.2 → portal-3.1.4}/MANIFEST.in +0 -0
  9. {portal-3.1.2 → portal-3.1.4}/README.md +0 -0
  10. {portal-3.1.2 → portal-3.1.4}/portal/batching.py +0 -0
  11. {portal-3.1.2 → portal-3.1.4}/portal/contextlib.py +0 -0
  12. {portal-3.1.2 → portal-3.1.4}/portal/packlib.py +0 -0
  13. {portal-3.1.2 → portal-3.1.4}/portal/poollib.py +0 -0
  14. {portal-3.1.2 → portal-3.1.4}/portal/process.py +0 -0
  15. {portal-3.1.2 → portal-3.1.4}/portal/server.py +0 -0
  16. {portal-3.1.2 → portal-3.1.4}/portal/server_socket.py +0 -0
  17. {portal-3.1.2 → portal-3.1.4}/portal/sharray.py +0 -0
  18. {portal-3.1.2 → portal-3.1.4}/portal/thread.py +0 -0
  19. {portal-3.1.2 → portal-3.1.4}/portal/utils.py +0 -0
  20. {portal-3.1.2 → portal-3.1.4}/portal.egg-info/SOURCES.txt +0 -0
  21. {portal-3.1.2 → portal-3.1.4}/portal.egg-info/dependency_links.txt +0 -0
  22. {portal-3.1.2 → portal-3.1.4}/portal.egg-info/requires.txt +0 -0
  23. {portal-3.1.2 → portal-3.1.4}/portal.egg-info/top_level.txt +0 -0
  24. {portal-3.1.2 → portal-3.1.4}/pyproject.toml +0 -0
  25. {portal-3.1.2 → portal-3.1.4}/requirements.txt +0 -0
  26. {portal-3.1.2 → portal-3.1.4}/setup.cfg +0 -0
  27. {portal-3.1.2 → portal-3.1.4}/setup.py +0 -0
  28. {portal-3.1.2 → portal-3.1.4}/tests/test_batching.py +0 -0
  29. {portal-3.1.2 → portal-3.1.4}/tests/test_client.py +0 -0
  30. {portal-3.1.2 → portal-3.1.4}/tests/test_errfile.py +0 -0
  31. {portal-3.1.2 → portal-3.1.4}/tests/test_pack.py +0 -0
  32. {portal-3.1.2 → portal-3.1.4}/tests/test_process.py +0 -0
  33. {portal-3.1.2 → portal-3.1.4}/tests/test_server.py +0 -0
  34. {portal-3.1.2 → portal-3.1.4}/tests/test_socket.py +0 -0
  35. {portal-3.1.2 → portal-3.1.4}/tests/test_thread.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.1.2
3
+ Version: 3.1.4
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.2'
1
+ __version__ = '3.1.4'
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
@@ -47,7 +47,7 @@ class Client:
47
47
  def stats(self):
48
48
  now = time.time()
49
49
  stats = {
50
- 'inflight': self._numinflight(),
50
+ 'inflight': len(self.futures),
51
51
  'numsend': self.sendrate[0],
52
52
  'numrecv': self.recvrate[0],
53
53
  'sendrate': self.sendrate[0] / (now - self.sendrate[1]),
@@ -65,7 +65,7 @@ class Client:
65
65
  def call(self, method, *data):
66
66
  reqnum = next(self.reqnum).to_bytes(8, 'little', signed=False)
67
67
  start = time.time()
68
- while self._numinflight() >= self.maxinflight:
68
+ while len(self.futures) >= self.maxinflight:
69
69
  with self.cond: self.cond.wait(timeout=0.2)
70
70
  try:
71
71
  self.socket.require_connection(timeout=0)
@@ -93,9 +93,6 @@ class Client:
93
93
  self.futures.clear()
94
94
  self.socket.close(timeout)
95
95
 
96
- def _numinflight(self):
97
- return len([x for x in self.futures.values() if not x.don])
98
-
99
96
  def _recv(self, data):
100
97
  assert len(data) >= 16, 'Unexpectedly short response'
101
98
  reqnum = bytes(data[:8])
@@ -111,10 +111,11 @@ class ClientSocket:
111
111
  recvbuf = buffers.RecvBuffer(maxsize=self.options.max_msg_size)
112
112
  sel = selectors.DefaultSelector()
113
113
  sock = None
114
+ isconn = False # Local mirror of self.isconn without the lock.
114
115
 
115
- while self.running or (self.sendq and self.isconn.is_set()):
116
+ while self.running or (self.sendq and isconn):
116
117
 
117
- if not self.isconn.is_set():
118
+ if not isconn:
118
119
  if not self.options.autoconn and not self.wantconn.wait(timeout=0.2):
119
120
  continue
120
121
  sock = self._connect()
@@ -122,27 +123,32 @@ class ClientSocket:
122
123
  break
123
124
  sel.register(sock, selectors.EVENT_READ | selectors.EVENT_WRITE)
124
125
  self.isconn.set()
126
+ isconn = True
125
127
  if not self.options.autoconn:
126
128
  self.wantconn.clear()
127
129
  [x() for x in self.callbacks_conn]
128
130
 
129
131
  try:
130
132
 
131
- sel.select(timeout=0.2)
133
+ ready = sel.select(timeout=0.2)
134
+ if not ready:
135
+ continue
136
+ _, mask = ready[0]
132
137
 
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:
138
+ if mask & selectors.EVENT_READ:
139
+ try:
140
+ recvbuf.recv(sock)
141
+ if recvbuf.done():
142
+ if self.recvq.qsize() > self.options.max_recv_queue:
143
+ raise RuntimeError('Too many incoming messages enqueued')
144
+ msg = recvbuf.result()
145
+ self.recvq.put(msg)
146
+ [x(msg) for x in self.callbacks_recv]
147
+ recvbuf = buffers.RecvBuffer(maxsize=self.options.max_msg_size)
148
+ except BlockingIOError:
149
+ pass
150
+
151
+ if self.sendq and mask & selectors.EVENT_WRITE:
146
152
  try:
147
153
  self.sendq[0].send(sock)
148
154
  if self.sendq[0].done():
@@ -155,6 +161,7 @@ class ClientSocket:
155
161
  detail = f'{detail}: {e}' if str(e) else detail
156
162
  self._log(f'Connection to server lost ({detail})')
157
163
  self.isconn.clear()
164
+ isconn = False
158
165
  sel.unregister(sock)
159
166
  sock.close()
160
167
  # Clear message queue on disconnect. There is no meaningful concept of
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: portal
3
- Version: 3.1.2
3
+ Version: 3.1.4
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
File without changes