Hi Alex,
I had a similar problem with a connect being done on the heals of a disconnect. I determined that the EClient disconnect code failed to wait for the reader thread to come home. It was orphaned but still active and snatched the handshaking responses during the following connect.
Not sure you have the same problem, but just in case, following is my disconnect code that overrides the EClient disconnect. Try that out if you want.
You can either comment out the logging code or get scottbrian-utils from PyPI and add "from scottbrian_utils.diag_msg import get_formatted_call_sequence" to your imports.
Note also that you will need the add "self.disconnect_lock = Lock()" in your __init__ method for your IBapi class and add "from threading import Lock" to your imports.?
Note also in my disconnect_from_ib that I join the run thread to wait for it to come home before exiting the disconnect process. Having both the reader thread and the run thread finished makes for a clean connect.
###########################################################################
# disconnect_from_ib
###########################################################################
def disconnect_from_ib(self) -> None:
"""Disconnect from ib."""
logger.info('calling EClient disconnect')
self.disconnect() # call our disconnect (overrides EClient)
logger.info('join run_thread to wait for it to come home')
self.run_thread.join()
logger.info('disconnect complete')
###########################################################################
# disconnect
###########################################################################
def disconnect(self) -> None:
"""Call this function to terminate the connections with TWS."""
# We would like to call EClient.disconnect, but it does not wait for
# the reader thread to come home which leads to problems if a connect
# is done immediately after the disconnect. The still running reader
# thread snatches the early handshaking messages and leaves the
# connect hanging. The following code is from client.py and is
# modified here to add the thread join to ensure the reader comes
# home before the disconnect returns.
# Note also the use of the disconnect lock to serialize the two known
# cases of disconnect being called from different threads (one from
# mainline through disconnect_from_ib in AlgoApp, and one from the
# EClient run method in the run thread.
call_seq = get_formatted_call_sequence()
logger.debug("%s entered disconnect", call_seq)
with self.disconnect_lock:
logger.debug("%s setting conn state", call_seq)
self.setConnState(EClient.DISCONNECTED)
if self.conn is not None:
logger.info("%s disconnecting", call_seq)
self.conn.disconnect()
self.wrapper.connectionClosed()
reader_id = id(self.reader)
my_id = get_ident()
my_native_id = get_native_id()
logger.debug('about to join reader id %d for self id %d to'
' wait for it to come home on thread %d %d',
reader_id, id(self), my_id, my_native_id)
self.reader.join()
logger.debug('reader id %d came home for id(self) %d '
'thread id %d %d',
reader_id,
id(self), my_id, my_native_id)
self.reset()
? ? ? ?