Skip to content

Commit 9ecefc0

Browse files
authored
Merge pull request #258 from GaneshPatil7517/fix/issue-244-zmq-simtime
Fix: Prepend simtime to ZMQ write() payload for consistency (Issue #244)
2 parents 32248ee + 0e49e15 commit 9ecefc0

2 files changed

Lines changed: 49 additions & 5 deletions

File tree

concore.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ def read(port_identifier, name, initstr_val):
298298
zmq_p = zmq_ports[port_identifier]
299299
try:
300300
message = zmq_p.recv_json_with_retry()
301+
# Strip simtime prefix if present (mirroring file-based read behavior)
302+
if isinstance(message, list) and len(message) > 0:
303+
first_element = message[0]
304+
if isinstance(first_element, (int, float)):
305+
simtime = max(simtime, first_element)
306+
return message[1:]
301307
return message
302308
except zmq.error.ZMQError as e:
303309
logging.error(f"ZMQ read error on port {port_identifier} (name: {name}): {e}. Returning default.")
@@ -365,7 +371,7 @@ def read(port_identifier, name, initstr_val):
365371
def write(port_identifier, name, val, delta=0):
366372
"""
367373
Write data either to ZMQ port or file.
368-
`val` must be list (with simtime prefix) or string.
374+
`val` is the data payload (list or string); write() prepends [simtime + delta] internally.
369375
"""
370376
global simtime
371377

@@ -375,7 +381,13 @@ def write(port_identifier, name, val, delta=0):
375381
try:
376382
# Keep ZMQ payloads JSON-serializable by normalizing numpy types.
377383
zmq_val = convert_numpy_to_python(val)
378-
zmq_p.send_json_with_retry(zmq_val)
384+
if isinstance(zmq_val, list):
385+
# Prepend simtime to match file-based write behavior
386+
payload = [simtime + delta] + zmq_val
387+
zmq_p.send_json_with_retry(payload)
388+
simtime += delta
389+
else:
390+
zmq_p.send_json_with_retry(zmq_val)
379391
except zmq.error.ZMQError as e:
380392
logging.error(f"ZMQ write error on port {port_identifier} (name: {name}): {e}")
381393
except Exception as e:

tests/test_concore.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,43 @@ def send_json_with_retry(self, message):
236236
dummy = DummyPort()
237237
concore.zmq_ports["test_zmq"] = dummy
238238

239+
# Reset simtime for predictable test behavior
240+
concore.simtime = 0
241+
239242
payload = [np.int64(7), np.float64(3.5), {"x": np.float32(1.25)}]
240243
concore.write("test_zmq", "data", payload)
241244

242245
assert dummy.sent is not None
243-
assert dummy.sent == [7, 3.5, {"x": 1.25}]
244-
assert not isinstance(dummy.sent[0], np.generic)
246+
# ZMQ write now prepends simtime (0 in this case) to match file-based write behavior
247+
assert dummy.sent == [0, 7, 3.5, {"x": 1.25}]
248+
# Data values (after simtime) should be converted from numpy types
245249
assert not isinstance(dummy.sent[1], np.generic)
246-
assert not isinstance(dummy.sent[2]["x"], np.generic)
250+
assert not isinstance(dummy.sent[2], np.generic)
251+
assert not isinstance(dummy.sent[3]["x"], np.generic)
252+
253+
def test_zmq_write_read_roundtrip(self):
254+
"""Test that ZMQ write+read returns original data without simtime prefix."""
255+
import concore
256+
257+
class DummyZMQPort:
258+
def __init__(self):
259+
self.buffer = None
260+
261+
def send_json_with_retry(self, message):
262+
self.buffer = message
263+
264+
def recv_json_with_retry(self):
265+
return self.buffer
266+
267+
dummy = DummyZMQPort()
268+
concore.zmq_ports["roundtrip_test"] = dummy
269+
270+
# Reset simtime for predictable test behavior
271+
concore.simtime = 0
272+
273+
original_data = [1.5, 2.5, 3.5]
274+
concore.write("roundtrip_test", "data", original_data)
275+
276+
# Read should return original data (simtime stripped)
277+
result = concore.read("roundtrip_test", "data", "[]")
278+
assert result == original_data

0 commit comments

Comments
 (0)