1
1
# distutils: language = c++
2
2
# cython: always_allow_keywords=True
3
- from libcpp.deque cimport deque as cppdq
4
3
5
4
from dxfeed.core.utils.helpers cimport *
6
5
from dxfeed.core.utils.helpers import *
@@ -12,6 +11,7 @@ from datetime import datetime
12
11
import pandas as pd
13
12
from typing import Optional, Union, Iterable
14
13
from warnings import warn
14
+ from weakref import WeakSet
15
15
16
16
# for importing variables
17
17
import dxfeed.core.listeners.listener as lis
@@ -53,24 +53,29 @@ cdef class ConnectionClass:
53
53
Data structure that contains connection
54
54
"""
55
55
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
60
57
61
58
def __init__ (self ):
62
- self .subs_order = 0
59
+ self .__sub_refs = WeakSet()
63
60
64
61
def __dealloc__ (self ):
65
62
dxf_close_connection(self )
66
63
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
+
67
75
cpdef SubscriptionClass make_new_subscription(self , data_len: int ):
68
76
cdef SubscriptionClass out = SubscriptionClass(data_len)
69
77
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)
74
79
return out
75
80
76
81
@@ -80,9 +85,8 @@ cdef class SubscriptionClass:
80
85
"""
81
86
cdef clib.dxf_connection_t connection
82
87
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
85
88
cdef dxf_event_listener_t listener
89
+ cdef object __weakref__ # Weak referencing enabling
86
90
cdef object event_type_str
87
91
cdef list columns
88
92
cdef object data
@@ -105,9 +109,7 @@ cdef class SubscriptionClass:
105
109
self .listener = NULL
106
110
107
111
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 )
111
113
112
114
def get_data (self ):
113
115
"""
@@ -187,7 +189,7 @@ def dxf_create_connection_auth_bearer(address: Union[str, unicode, bytes],
187
189
address = address.encode(' utf-8' )
188
190
token = token.encode(' utf-8' )
189
191
clib.dxf_create_connection_auth_bearer(address, token,
190
- NULL , NULL , NULL , NULL , NULL , & cc.connection)
192
+ NULL , NULL , NULL , NULL , NULL , & cc.connection)
191
193
error_code = process_last_error(verbose = False )
192
194
if error_code:
193
195
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
229
231
candle_time = datetime.strptime(candle_time, ' %Y -%m -%d %H :%M :%S ' ) if candle_time else datetime.utcnow()
230
232
timestamp = int ((candle_time - datetime(1970 , 1 , 1 )).total_seconds()) * 1000 - 5000
231
233
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 " )
233
235
234
236
if event_type == ' Candle' :
235
237
clib.dxf_create_subscription_timed(sc.connection, et_type_int, timestamp, & sc.subscription)
@@ -368,16 +370,11 @@ def dxf_close_connection(ConnectionClass cc):
368
370
cc: ConnectionClass
369
371
Variable with connection information
370
372
"""
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
-
380
373
if cc.connection:
374
+ related_subs = cc.get_sub_refs()
375
+ for sub in related_subs:
376
+ dxf_close_subscription(sub)
377
+
381
378
clib.dxf_close_connection(cc.connection)
382
379
cc.connection = NULL
383
380
@@ -393,7 +390,6 @@ def dxf_close_subscription(SubscriptionClass sc):
393
390
if sc.subscription:
394
391
clib.dxf_close_subscription(sc.subscription)
395
392
sc.subscription = NULL
396
- sc.con_sub_list_ptr[0 ][sc.subscription_order] = NULL
397
393
398
394
def dxf_get_current_connection_status (ConnectionClass cc , return_str: bool = True ):
399
395
"""
0 commit comments