Running cryptofeed (asyncio library) in a new thread

Viewed 211

I would like to start the cryptofeed FeedHandler in a separate thread. My main thread will just be a loop that prints something to screen every two seconds:

import asyncio

from time import sleep
from concurrent.futures import ThreadPoolExecutor

from cryptofeed import FeedHandler
from cryptofeed.exchanges import FTX
from cryptofeed.defines import L2_BOOK


class TestApp:
    def __init__(self, symbols: list):
        self.coin_book: dict = {}
        self.symbols = symbols

    async def book_update(self, feed, symbol, book, timestamp, receipt_timestamp):
        self.coin_book = book

    async def start_feed(self):
        loop = asyncio.get_running_loop()

        fh = FeedHandler()
        fh.add_feed(FTX(symbols=self.symbols, channels=[L2_BOOK], callbacks={L2_BOOK: self.book_update}))

        with ThreadPoolExecutor() as pool:
            result = await loop.run_in_executor(pool, fh.run)

    def display(self):
        print('bid', self.coin_book['bid'].peekitem(-1))
        print('ask', self.coin_book['ask'].peekitem(0))

    async def run(self):
        await self.start_feed()

        while True:
            sleep(2)
            self.display()


if __name__ == '__main__':
    app = TestApp(['RAY-USD'])
    asyncio.run(app.run())

I know you need to use loop.run_in_executor() to start a coroutine in a new thread (as described here, but I still get the following error msg:

Traceback (most recent call last):
  File "/Users/mc/Library/Application Support/JetBrains/PyCharmCE2021.1/scratches/scratch.py", line 42, in <module>
    asyncio.run(app.run())
  File "/Users/mc/.pyenv/versions/3.9.1/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Users/mc/.pyenv/versions/3.9.1/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/Users/mc/Library/Application Support/JetBrains/PyCharmCE2021.1/scratches/scratch.py", line 33, in run
    await self.start_feed()
  File "/Users/mc/Library/Application Support/JetBrains/PyCharmCE2021.1/scratches/scratch.py", line 26, in start_feed
    result = await loop.run_in_executor(pool, fh.run)
  File "/Users/mc/.pyenv/versions/3.9.1/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/Users/mc/.virtualenvs/crypto/lib/python3.9/site-packages/cryptofeed/feedhandler.py", line 145, in run
    loop = asyncio.get_event_loop()
  File "/Users/mc/.pyenv/versions/3.9.1/lib/python3.9/asyncio/events.py", line 642, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'ThreadPoolExecutor-0_0'.
0 Answers
Related