I have scripts running 24/7 that sometimes get stuck when a thread in concurrent.futures gets no response for a request. I use concurrent.futures Threadpools to simultaneously send requests to a Broker. So, every thread is something simple like a function that requests the account balance or sends an order. I need those Threads either executed or failed in order to move on, because every further action requires the data acquired through the threads before.
Below is an example of two simple order functions and the concurrent futures.
def sell_orders_0():
order = client.new_order(symbol = ticker, side = 'SELL', type = 'LIMIT_MAKER', quantity = xquantity, price = xprice)
def buy_orders_0():
order = client.new_order(symbol = ticker, side = 'SELL', type = 'LIMIT_MAKER', quantity = xquantity, price = xprice)
with concurrent.futures.ThreadPoolExecutor() as executor:
sells_0 = executor.submit(sell_orders_0)
buys_0 = executor.submit(buy_orders_0)
The hanging Threads module prints out which thread hangs and why:
Thread 139646566659840 "ThreadPoolExecutor-666849_1" hangs -
File "/usr/lib/python3.9/threading.py", line 912, in _bootstrap
self._bootstrap_inner()
File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 77, in _worker
work_item.run()
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/user/binance_bot.py", line 1346, in sell_orders_3
order = client.new_order(symbol = ticker, side = 'SELL', type = 'LIMIT_MAKER', quantity = xquantity, price = xprice)
File "/home/user/.local/lib/python3.9/site-packages/binance/spot/trade.py", line 68, in new_order
return self.sign_request("POST", url_path, params)
File "/home/user/.local/lib/python3.9/site-packages/binance/api.py", line 83, in sign_request
return self.send_request(http_method, url_path, payload)
File "/home/user/.local/lib/python3.9/site-packages/binance/api.py", line 115, in send_request
response = self._dispatch_request(http_method)(**params)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 635, in post
return self.request("POST", url, data=data, json=json, **kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 587, in request
resp = self.send(prep, **send_kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 701, in send
r = adapter.send(request, **kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/adapters.py", line 489, in send
resp = conn.urlopen(
File "/home/user/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "/home/user/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 444, in _make_request
httplib_response = conn.getresponse()
File "/usr/lib/python3.9/http/client.py", line 1347, in getresponse
response.begin()
File "/usr/lib/python3.9/http/client.py", line 307, in begin
version, status, reason = self._read_status()
File "/usr/lib/python3.9/http/client.py", line 268, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "/usr/lib/python3.9/socket.py", line 704, in readinto [0/1893]
return self._sock.recv_into(b)
File "/usr/lib/python3.9/ssl.py", line 1241, in recv_into
return self.read(nbytes, buffer)
File "/usr/lib/python3.9/ssl.py", line 1099, in read
return self._sslobj.read(len, buffer)
Thread 139646533089024 "ThreadPoolExecutor-666849_0" hangs -
File "/usr/lib/python3.9/threading.py", line 912, in _bootstrap
self._bootstrap_inner()
File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/usr/lib/python3.9/threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 77, in _worker
work_item.run()
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/user/binance_bot.py", line 1298, in sell_orders_0
order = client.new_order(symbol = ticker, side = 'SELL', type = 'LIMIT_MAKER', quantity = xquantity, price = xprice)
File "/home/user/.local/lib/python3.9/site-packages/binance/spot/trade.py", line 68, in new_order
return self.sign_request("POST", url_path, params)
File "/home/user/.local/lib/python3.9/site-packages/binance/api.py", line 83, in sign_request
return self.send_request(http_method, url_path, payload)
File "/home/user/.local/lib/python3.9/site-packages/binance/api.py", line 115, in send_request
response = self._dispatch_request(http_method)(**params)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 635, in post
return self.request("POST", url, data=data, json=json, **kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 587, in request
resp = self.send(prep, **send_kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/sessions.py", line 701, in send
r = adapter.send(request, **kwargs)
File "/home/user/.local/lib/python3.9/site-packages/requests/adapters.py", line 489, in send
resp = conn.urlopen(
File "/home/user/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "/home/user/.local/lib/python3.9/site-packages/urllib3/connectionpool.py", line 444, in _make_request
httplib_response = conn.getresponse()
File "/usr/lib/python3.9/http/client.py", line 1347, in getresponse
response.begin()
File "/usr/lib/python3.9/http/client.py", line 307, in begin
version, status, reason = self._read_status()
File "/usr/lib/python3.9/http/client.py", line 268, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "/usr/lib/python3.9/socket.py", line 704, in readinto
return self._sock.recv_into(b)
File "/usr/lib/python3.9/ssl.py", line 1241, in recv_into
return self.read(nbytes, buffer)
File "/usr/lib/python3.9/ssl.py", line 1099, in read
return self._sslobj.read(len, buffer)
---------Thread 139646838966080 "MainThread" hangs ---------
File "/home/user/binance_bot.py", line 1596, in <module>
buys_0 = executor.submit(buy_orders_0)
File "/usr/lib/python3.9/concurrent/futures/_base.py", line 628, in __exit__
self.shutdown(wait=True)
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 229, in shutdown
t.join()
File "/usr/lib/python3.9/threading.py", line 1033, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.9/threading.py", line 1049, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
How could i make my code nonblocking?
I already asked how i could raise an exception when my code hangs, but that's not possible since cancelling a running Thread from outside is impossible.