mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-29 13:12:39 +08:00
Use a weak reference to sqlalchemy Engine to avoid memory leak (#1771)
* Use a weak reference to sqlalchemy Engine to avoid memory leak Closes #1761 By using a weak reference to the `Engine` object, we can avoid the memory leak as disposed `Engines` get properly deallocated. Whenever `SQLAlchemy` is uninstrumented, we only trigger a removal for those event listeners which are listening for objects that haven't been garbage-collected yet. * Made a mistake in resolving the weak reference * Fixed formatting issues * Updated changelog * Added unit test to check that engine was garbage collected * Do not save engine in EngineTracer to avoid memory leak * Add an empty line to satisfy black formatter * Fix isort complaints * Fixed the issue when pool name is not set and =None * Fix formatting issue * Rebased after changes in a recent commit * Updated PR number in changelog --------- Co-authored-by: Shalev Roda <65566801+shalevr@users.noreply.github.com>
This commit is contained in:
@ -307,3 +307,26 @@ class TestSqlalchemyInstrumentation(TestBase):
|
||||
cnx.execute("SELECT 1 + 1;").fetchall()
|
||||
spans = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(spans), 0)
|
||||
|
||||
def test_no_memory_leakage_if_engine_diposed(self):
|
||||
SQLAlchemyInstrumentor().instrument()
|
||||
import gc
|
||||
import weakref
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
callback = mock.Mock()
|
||||
|
||||
def make_shortlived_engine():
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
# Callback will be called if engine is deallocated during garbage
|
||||
# collection
|
||||
weakref.finalize(engine, callback)
|
||||
with engine.connect() as conn:
|
||||
conn.execute("SELECT 1 + 1;").fetchall()
|
||||
|
||||
for _ in range(0, 5):
|
||||
make_shortlived_engine()
|
||||
|
||||
gc.collect()
|
||||
assert callback.call_count == 5
|
||||
|
Reference in New Issue
Block a user