Skip to content
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

Strange Behavior in dispatchEventQueue() #46

Open
Billy10mm opened this issue Oct 28, 2018 · 2 comments
Open

Strange Behavior in dispatchEventQueue() #46

Billy10mm opened this issue Oct 28, 2018 · 2 comments

Comments

@Billy10mm
Copy link

Billy10mm commented Oct 28, 2018

dispatchEventQueue() can behave badly if I receive data but don't do anything with it. I'm not sure how else to describe this, but consider the following example code:

from pyrfa import Pyrfa
from threading import Thread
import time

class Reuters(Thread):
    def __init__(self):
        self.rfa = Pyrfa()
        self.running = True
        self.sessions = ['Session1']
        Thread.__init__(self, name='rfa')

    def connect(self):
        self.rfa.createConfigDb('reuters.cfg')
        for session in self.sessions:
            self.rfa.acquireSession(session)
        self.rfa.createOMMConsumer()
        self.rfa.login()
        self.rfa.directoryRequest()
        self.rfa.dictionaryRequest()
        self.subscribe('ESZ8')

    def run(self):
        self.connect()
        while self.running:
            data = self.rfa.dispatchEventQueue(100)

    def subscribe(self, ric):
        self.rfa.marketPriceRequest(ric)

r = Reuters()
r.start()
for x in range(0,5):
    print '{:.6f}'.format(time.time())
    time.sleep(1)
r.running = False

When I run the above on Python 2.7.15 (with optimizations enabled), the process hangs seemingly forever (it eventually does end, but it can take over 20 minutes). But if you simply add a print data immediately following the call to dispatchEventQueue(), then the software does not hang and ends in approximately 5 seconds as it should. If I change the call to dispatchEventQueue() and remove the blocking timeout as so, data = self.rfa.dispatchEventQueue(), then I have no issues at all.

@wiwat-tharateeraparb
Copy link
Contributor

wiwat-tharateeraparb commented Oct 29, 2018

For Python 2.7, time.sleep() which has some strange implementation underneath. Your code does not hang with Python 3 however as threading in Python 3 is implemented with pure C. If you are bound to Python 2.7, dispatchEventQueue() with empty argument will not block main thread:

...
    def run(self):
        self.connect()
        while self.running:
            time.sleep(0.1)
            data = self.rfa.dispatchEventQueue()
...

@wiwat-tharateeraparb
Copy link
Contributor

UPDATE: for Python2.7, adding Lock in both Pyrfa thread and main thread will also help.

from pyrfa import Pyrfa
from threading import Lock, Thread
import time
lock = Lock()

class Reuters(Thread):
    def __init__(self):
        self.rfa = Pyrfa()
        self.running = True
        self.sessions = ['Session1']
        Thread.__init__(self, name='rfa')

    def connect(self):
        self.rfa.createConfigDb('pyrfa.cfg')
        for session in self.sessions:
            self.rfa.acquireSession(session)
        self.rfa.createOMMConsumer()
        self.rfa.login()
        self.rfa.directoryRequest()
        self.rfa.dictionaryRequest()
        self.subscribe('EUR=')

    def run(self):
        self.connect()
        while self.running:
            lock.acquire()
            data = self.rfa.dispatchEventQueue(100)
            lock.release()

    def subscribe(self, ric):
        self.rfa.marketPriceRequest(ric)

r = Reuters()
r.start()
for x in range(0,5):
    lock.acquire()
    print('{:.6f}'.format(time.time()))
    time.sleep(1)
    lock.release()
r.running = False

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants