)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a8161e0c946cd5aca73b202985c2f3f8a036449a","unresolved":true,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Generated-By: Anthropic Claude Opus 5.5"},{"line_number":22,"context_line":"Change-Id: I2ac806394e48e591e91678072c197d2d96ced55a"},{"line_number":23,"context_line":"Signed-off-by: Adam Harwell \u003cflux.adam@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"2b20ec41_be8c18df","line":23,"updated":"2026-10-21 14:05:22.000000000","message":"As with https://review.opendev.org/c/openstack/tooz/+/1011567, do we want to file a bug report so we can backport this?","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ff389adb94976591ab703b58d9cb33a6b5fd9ea8","unresolved":false,"context_lines":[{"line_number":20,"context_line":""},{"line_number":21,"context_line":"Generated-By: Anthropic Claude Opus 5.5"},{"line_number":22,"context_line":"Change-Id: I2ac806394e48e591e91678072c197d2d96ced55a"},{"line_number":23,"context_line":"Signed-off-by: Adam Harwell \u003cflux.adam@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"8be4bb30_25634787","line":23,"in_reply_to":"2b20ec41_be8c18df","updated":"2026-10-21 18:41:24.000000000","message":"Yes: I filed https://bugs.launchpad.net/bugs/2171770, and the commit message closes it in PS2.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"433e4f0998eefc668b01912446c755875e9614f5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"788f990e_ecca829d","updated":"2026-10-22 08:40:29.000000000","message":"I\u0027m happy with this as-is, but I\u0027m also happy to be overruled if Takashi-san thinks otherwise","commit_id":"215b98e5d66c8b50b229f7c80b015c89467d3c2e"}],"releasenotes/notes/zookeeper-get-members-pipelined-90351009f8940d6e.yaml":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"a8161e0c946cd5aca73b202985c2f3f8a036449a","unresolved":true,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"other:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ZooKeeper driver now sends the reads of all a group\u0027s members before"},{"line_number":5,"context_line":"    it waits for the first answer, when it reads the members with their"}],"source_content_type":"text/x-yaml","patch_set":1,"id":"70637ed4_30444675","line":2,"updated":"2026-10-21 14:05:22.000000000","message":"```suggestion\nfixes:\n```\n\n?","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ff389adb94976591ab703b58d9cb33a6b5fd9ea8","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"other:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ZooKeeper driver now sends the reads of all a group\u0027s members before"},{"line_number":5,"context_line":"    it waits for the first answer, when it reads the members with their"}],"source_content_type":"text/x-yaml","patch_set":1,"id":"e419e4c3_6a57a819","line":2,"in_reply_to":"70637ed4_30444675","updated":"2026-10-21 18:41:24.000000000","message":"Done in PS2.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"721e7b3544966b6ed91bb42b545283cac8f1549b","unresolved":true,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"other:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ZooKeeper driver now sends the reads of all a group\u0027s members before"},{"line_number":5,"context_line":"    it waits for the first answer, when it reads the members with their"},{"line_number":6,"context_line":"    capabilities. With 1,000 members on a local ensemble, reading them takes"},{"line_number":7,"context_line":"    about 90 ms instead of 390 ms."}],"source_content_type":"text/x-yaml","patch_set":1,"id":"5ec5980d_2a71d094","line":4,"range":{"start_line":4,"start_character":29,"end_line":4,"end_character":34},"updated":"2026-10-21 14:37:25.000000000","message":"Does it actually send read request to zookeeprr or does it just submit a read request task into a callback queue being processed by threading ? The description gives the impression like the former behavior but the kazoo documentation gives the impression of the latter.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ff389adb94976591ab703b58d9cb33a6b5fd9ea8","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"other:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    The ZooKeeper driver now sends the reads of all a group\u0027s members before"},{"line_number":5,"context_line":"    it waits for the first answer, when it reads the members with their"},{"line_number":6,"context_line":"    capabilities. With 1,000 members on a local ensemble, reading them takes"},{"line_number":7,"context_line":"    about 90 ms instead of 390 ms."}],"source_content_type":"text/x-yaml","patch_set":1,"id":"f7fc6e81_54c5ad12","line":4,"in_reply_to":"5ec5980d_2a71d094","updated":"2026-10-21 18:41:24.000000000","message":"Good catch, the note was not precise. get_async() puts the request on kazoo\u0027s queue and wakes its connection thread, and that thread does the sending. It does not use the handler\u0027s callback queue, as we register no callbacks. The thread sends one queued request and reads one answer per loop, so the reads go out back to back without waiting for their answers. The old get() took the same path: it is get_async().get().\n\nI reworded the note, the code comment and the commit message in PS2 to say this.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"}],"tooz/drivers/zookeeper.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"721e7b3544966b6ed91bb42b545283cac8f1549b","unresolved":true,"context_lines":[{"line_number":482,"context_line":"            for m in members_ids:"},{"line_number":483,"context_line":"                member_id \u003d m.encode(\u0027ascii\u0027)"},{"line_number":484,"context_line":"                member_path \u003d self._path_member(group_id, member_id)"},{"line_number":485,"context_line":"                reads.append((member_id, self._coord.get_async(member_path)))"},{"line_number":486,"context_line":"            result: dict[bytes, coordination.Capabilities | None] \u003d {}"},{"line_number":487,"context_line":"            for member_id, read in reads:"},{"line_number":488,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"7b963aa1_620e4288","line":485,"range":{"start_line":485,"start_character":41,"end_line":485,"end_character":75},"updated":"2026-10-21 14:37:25.000000000","message":"While I like the approach of batching for effeciency, do we need some thrttoling mechanism here ? AFAIK these async jobs are handled by a sing thread eventually so if one thread attempts to read many members it may block the whole async mechanism.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":10273,"name":"Adam Harwell","email":"flux.adam@gmail.com","username":"rm_you"},"change_message_id":"ff389adb94976591ab703b58d9cb33a6b5fd9ea8","unresolved":true,"context_lines":[{"line_number":482,"context_line":"            for m in members_ids:"},{"line_number":483,"context_line":"                member_id \u003d m.encode(\u0027ascii\u0027)"},{"line_number":484,"context_line":"                member_path \u003d self._path_member(group_id, member_id)"},{"line_number":485,"context_line":"                reads.append((member_id, self._coord.get_async(member_path)))"},{"line_number":486,"context_line":"            result: dict[bytes, coordination.Capabilities | None] \u003d {}"},{"line_number":487,"context_line":"            for member_id, read in reads:"},{"line_number":488,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"e8eeb1e4_4099279a","line":485,"range":{"start_line":485,"start_character":41,"end_line":485,"end_character":75},"in_reply_to":"7b963aa1_620e4288","updated":"2026-10-21 18:41:24.000000000","message":"I measured it to check. Setup: one group of 5,001 members, a local three-server ensemble, ZooKeeper 3.8.4, kazoo 2.11.0, all on one laptop. The results were ... somewhat counter-intuitive.\n\n- Both versions send the same 5,001 requests. In this run, all at once took 0.37 s instead of 1.8 s. It used about half the server CPU (0.57 s instead of 1.04 s) and 40% of the client CPU (0.38 s instead of 0.94 s).\n- It does not block the connection thread. Other requests on the same client wait their turn behind the queued reads: up to 31-32 ms with 5,001 members, against 3-4 ms one at a time.\n- A client reading alone had at most 185 reads in flight, as the thread sends one request and reads one answer per loop.\n- Other clients of the same server: no change while 1 or 4 processes re-read the group in a loop. With 16 at the same moment, another client\u0027s small get took 2.1 ms median and 12-20 ms worst, against 0.7 ms and 2.6-4.1 ms when the 16 read one at a time. Those 16 readers also did 2.5 to 3 times as many reads, at a third of the server CPU per read.\n- If many big reads overlap, ZooKeeper\u0027s own globalOutstandingLimit pauses reading from busy connections until the server catches up. It fails nothing.\n- A cap did not help: a cap of 1,000 reads in flight changed almost nothing (360 ms, 31 ms worst wait), and a cap of 64 cut the wait to 5 ms but doubled the read time.\n\nSo I\u0027d like to keep it without a cap. I can add one if you still prefer it, but I don\u0027t believe the slight extra wait (when it exists) is actually much of a net negative versus the benefit. I encourage you to do your own comparison if you\u0027ve got the cycles/tokens to validate my findings, as I don\u0027t always trust AI test results on the first pass.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"df953d59d964ef36d453c26d17ffe0657c3d97a8","unresolved":false,"context_lines":[{"line_number":482,"context_line":"            for m in members_ids:"},{"line_number":483,"context_line":"                member_id \u003d m.encode(\u0027ascii\u0027)"},{"line_number":484,"context_line":"                member_path \u003d self._path_member(group_id, member_id)"},{"line_number":485,"context_line":"                reads.append((member_id, self._coord.get_async(member_path)))"},{"line_number":486,"context_line":"            result: dict[bytes, coordination.Capabilities | None] \u003d {}"},{"line_number":487,"context_line":"            for member_id, read in reads:"},{"line_number":488,"context_line":"                try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"ea508736_30b63820","line":485,"range":{"start_line":485,"start_character":41,"end_line":485,"end_character":75},"in_reply_to":"e8eeb1e4_4099279a","updated":"2026-10-22 09:47:23.000000000","message":"OK. I\u0027m curious if the result can be different if zookeeper is connected over network and read takes some rond-trip time. However this API is relatively new and I assume people are not yet using it extensively, let\u0027s keep the current implementation as-is and fix it in case anyone actually find this problematic.","commit_id":"98a9449b8afaabcdf4c44c44b2ce64dac9300de9"}]}
