11# distutils: language = c++
22# cython: always_allow_keywords=True
3- from libcpp.deque cimport deque as cppdq
43
54from dxfeed.core.utils.helpers cimport *
65from dxfeed.core.utils.helpers import *
@@ -12,6 +11,7 @@ from datetime import datetime
1211import pandas as pd
1312from typing import Optional, Union, Iterable
1413from warnings import warn
14+ from weakref import WeakSet
1515
1616# for importing variables
1717import dxfeed.core.listeners.listener as lis
@@ -53,24 +53,29 @@ cdef class ConnectionClass:
5353 Data structure that contains connection
5454 """
5555 cdef clib.dxf_connection_t connection
56- # sub_ptr_list contains pointers to all subscriptions related to current connection
57- cdef cppdq[clib.dxf_subscription_t * ] sub_ptr_list
58- # each subscription has its own index in a list
59- cdef int subs_order
56+ cdef object __sub_refs
6057
6158 def __init__ (self ):
62- self .subs_order = 0
59+ self .__sub_refs = WeakSet()
6360
6461 def __dealloc__ (self ):
6562 dxf_close_connection(self )
6663
64+ def get_sub_refs (self ):
65+ """
66+ Method to get list of references to all subscriptions related to current connection
67+
68+ Returns
69+ -------
70+ :list
71+ List of weakref objects. Empty list if no refs
72+ """
73+ return list (self .__sub_refs)
74+
6775 cpdef SubscriptionClass make_new_subscription(self , data_len: int ):
6876 cdef SubscriptionClass out = SubscriptionClass(data_len)
6977 out.connection = self .connection
70- self .sub_ptr_list.push_back(& out.subscription) # append pointer to new subscription
71- out.subscription_order = self .subs_order # assign each subscription an index
72- self .subs_order += 1
73- out.con_sub_list_ptr = & self .sub_ptr_list # reverse pointer to pointers list
78+ self .__sub_refs.add(out)
7479 return out
7580
7681
@@ -80,9 +85,8 @@ cdef class SubscriptionClass:
8085 """
8186 cdef clib.dxf_connection_t connection
8287 cdef clib.dxf_subscription_t subscription
83- cdef int subscription_order # index in list of subscription pointers
84- cdef cppdq[clib.dxf_subscription_t * ] * con_sub_list_ptr # pointer to list of subscription pointers
8588 cdef dxf_event_listener_t listener
89+ cdef object __weakref__ # Weak referencing enabling
8690 cdef object event_type_str
8791 cdef list columns
8892 cdef object data
@@ -105,9 +109,7 @@ cdef class SubscriptionClass:
105109 self .listener = NULL
106110
107111 def __dealloc__ (self ):
108- if self .subscription: # if connection is not closed
109- clib.dxf_close_subscription(self .subscription)
110- self .con_sub_list_ptr[0 ][self .subscription_order] = NULL
112+ dxf_close_subscription(self )
111113
112114 def get_data (self ):
113115 """
@@ -187,7 +189,7 @@ def dxf_create_connection_auth_bearer(address: Union[str, unicode, bytes],
187189 address = address.encode(' utf-8' )
188190 token = token.encode(' utf-8' )
189191 clib.dxf_create_connection_auth_bearer(address, token,
190- NULL , NULL , NULL , NULL , NULL , & cc.connection)
192+ NULL , NULL , NULL , NULL , NULL , & cc.connection)
191193 error_code = process_last_error(verbose = False )
192194 if error_code:
193195 raise RuntimeError (f" In underlying C-API library error {error_code} occurred!" )
@@ -229,7 +231,7 @@ def dxf_create_subscription(ConnectionClass cc, event_type: str, candle_time: Op
229231 candle_time = datetime.strptime(candle_time, ' %Y -%m -%d %H :%M :%S ' ) if candle_time else datetime.utcnow()
230232 timestamp = int ((candle_time - datetime(1970 , 1 , 1 )).total_seconds()) * 1000 - 5000
231233 except ValueError :
232- raise Exception (" Inapropriate date format, should be %Y -%m -%d %H :%M :%S " )
234+ raise Exception (" Inappropriate date format, should be %Y -%m -%d %H :%M :%S " )
233235
234236 if event_type == ' Candle' :
235237 clib.dxf_create_subscription_timed(sc.connection, et_type_int, timestamp, & sc.subscription)
@@ -368,16 +370,11 @@ def dxf_close_connection(ConnectionClass cc):
368370 cc: ConnectionClass
369371 Variable with connection information
370372 """
371-
372- # close all subscriptions before closing the connection
373- for i in range (cc.sub_ptr_list.size()):
374- if cc.sub_ptr_list[i]: # subscription should not be closed previously
375- clib.dxf_close_subscription(cc.sub_ptr_list[i][0 ])
376- cc.sub_ptr_list[i][0 ] = NULL # mark subscription as closed
377-
378- cc.sub_ptr_list.clear()
379-
380373 if cc.connection:
374+ related_subs = cc.get_sub_refs()
375+ for sub in related_subs:
376+ dxf_close_subscription(sub)
377+
381378 clib.dxf_close_connection(cc.connection)
382379 cc.connection = NULL
383380
@@ -393,7 +390,6 @@ def dxf_close_subscription(SubscriptionClass sc):
393390 if sc.subscription:
394391 clib.dxf_close_subscription(sc.subscription)
395392 sc.subscription = NULL
396- sc.con_sub_list_ptr[0 ][sc.subscription_order] = NULL
397393
398394def dxf_get_current_connection_status (ConnectionClass cc , return_str: bool = True ):
399395 """
0 commit comments