@@ -456,6 +456,38 @@ def __exit__(self, exc_type, exc_value, error_traceback):
456
456
if exc_type :
457
457
logger .critical (f"An exception occurred: { exc_type } - { exc_value } - { error_traceback } " )
458
458
459
+ async def _run_process_asyncio_queue (self , scope = None , stream_id = None ) -> bool :
460
+ """ Execute a provided coroutine within the loop and process the exception results asynchronously."""
461
+ if stream_id is None :
462
+ return False
463
+ stream_label = self .get_stream_label (stream_id = stream_id )
464
+ if stream_label is None :
465
+ stream_label = ""
466
+ else :
467
+ stream_label = f" ({ stream_label } )"
468
+ try :
469
+ if scope == "global" :
470
+ await self .process_asyncio_queue (stream_id = stream_id )
471
+ elif scope == "specific" :
472
+ await self .specific_process_asyncio_queue [stream_id ](stream_id = stream_id )
473
+ else :
474
+ return False
475
+ logger .debug (f"`process_asyncio_queue` of stream_id { stream_id } { stream_label } completed successfully." )
476
+ return True
477
+ except Exception as error_msg :
478
+ error_msg_wrapper = (f"Exception within to UBWA`s provided `process_asyncio_queue`-coroutine of stream "
479
+ f"'{ stream_id } '{ stream_label } : "
480
+ f"\033 [1m\033 [31m{ type (error_msg ).__name__ } - { error_msg } \033 [0m\r \n "
481
+ f"{ traceback .format_exc ()} " )
482
+ print (f"\r \n { error_msg_wrapper } " )
483
+ error_msg_wrapper = (f"Exception within to UBWA`s provided `process_asyncio_queue`-coroutine of stream "
484
+ f"'{ stream_id } '{ stream_label } : "
485
+ f"{ type (error_msg ).__name__ } - { error_msg } \r \n "
486
+ f"{ traceback .format_exc ()} " )
487
+ logger .critical (error_msg_wrapper )
488
+ self ._crash_stream (stream_id = stream_id , error_msg = error_msg_wrapper )
489
+ return False
490
+
459
491
async def _shutdown_asyncgens (self , stream_id = None , loop = None ) -> bool :
460
492
if loop is None :
461
493
return False
@@ -595,6 +627,10 @@ def send_stream_signal(self, signal_type=None, stream_id=None, data_record=None,
595
627
"""
596
628
Send a stream signal
597
629
"""
630
+ if str (error_msg ).startswith ("Stream with stream_id=" ):
631
+ match = re .search (r'Reason:\s*(.*)' , error_msg )
632
+ if match :
633
+ error_msg = match .group (1 )
598
634
self .process_stream_signals (signal_type = signal_type ,
599
635
stream_id = stream_id ,
600
636
data_record = data_record ,
@@ -740,6 +776,7 @@ def _add_stream_to_stream_list(self,
740
776
'last_heartbeat' : None ,
741
777
'stop_request' : False ,
742
778
'crash_request' : False ,
779
+ 'crash_request_reason' : None ,
743
780
'loop_is_closing' : False ,
744
781
'seconds_since_has_stopped' : None ,
745
782
'has_stopped' : None ,
@@ -753,7 +790,8 @@ def _add_stream_to_stream_list(self,
753
790
'last_received_data_record' : None ,
754
791
'processed_receives_statistic' : {},
755
792
'transfer_rate_per_second' : {'bytes' : {}, 'speed' : 0 },
756
- 'websocket_uri' : None }
793
+ 'websocket_uri' : None ,
794
+ '3rd-party-future' : None }
757
795
logger .info ("BinanceWebSocketApiManager._add_stream_to_stream_list(" +
758
796
str (stream_id ) + ", " + str (channels ) + ", " + str (markets ) + ", " + str (stream_label ) + ", "
759
797
+ str (stream_buffer_name ) + ", " + str (stream_buffer_maxlen ) + ", " + str (symbols ) + ")" )
@@ -816,6 +854,11 @@ def _create_stream_thread(self,
816
854
except RuntimeError as error_msg :
817
855
logger .debug (f"BinanceWebSocketApiManager._create_stream_thread() stream_id={ str (stream_id )} "
818
856
f" - RuntimeError `error: 12` - error_msg: { str (error_msg )} " )
857
+ except Exception as error_msg :
858
+ logger .critical (f"BinanceWebSocketApiManager._create_stream_thread({ str (stream_id )} - Unknown Exception - "
859
+ f"Please report this issue if your stream does not restart: "
860
+ f"https://github.com/LUCIT-Systems-and-Development/unicorn-binance-websocket-api/issues/new/choose"
861
+ f" - error_msg: { str (error_msg )} " )
819
862
finally :
820
863
logger .debug (f"Finally closing the loop stream_id={ str (stream_id )} " )
821
864
try :
@@ -1694,7 +1737,8 @@ def create_stream(self,
1694
1737
logger .debug (f"BinanceWebSocketApiManager.create_stream({ stream_id } - Adding "
1695
1738
f"`specific_process_asyncio_queue[{ stream_id } ]()` to asyncio loop ..." )
1696
1739
if self .get_event_loop_by_stream_id (stream_id = stream_id ) is not None :
1697
- asyncio .run_coroutine_threadsafe (self .specific_process_asyncio_queue [stream_id ](stream_id = stream_id ),
1740
+ asyncio .run_coroutine_threadsafe (self ._run_process_asyncio_queue (scope = "specific" ,
1741
+ stream_id = stream_id ),
1698
1742
self .get_event_loop_by_stream_id (stream_id = stream_id ))
1699
1743
else :
1700
1744
logger .error (f"BinanceWebSocketApiManager.create_stream({ stream_id } - No valid asyncio loop!" )
@@ -1705,7 +1749,8 @@ def create_stream(self,
1705
1749
logger .debug (f"BinanceWebSocketApiManager.create_stream({ stream_id } - "
1706
1750
f"Adding `process_asyncio_queue()` to asyncio loop ..." )
1707
1751
if self .get_event_loop_by_stream_id (stream_id = stream_id ) is not None :
1708
- asyncio .run_coroutine_threadsafe (self .process_asyncio_queue (stream_id = stream_id ),
1752
+ asyncio .run_coroutine_threadsafe (self ._run_process_asyncio_queue (scope = "global" ,
1753
+ stream_id = stream_id ),
1709
1754
self .get_event_loop_by_stream_id (stream_id = stream_id ))
1710
1755
else :
1711
1756
logger .error (f"BinanceWebSocketApiManager.create_stream({ stream_id } - No valid asyncio loop!" )
@@ -2305,7 +2350,8 @@ def get_latest_release_info():
2305
2350
:return: dict or None
2306
2351
"""
2307
2352
try :
2308
- respond = requests .get ('https://api.github.com/repos/LUCIT-Systems-and-Development/unicorn-binance-websocket-api/releases/latest' )
2353
+ respond = requests .get (f'https://api.github.com/repos/LUCIT-Systems-and-Development/'
2354
+ f'unicorn-binance-websocket-api/releases/latest' )
2309
2355
latest_release_info = respond .json ()
2310
2356
return latest_release_info
2311
2357
except Exception :
@@ -4128,18 +4174,21 @@ def stop_stream(self, stream_id, delete_listen_key: bool = True):
4128
4174
f"requests.exceptions.ConnectionError: { error_msg } " )
4129
4175
return True
4130
4176
4131
- def _crash_stream (self , stream_id ):
4177
+ def _crash_stream (self , stream_id , error_msg = None ):
4132
4178
"""
4133
4179
Loop inside: Stop a specific stream with 'crashed' status
4134
4180
4135
4181
:param stream_id: id of a stream
4136
4182
:type stream_id: str
4183
+ :param error_msg: Reason
4184
+ :type error_msg: str
4137
4185
:return: bool
4138
4186
"""
4139
4187
# stop a specific stream by stream_id
4140
4188
logger .critical (f"BinanceWebSocketApiManager._crash_stream({ stream_id } ){ self .get_debug_log ()} " )
4141
4189
try :
4142
4190
self .stream_list [stream_id ]['crash_request' ] = True
4191
+ self .stream_list [stream_id ]['crash_request_reason' ] = error_msg
4143
4192
except KeyError :
4144
4193
return False
4145
4194
return True
@@ -4160,7 +4209,10 @@ def _stream_is_crashing(self, stream_id: str = None, error_msg: str = None) -> b
4160
4209
self .set_socket_is_ready (stream_id )
4161
4210
if error_msg is not None :
4162
4211
self .stream_list [stream_id ]['status' ] += " - " + str (error_msg )
4163
- self .send_stream_signal (stream_id = stream_id , signal_type = "STREAM_UNREPAIRABLE" )
4212
+ else :
4213
+ if self .stream_list [stream_id ]['crash_request_reason' ] is not None :
4214
+ error_msg = self .stream_list [stream_id ]['crash_request_reason' ]
4215
+ self .send_stream_signal (stream_id = stream_id , signal_type = "STREAM_UNREPAIRABLE" , error_msg = error_msg )
4164
4216
return True
4165
4217
4166
4218
def _stream_is_restarting (self , stream_id , error_msg = None ):
@@ -4259,7 +4311,7 @@ def subscribe_to_stream(self, stream_id, channels=[], markets=[]):
4259
4311
"been exceeded!"
4260
4312
logger .critical (f"BinanceWebSocketApiManager.subscribe_to_stream({ str (stream_id )} ) "
4261
4313
f"Info: { str (error_msg )} " )
4262
- self ._crash_stream (stream_id )
4314
+ self ._crash_stream (stream_id , error_msg = error_msg )
4263
4315
return False
4264
4316
4265
4317
try :
0 commit comments