)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"21fc58b4e2a732787cd3bde9596c63fe05fe8835","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"4daf2a6f_413791fd","updated":"2026-03-23 10:10:12.000000000","message":"recheck","commit_id":"00b64102cb7a4fbf246154fa0cf97966d855125e"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"d707e207034897c1c96e4b9eba25735295a099d3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"da1ddb74_d0f866ff","updated":"2026-05-13 05:23:30.000000000","message":"recheck\n\nTimed out when uploading logs?","commit_id":"b3fabc1d996c9a9fd3027d6041bcbf52180fab8a"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"daa4c7bdb8af3a63eb0640a20b2588e1a18977c8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"1a6840e6_51acc1d9","updated":"2026-05-13 08:35:00.000000000","message":"recheck\n\nTests pass on two different dev envs","commit_id":"73155f88f75feb525be799712fb892c2e274ac27"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"166bedb122a92d2030d8bea2cf0bf50fb2d23a68","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"b7ff331e_6ae1d86e","updated":"2026-06-08 12:55:34.000000000","message":"I\u0027m voting -1 for now because of the memory leak that I believe it has to be fixed and if you don\u0027t think so, please, answer my comments below!","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"9366e6f4771fe37ada51e7961904cbeafd48efe1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"f741004a_81b9aef4","in_reply_to":"b7ff331e_6ae1d86e","updated":"2026-06-11 13:29:34.000000000","message":"Good catch! Updated the patch to track futures and a test to ensure it\u0027s cleaned up.","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"ee22e90bb484ef01233d4e91dcf513906ba3ede3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"ec930965_29417d32","updated":"2026-06-16 10:23:34.000000000","message":"There\u0027s still some work to do but we are getting closer!","commit_id":"b67471cf7e3dcecc7cf09c707828583a501f65f6"}],"swift/common/concurrency.py":[{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"166bedb122a92d2030d8bea2cf0bf50fb2d23a68","unresolved":true,"context_lines":[{"line_number":313,"context_line":"    class SwiftPool(ThreadPoolExecutor):"},{"line_number":314,"context_line":"        \"\"\"SwiftPool-compatible pool backed by ThreadPoolExecutor."},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"        Provides the same API as eventlet.SwiftPool so callers don\u0027t need"},{"line_number":317,"context_line":"        per-method ``if USE_EVENTLET`` branches."},{"line_number":318,"context_line":"        \"\"\""},{"line_number":319,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3e3a4b98_9ee1987f","line":316,"updated":"2026-06-08 12:55:34.000000000","message":"Requirement: I believe it should be \"Provides the same API as eventlet.GreenPool\" instead \"Provides the same API as eventlet.SwiftPool\"","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"9366e6f4771fe37ada51e7961904cbeafd48efe1","unresolved":false,"context_lines":[{"line_number":313,"context_line":"    class SwiftPool(ThreadPoolExecutor):"},{"line_number":314,"context_line":"        \"\"\"SwiftPool-compatible pool backed by ThreadPoolExecutor."},{"line_number":315,"context_line":""},{"line_number":316,"context_line":"        Provides the same API as eventlet.SwiftPool so callers don\u0027t need"},{"line_number":317,"context_line":"        per-method ``if USE_EVENTLET`` branches."},{"line_number":318,"context_line":"        \"\"\""},{"line_number":319,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"bb9f06a6_0c1a9d3b","line":316,"in_reply_to":"3e3a4b98_9ee1987f","updated":"2026-06-11 13:29:34.000000000","message":"Done","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"166bedb122a92d2030d8bea2cf0bf50fb2d23a68","unresolved":true,"context_lines":[{"line_number":322,"context_line":"            self.size \u003d size"},{"line_number":323,"context_line":"            self.futures \u003d []"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"        def spawn(self, func, *args, **kwargs):"},{"line_number":326,"context_line":"            future \u003d self.submit(func, *args, **kwargs)"},{"line_number":327,"context_line":"            self.futures.append(future)"},{"line_number":328,"context_line":"            return future"}],"source_content_type":"text/x-python","patch_set":9,"id":"ccb69813_5ea039cf","line":325,"updated":"2026-06-08 12:55:34.000000000","message":"Requirement: Memory leak in SwiftPool - completed futures accumulate unbounded\n\nThe SwiftPool.futures list grows unbounded when `spawn()` or `spawn_n()` are called repeatedly without `waitall()`. Each spawned task appends a Future to `self.futures`, but completed futures are never removed until `waitall()` is called. This causes a memory leak in long-running Swift daemons.\n\nThis affects any Swift daemon that uses a pool for extended periods without calling `waitall()`\n\nWith Claude\u0027s help I wrote a test script that simulated daemon behavior and ran it inside a SAIO machine\n\n```python\npool \u003d SwiftPool(size\u003d10)\nfor i in range(1000):\n    pool.spawn_n(process_task, i)\n    # No waitall() - simulates continuous processing\n```\n\nResults from test script:\n- Threading mode (SwiftPool): 1000 futures tracked for 1000 spawned tasks\n  - ALL completed futures remain in memory\n  - Memory usage scales linearly with tasks spawned, not pool size\n\n- Eventlet mode (GreenPool): running\u003d10, free\u003d0 (stable)\n  - Completed greenthreads are automatically cleaned up\n  - No accumulation\n\nYou could try adding a clean up completed futures in the running() method, since it already iterates through the futures list:\n\n```python\ndef running(self):\n    self.futures \u003d [f for f in self.futures if not f.done()]\n    return len([f for f in self.futures if f.running()])\n```\n\nBut I didn\u0027t test it if this solution works.\n\nPreference: Add a unit test to verify completed futures are cleaned up:\n\n```python\ndef test_completed_futures_are_cleaned_up(self):\n    \"\"\"Verify completed futures don\u0027t accumulate (memory leak prevention).\"\"\"\n    pool \u003d SwiftPool(size\u003d10)\n\n    # Spawn 100 tasks\n    for i in range(100):\n        pool.spawn_n(lambda x: x, i)\n\n    time.sleep(0.1)  # Let tasks complete\n\n    # Calling running() should clean up completed futures\n    running_count \u003d pool.running()\n\n    # Verify no completed futures remain in the list\n    done_futures \u003d len([f for f in pool.futures if f.done()])\n    self.assertEqual(done_futures, 0,\n                    \"Completed futures should be cleaned up to prevent memory leak\")\n\n    pool.shutdown(wait\u003dTrue)\n```","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"9366e6f4771fe37ada51e7961904cbeafd48efe1","unresolved":false,"context_lines":[{"line_number":322,"context_line":"            self.size \u003d size"},{"line_number":323,"context_line":"            self.futures \u003d []"},{"line_number":324,"context_line":""},{"line_number":325,"context_line":"        def spawn(self, func, *args, **kwargs):"},{"line_number":326,"context_line":"            future \u003d self.submit(func, *args, **kwargs)"},{"line_number":327,"context_line":"            self.futures.append(future)"},{"line_number":328,"context_line":"            return future"}],"source_content_type":"text/x-python","patch_set":9,"id":"6accf61d_2b909d26","line":325,"in_reply_to":"ccb69813_5ea039cf","updated":"2026-06-11 13:29:34.000000000","message":"Done","commit_id":"1255d0ca75ff46b932bce10a4841bf575779e531"},{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"ee22e90bb484ef01233d4e91dcf513906ba3ede3","unresolved":true,"context_lines":[{"line_number":369,"context_line":"        def starmap(self, func, iterable):"},{"line_number":370,"context_line":"            return self.map(lambda args: func(*args), iterable)"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":"        def imap(self, func, *iterables):"},{"line_number":373,"context_line":"            return self.map(func, *iterables)"},{"line_number":374,"context_line":""},{"line_number":375,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"c8f993cd_3b1849de","line":372,"updated":"2026-06-16 10:23:34.000000000","message":"Question: SwiftPool.imap() delegates to ThreadPoolExecutor.map() which returns results in order and eventlet.GreenPool.imap() returns results as they complete (unordered). Are there any Swift components that rely on imap() returning results in completion order (unordered) rather than submission order?","commit_id":"2b31276185ee43730c602626c5652c66d5c99477"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":38496,"name":"Andressa Cabistani","display_name":"Andressa","email":"acabistani@gmail.com","username":"andressadotpy"},"change_message_id":"ee22e90bb484ef01233d4e91dcf513906ba3ede3","unresolved":true,"context_lines":[{"line_number":2138,"context_line":"            # be reused for subsequent ranges in multi-range EC responses."},{"line_number":2139,"context_line":"            for future in self.futures:"},{"line_number":2140,"context_line":"                future.cancel()"},{"line_number":2141,"context_line":"            self.futures \u003d []"},{"line_number":2142,"context_line":""},{"line_number":2143,"context_line":""},{"line_number":2144,"context_line":"class GreenAsyncPileWaitallTimeout(Timeout):"}],"source_content_type":"text/x-python","patch_set":11,"id":"85b8f23f_03c2c4d2","line":2141,"updated":"2026-06-16 10:23:34.000000000","message":"Requirement: So you see, we are getting closer but it\u0027s still not right - when you do `self.futures \u003d []` you are creating a new List object, not cleaning it, so when trying to re-use the pool we see a `\u0027list\u0027 object has no attribute \u0027add\u0027`.\n\nSo if we do:\n\n```\npool \u003d ContextPool(size\u003d4)\npool.spawn(func1)\npool.spawn(func2)\npool.close()\n```\n\nwe won\u0027t see the error happening because it\u0027s not reusing the pool, but as soon as we do\n\n```\npool \u003d ContextPool(size\u003d4)\npool.spawn(func1)\npool.close()\npool.spawn(func2)\n```\n\nit breaks with the error because it\u0027s trying to re-use the pool.\n\nI believe the fix for this is changing `self.futures \u003d []` to `self.futures.clear()` to clear the set, not rebind it.","commit_id":"2b31276185ee43730c602626c5652c66d5c99477"}]}
