-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
First sample is lost #89
Comments
That was not a great bug report. I have narrowed it down a bit, but understand nothing. See the following scripts (order of starting doesn't matter). send.py import random
import time
from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop
# out stream
info = StreamInfo('Wally_finder', 'Wally_master', 1, 0, "string", "myuidw43536")
outlet = StreamOutlet(info)
# return/answer stream
streams = resolve_byprop("type", "Wally_client")
inlet = StreamInlet(streams[0])
markernames = ["Test", "Blah", "Marker", "XXX", "Testtest", "Test-1-2-3"]
while True:
# send a random sample
msg = random.choice(markernames)
outlet.push_sample([msg])
# wait for reply
t0 = time.monotonic()
sample, timestamp = inlet.pull_sample()
if sample:
print("sent %s, got %s at time %s" % (msg, sample[0], timestamp))
else:
print('sent %s, got nothing' % (msg))
# throttle
time.sleep(max(0.,t0+1-time.monotonic())) receive.py from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop
import time
def send(msg, outlet):
print(f'sending: {msg}')
outlet.push_sample([msg])
# first resolve stream from which we receive requests
print("looking for a marker stream...")
streams = resolve_byprop("type", "Wally_master")
inlet = StreamInlet(streams[0])
# open answer stream
info = StreamInfo('Wally_finder', 'Wally_client', 1, 0, "string", "fdg")
outlet = StreamOutlet(info)
time.sleep(1)
for _ in range(1):
send('warm up', outlet)
while True:
# wait to receive a request
sample, timestamp = inlet.pull_sample(timeout=0.0)
if sample:
# reply with the same string
send(sample[0], outlet)
#time.sleep(1) Note that there are two sleeps in receive.py, one after opening the outlet, and one in the loop. With the one after opening the outlet active, and the loop commented out, i get the following output from send.py:
and receive.py:
As you see, receive never got the first sample from send, but the warm up message sent earlier is picked up by send. With the sleep in the loop active and the one after opening the outlet commented out, the output is:
receive.py:
So, all main messages are ping ponged, but the warm up message is lost. This could work as a workaround, were it not for the below: If i now shorten the sleep in the loop in receive.py to something shorter than .1 s (haven't really narrowed it down), like 0.01 s, and add a timeout to send.py's sample pull (
receive.py:
So now both "warm up" and the first reply ("Blah") are lost. What is going on here? How to get this to work reliably? Adding a |
one further note. I just saw i was using pylsl 1.15.0. Upgrading to 1.16.2 changes nothing. |
Ok, now maybe we're getting to some diagnosis. Consider the following: send.py: import random
import time
from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop
# out stream
info = StreamInfo('Wally_finder', 'Wally_master', 1, 0, "string", "myuidw43536")
outlet = StreamOutlet(info)
# return/answer stream
streams = resolve_byprop("type", "Wally_client")
inlet = StreamInlet(streams[0])
markernames = ["Test", "Blah", "Marker", "XXX", "Testtest", "Test-1-2-3"]
while True:
# send a random sample
msg = random.choice(markernames)
hc = outlet.have_consumers()
outlet.push_sample([msg])
# wait for reply
t0 = time.monotonic()
sample, timestamp = inlet.pull_sample(timeout=.1)
if sample:
print("sent %s, got %s at time %s (have consumers: %d)" % (msg, sample[0], timestamp, hc))
else:
print('sent %s, got nothing (have consumers: %d)' % (msg, hc))
# throttle
time.sleep(max(0.,t0+1-time.monotonic())) receive.py: from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop
def send(msg, outlet: StreamOutlet):
print(f'sending: {msg}, have consumers: {outlet.have_consumers()}')
outlet.push_sample([msg])
# first resolve stream from which we receive requests
streams = resolve_byprop("type", "Wally_master")
inlet = StreamInlet(streams[0])
# open answer stream
info = StreamInfo('Wally_finder', 'Wally_client', 1, 0, "string", "fdg")
outlet = StreamOutlet(info)
while True:
# wait to receive a request
sample, timestamp = inlet.pull_sample(timeout=0.1)
if sample:
# reply with the same string
send(sample[0], outlet) That is, i got rid of all the sleeps, and added a check whether the outlet has any consumer (which it should, since both outlets have a registered inlet on the other side). output of send.py:
output of receive.py:
So, the first reply of receiver.py is not sent as there are no registered consumers for its output stream. So i thought maybe its the ordering of the inlet and outlet creation. If i change receive.py to first open its outlet as well, like this: from pylsl import StreamInfo, StreamOutlet, StreamInlet, resolve_byprop
def send(msg, outlet: StreamOutlet):
print(f'sending: {msg}, have consumers: {outlet.have_consumers()}')
outlet.push_sample([msg])
# open answer stream
info = StreamInfo('Wally_finder', 'Wally_client', 1, 0, "string", "fdg")
outlet = StreamOutlet(info)
# first resolve stream from which we receive requests
streams = resolve_byprop("type", "Wally_master")
inlet = StreamInlet(streams[0])
while True:
# wait to receive a request
sample, timestamp = inlet.pull_sample(timeout=0.1)
if sample:
# reply with the same string
send(sample[0], outlet) we get the following output:
output of receive.py:
So no, that just moves the problem. Adding a 1s sleep in both scripts after creating the inlet changes nothing in the output. Is this expected behavior? How do i get this bi-directional communication to work reliably? |
This is similar to #95.
I have simplified the working example code from there to the code posted at the end, which still works fine.
However, an almost the same example always loses the first sample on the return leg. this is the code
send.py:
receive.py:
Here some example output i get from send.py. The first reply sample, as shown in this example, is always missing, regardless of whether i start send.py or receive.py first:
receive.py output in the mean time:
Note that sending one or many earlier warm up packets also doesn't matter, they are also lost. I am not sure how this is different from the example code from #85, nor why it is possible to lose samples at all. That shouldn't be possible, right?
example code from #85 (works):
ping.py
pong.py:
The text was updated successfully, but these errors were encountered: