You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2023/02/07 21:13:57 UTC

[qpid-proton] branch main updated: PROTON-2095: Improve CFFI object allocation debugging/testing

This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/main by this push:
     new 22b93044e PROTON-2095: Improve CFFI object allocation debugging/testing
22b93044e is described below

commit 22b93044ef18eef43976f25d5863ab884ebff9c3
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Tue Feb 7 16:10:40 2023 -0500

    PROTON-2095: Improve CFFI object allocation debugging/testing
    
    * Add visibility of retained object counts for debugging
    * Make one of the integration tests a bit more repeatable in the hope it
      will stop failing.
---
 python/cproton.py                                     | 15 +++++++++------
 .../test_PROTON_1709_application_event_object_leak.py | 19 +++++++++++++------
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/python/cproton.py b/python/cproton.py
index 91efe043d..5abcb11d6 100644
--- a/python/cproton.py
+++ b/python/cproton.py
@@ -296,24 +296,27 @@ def pn_transport_set_pytracer(transport, tracer):
     attrs['_tracer'] = tracer
     lib.pn_transport_set_tracer(transport, lib.pn_pytracer)
 
-
+retained_objects = set()
 lib.init()
-global_root = set()
 
 
+def retained_count():
+    """ Debugging aid to give the number of wrapper objects retained by the bindings"""
+    return len(retained_objects)
+
 @ffi.def_extern()
 def pn_pyref_incref(obj):
-    global_root.add(obj)
+    retained_objects.add(obj)
 
 
 @ffi.def_extern()
 def pn_pyref_decref(obj):
-    global_root.discard(obj)
+    retained_objects.discard(obj)
 
 
 def pn_collector_put_pyref(collector, obj, etype):
     d = ffi.new_handle(obj)
-    global_root.add(d)
+    retained_objects.add(d)
     lib.pn_collector_put_py(collector, d, etype.number)
 
 
@@ -333,7 +336,7 @@ def pn_record_set_py(record, value):
         d = ffi.NULL
     else:
         d = ffi.new_handle(value)
-        global_root.add(d)
+        retained_objects.add(d)
     lib.pn_record_set_py(record, d)
 
 
diff --git a/python/tests/integration/test_PROTON_1709_application_event_object_leak.py b/python/tests/integration/test_PROTON_1709_application_event_object_leak.py
index 8fc9690e2..c0b15b689 100644
--- a/python/tests/integration/test_PROTON_1709_application_event_object_leak.py
+++ b/python/tests/integration/test_PROTON_1709_application_event_object_leak.py
@@ -21,11 +21,13 @@
 PROTON-1709 [python] ApplicationEvent causing memory growth
 """
 
+import array
 import gc
 import platform
 import threading
 import unittest
 
+
 import proton
 from proton.handlers import MessagingHandler
 from proton.reactor import Container, ApplicationEvent, EventInjector
@@ -36,10 +38,12 @@ class Program(MessagingHandler):
         self.injector = injector
         self.counter = 0
         self.on_start_ = threading.Event()
+        self.on_start_continue_ = threading.Event()
 
     def on_reactor_init(self, event):
         event.reactor.selectable(self.injector)
         self.on_start_.set()
+        self.on_start_continue_.wait()
 
     def on_count_up(self, event):
         self.counter += 1
@@ -47,6 +51,7 @@ class Program(MessagingHandler):
 
     def on_done(self, event):
         event.subject.stop()
+        gc.collect()
 
 
 class Proton1709Test(unittest.TestCase):
@@ -58,20 +63,21 @@ class Proton1709Test(unittest.TestCase):
         p = Program(injector)
         c = Container(p)
         t = threading.Thread(target=c.run)
-        t.start()
+        object_counts = array.array('L', [0]*3)
 
+        t.start()
         p.on_start_.wait()
 
-        object_counts = []
-
         gc.collect()
-        object_counts.append(len(gc.get_objects()))
+        object_counts[0] = len(gc.get_objects())
+
+        p.on_start_continue_.set()
 
         for i in range(100):
             injector.trigger(ApplicationEvent("count_up"))
 
         gc.collect()
-        object_counts.append(len(gc.get_objects()))
+        object_counts[1] = len(gc.get_objects())
 
         self.assertEqual(len(proton.EventType.TYPES), event_types_count + 1)
 
@@ -81,7 +87,7 @@ class Proton1709Test(unittest.TestCase):
         t.join()
 
         gc.collect()
-        object_counts.append(len(gc.get_objects()))
+        object_counts[2] = len(gc.get_objects())
 
         self.assertEqual(p.counter, 100)
 
@@ -89,3 +95,4 @@ class Proton1709Test(unittest.TestCase):
                         "Object counts should not be increasing too fast: {0}".format(object_counts))
         self.assertTrue(object_counts[2] - object_counts[0] <= 10,
                         "No objects should be leaking at the end: {0}".format(object_counts))
+


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org