xloil icon indicating copy to clipboard operation
xloil copied to clipboard

scheduling timer tasks

Open ekwf opened this issue 8 months ago • 7 comments

First, I wanted to say that this project is excellent!

I have a sheet that gets some data from Bloomberg, calculates model values and uses xloil-python to send these values to a database over tcpip. Sometimes the model values don't change enough to bother updating so there are periods of inactivity. I dealt with this by creating a heartbeat mechanism that sends a heartbeat message ever 30seconds.

The user opens this sheet and presses a button runs an xloil macro function to initialize the TCP connection object. Upon initialization this function is called:

def start_hb(self):
        logging.debug("%s starting hb loop" % self.name)
        loop = xloil.get_event_loop()
        self.hb_task = asyncio.run_coroutine_threadsafe(self.send_hb(),loop)
        logging.debug("%s kicked off send_hb loop" % (self.name))

which schedules this function on the xloil event loop:

async def send_hb(self):
        while True:        
            self._send_hb()
            await asyncio.sleep(self.hb_int)

the actual _send_hb() function does a time check and if enough time has passed sends the heartbeat. It also has a debug that prints regardless of whether a send happens or not. During all of this Bloomberg data ticks via RTD at it's own pace.

What I noticed is that when the sheet is initialized without Bloomberg, the heartbeat fires exactly as expected. However, with Bloomberg (a lot of RTD calls) the start_hb function never finishes. That is, starting hb loop prints, but kicked off send_hb loop never prints and eventually during a period of low activity the tcp connection disconnects due to heartbeat timeout.

Am I missing something about how run_coroutine_threadsafe works here? For what it's worth, I tried to follow the discussion in https://github.com/cunnane/xloil/issues/59 to do this.

ekwf avatar Jun 24 '24 17:06 ekwf