Skip to content

MonitoringThreadContainer creates ThreadPoolExecutor at import time, causing pytest to hang #1055

@jaredkeil

Description

@jaredkeil

Describe the bug

Similar to the recently fixed issue with SlidingExpirationCacheWithCleanupThread (#1043, #1039), the MonitoringThreadContainer class in host_monitoring_plugin.py creates a ThreadPoolExecutor at class definition time. This causes background threads to be created during module import (such as from aws_advanced_python_wrapper import AwsWrapperConnection), which prevents pytest from terminating cleanly as it waits for these non-daemon threads to finish.

_executor: ClassVar[Executor] = ThreadPoolExecutor(thread_name_prefix="MonitoringThreadContainerExecutor")

Expected Behavior

Importing the aws-advanced-python-wrapper library should not create background threads that prevent process termination. Tests should complete without hanging.

What plugins are used? What other connection properties were set?

iam, aurora-pg

Current Behavior

When running pytest, tests complete successfully, but pytest hangs indefinitely. The process must be killed with Ctrl+C. Stack trace shows threads waiting in concurrent.futures.threads module

 pytest test_reproduction.py
==================================================== test session starts ====================================================
platform darwin -- Python 3.12.3, pytest-9.0.1, pluggy-1.6.0
rootdir: /Users/develop/projects/side/aws_wrapper_bug
configfile: pyproject.toml
collected 1 item

test_reproduction.py .                                                                                                [100%]

===================================================== 1 passed in 4.28s =====================================================
^CException ignored in: <module 'threading' from '/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py'>
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py", line 1592, in _shutdown
    atexit_call()
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/concurrent/futures/thread.py", line 31, in _python_exit
    t.join()
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py", line 1147, in join
    self._wait_for_tstate_lock()
  File "/usr/local/Cellar/[email protected]/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/threading.py", line 1167, in _wait_for_tstate_lock
    if lock.acquire(block, timeout):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
KeyboardInterrupt:

Reproduction Steps

test_reproduction.py:

def test_import_causes_hang():
    """This test will pass but pytest will hang after completion"""
    from aws_advanced_python_wrapper import AwsWrapperConnection
    assert True

Run: pytest test_reproduction.py
Result: Tests passes but pytest never exits

Possible Solution

Could apply similar solution used for SlidingExpirationCacheWithCleanupThread - either:

  1. Use daemon threads so they don't prevent process termination
  2. Use lazy initialization to avoid creating threads at import time

Additional Information/Context

Pytest version: 9.0.1

The AWS Advanced Python Wrapper version used

1.4.0

python version used

3.12.3

Operating System and version

macOS Sequoia 15.7.1 (also reproduced on macOS Monterey 12.7.6)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions