@@ -25,6 +25,9 @@ def __init__(self, agent):
25
25
# The agent for this process. Can be Standard, AWSLambda or Fargate
26
26
self .agent = agent
27
27
28
+ # The name assigned to the spawned thread
29
+ self .THREAD_NAME = "Instana Collector"
30
+
28
31
# The Queue where we store finished spans before they are sent
29
32
self .span_queue = queue .Queue ()
30
33
@@ -50,30 +53,56 @@ def __init__(self, agent):
50
53
# Reporting interval for the background thread(s)
51
54
self .report_interval = 1
52
55
56
+ # Flag to indicate if start/shutdown state
57
+ self .started = False
58
+
59
+ def is_reporting_thread_running (self ):
60
+ """
61
+ Indicates if there is a thread running with the name self.THREAD_NAME
62
+ """
63
+ for thread in threading .enumerate ():
64
+ if thread .name == self .THREAD_NAME :
65
+ return True
66
+ return False
67
+
53
68
def start (self ):
54
69
"""
55
70
Starts the collector and starts reporting as long as the agent is in a ready state.
56
71
@return: None
57
72
"""
73
+ if self .is_reporting_thread_running ():
74
+ if self .thread_shutdown .is_set ():
75
+ # Shutdown still in progress; Reschedule this start in 5 seconds from now
76
+ timer = threading .Timer (5 , self .start )
77
+ timer .daemon = True
78
+ timer .name = "Collector Timed Start"
79
+ timer .start ()
80
+ return
81
+ logger .debug ("Collecter.start non-fatal: call but thread already running (started: %s)" , self .started )
82
+ return
83
+
58
84
if self .agent .can_send ():
59
85
logger .debug ("BaseCollector.start: launching collection thread" )
60
86
self .thread_shutdown .clear ()
61
87
self .reporting_thread = threading .Thread (target = self .thread_loop , args = ())
62
88
self .reporting_thread .setDaemon (True )
89
+ self .reporting_thread .setName (self .THREAD_NAME )
63
90
self .reporting_thread .start ()
91
+ self .started = True
64
92
else :
65
- logger .warning ("BaseCollector.start: the agent tells us we can't send anything out. " )
93
+ logger .warning ("BaseCollector.start: the agent tells us we can't send anything out" )
66
94
67
95
def shutdown (self , report_final = True ):
68
96
"""
69
- Shuts down the collector and reports any final data.
97
+ Shuts down the collector and reports any final data (if possible).
98
+ e.g. If the host agent disappeared, we won't be able to report final data.
70
99
@return: None
71
100
"""
72
101
logger .debug ("Collector.shutdown: Reporting final data." )
73
102
self .thread_shutdown .set ()
74
-
75
103
if report_final is True :
76
104
self .prepare_and_report_data ()
105
+ self .started = False
77
106
78
107
def thread_loop (self ):
79
108
"""
@@ -90,15 +119,31 @@ def background_report(self):
90
119
if self .thread_shutdown .is_set ():
91
120
logger .debug ("Thread shutdown signal is active: Shutting down reporting thread" )
92
121
return False
93
- return self .prepare_and_report_data ()
94
122
95
- def should_send_snapshot_data (self ):
123
+ self .prepare_and_report_data ()
124
+
125
+ if self .thread_shutdown .is_set ():
126
+ logger .debug ("Thread shutdown signal is active: Shutting down reporting thread" )
127
+ return False
128
+
129
+ return True
130
+
131
+ def prepare_and_report_data (self ):
96
132
"""
97
- Determines if snapshot data should be sent
133
+ Prepare and report the data payload.
98
134
@return: Boolean
99
135
"""
100
- logger .debug ("BaseCollector: should_send_snapshot_data needs to be overridden" )
101
- return False
136
+ if env_is_test is False :
137
+ lock_acquired = self .background_report_lock .acquire (False )
138
+ if lock_acquired :
139
+ try :
140
+ payload = self .prepare_payload ()
141
+ self .agent .report_data_payload (payload )
142
+ finally :
143
+ self .background_report_lock .release ()
144
+ else :
145
+ logger .debug ("prepare_and_report_data: Couldn't acquire lock" )
146
+ return True
102
147
103
148
def prepare_payload (self ):
104
149
"""
@@ -108,24 +153,13 @@ def prepare_payload(self):
108
153
logger .debug ("BaseCollector: prepare_payload needs to be overridden" )
109
154
return DictionaryOfStan ()
110
155
111
- def prepare_and_report_data (self ):
156
+ def should_send_snapshot_data (self ):
112
157
"""
113
- Prepare and report the data payload.
158
+ Determines if snapshot data should be sent
114
159
@return: Boolean
115
160
"""
116
- if env_is_test is True :
117
- return True
118
-
119
- lock_acquired = self .background_report_lock .acquire (False )
120
- if lock_acquired :
121
- try :
122
- payload = self .prepare_payload ()
123
- self .agent .report_data_payload (payload )
124
- finally :
125
- self .background_report_lock .release ()
126
- else :
127
- logger .debug ("prepare_and_report_data: Couldn't acquire lock" )
128
- return True
161
+ logger .debug ("BaseCollector: should_send_snapshot_data needs to be overridden" )
162
+ return False
129
163
130
164
def collect_snapshot (self , * argv , ** kwargs ):
131
165
logger .debug ("BaseCollector: collect_snapshot needs to be overridden" )
0 commit comments