|
def monitor(seconds_frozen, tests_per_second): |
|
"""Monitoring thread function |
|
|
|
Checks if thread is hanging for time defined by |
|
seconds_frozen parameter in frequency |
|
of test_per_second parameter |
|
""" |
|
current_thread = threading.current_thread() |
|
hanging_threads = set() |
|
old_threads = {} # Threads found on previous iteration. |
|
|
|
while not current_thread.is_stopped(): |
|
new_threads = get_current_frames() |
|
|
|
# Report died threads. |
|
for thread_id in old_threads.keys(): |
|
if thread_id not in new_threads and thread_id in hanging_threads: |
|
log_died_thread(thread_id) |
|
|
|
# Process live threads. |
|
time.sleep(1. / tests_per_second) |
|
now = time.time() |
|
then = now - seconds_frozen |
|
for thread_id, thread_data in new_threads.items(): |
|
# Don't report the monitor thread. |
|
if thread_id == current_thread.ident: |
|
continue |
|
frame = thread_data['frame'] |
|
# If thread is new or it's stack is changed then update time. |
|
if (thread_id not in old_threads or |
|
frame != old_threads[thread_id]['frame']): |
|
thread_data['time'] = now |
|
# If the thread was hanging then report awaked thread. |
|
if thread_id in hanging_threads: |
|
hanging_threads.remove(thread_id) |
|
log_awaked_thread(thread_id) |
|
else: |
|
# If stack is not changed then keep old time. |
|
last_change_time = old_threads[thread_id]['time'] |
|
thread_data['time'] = last_change_time |
|
# Check if this is a new hanging thread. |
|
if (thread_id not in hanging_threads and |
|
last_change_time < then): |
|
# Gotcha! |
|
hanging_threads.add(thread_id) |
|
# Report the hanged thread. |
|
log_hanged_thread(thread_id, frame) |
|
old_threads = new_threads |