Skip to content

Commit 4032c29

Browse files
authored
Merge pull request #49 from open-ephys/development
Add callable stop flag to `EventListener` class
2 parents dbe1267 + 690c5ed commit 4032c29

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/open_ephys/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "1.0.0"
1+
__version__ = "1.0.1"

src/open_ephys/streaming/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,30 @@ stream.start(ttl_callback=ttl_callback,
8585

8686
To stop listening, press `ctrl-C`.
8787

88+
89+
### Running the event listener in a separate thread
90+
91+
To receive and respond to events in a separate thread, you can use the Python `threading` library:
92+
93+
```python
94+
import threading
95+
from open_ephys.streaming import EventListener
96+
97+
stream = EventListener(port=5557)
98+
99+
thread = threading.Thread(
100+
target = stream.start,
101+
args = (ttl_callback, spike_callback), # Arguments to the target function
102+
daemon = True # Ensures the main program doesn't exit when the thread finishes
103+
)
104+
105+
thread.start()
106+
```
107+
108+
To stop listening, call the `EventListener.stop()` method, and allow the thread to shut down gracefully by calling `thread.join()`:
109+
110+
```python
111+
stream.stop()
112+
thread.join()
113+
```
114+

src/open_ephys/streaming/event_listener.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import zmq
2626
import json
27+
import threading
2728

2829

2930
def default_spike_callback(info):
@@ -99,6 +100,8 @@ def __init__(self, ip_address="127.0.0.1", port=5557):
99100
self.socket = self.context.socket(zmq.SUB)
100101
self.socket.connect(self.url)
101102
self.socket.setsockopt(zmq.SUBSCRIBE, b"")
103+
self.socket.setsockopt(zmq.RCVTIMEO, 1000) # 1 second timeout
104+
self._stop_event = threading.Event()
102105

103106
print("Initialized EventListener at " + self.url)
104107

@@ -120,8 +123,9 @@ def start(
120123
"""
121124

122125
print("Starting EventListener")
126+
self._stop_event.clear() # Clear stop event
123127

124-
while True:
128+
while not self._stop_event.is_set():
125129
try:
126130
parts = self.socket.recv_multipart()
127131

@@ -133,7 +137,18 @@ def start(
133137
spike_callback(info)
134138
else:
135139
ttl_callback(info)
136-
140+
except zmq.Again:
141+
# Timeout occurred, continue loop to check stop flag
142+
continue
137143
except KeyboardInterrupt:
138-
print() # Add final newline
144+
print("Stopped by KeyboardInterrupt")
145+
break
146+
except Exception as e:
147+
print(f"Error: {e}")
139148
break
149+
150+
print("EventListener stopped")
151+
152+
def stop(self):
153+
"""Call this method to stop the listener"""
154+
self._stop_event.set()

0 commit comments

Comments
 (0)