)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"d3edfd56a956e4905762a024636257c46d0a580f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"79766f64_3d7c81ce","updated":"2025-12-04 17:54:27.000000000","message":"Thanks a lot for this patch!","commit_id":"634b457ccf3c6e21e7240cd2e34c5c3feb4b1e1b"}],"neutron/agent/metadata/proxy_base.py":[{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"433970b5aaecedfa26538dc887b8fc8138e213d4","unresolved":true,"context_lines":[{"line_number":47,"context_line":"    return workers"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class ThreadPoolUnixStreamServer(socketserver.ThreadingUnixStreamServer):"},{"line_number":51,"context_line":"    def __init__(self, max_workers, *kargs, **kwargs):"},{"line_number":52,"context_line":"        super().__init__(*kargs, **kwargs)"},{"line_number":53,"context_line":"        self.pool \u003d futures.ThreadPoolExecutor(max_workers\u003dmax_workers)"}],"source_content_type":"text/x-python","patch_set":3,"id":"b7e2151f_60cf4d7c","line":50,"range":{"start_line":50,"start_character":46,"end_line":50,"end_character":71},"updated":"2025-11-26 15:00:27.000000000","message":"Hmm I created this based on the implementation in old python versions, it seems. Let me update this to adopt recent versions.","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"7053365fdc972cea61427db7d8c2c90c371cc8d0","unresolved":false,"context_lines":[{"line_number":47,"context_line":"    return workers"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"class ThreadPoolUnixStreamServer(socketserver.ThreadingUnixStreamServer):"},{"line_number":51,"context_line":"    def __init__(self, max_workers, *kargs, **kwargs):"},{"line_number":52,"context_line":"        super().__init__(*kargs, **kwargs)"},{"line_number":53,"context_line":"        self.pool \u003d futures.ThreadPoolExecutor(max_workers\u003dmax_workers)"}],"source_content_type":"text/x-python","patch_set":3,"id":"50028c1c_6a43d927","line":50,"range":{"start_line":50,"start_character":46,"end_line":50,"end_character":71},"in_reply_to":"b7e2151f_60cf4d7c","updated":"2025-11-26 16:27:19.000000000","message":"Done","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"de6aff3cc839dddf8b827276200095a9d66d2a54","unresolved":true,"context_lines":[{"line_number":52,"context_line":"    def __init__(self, *kargs, **kwargs):"},{"line_number":53,"context_line":"        super().__init__(*kargs, **kwargs)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        workers \u003d cfg.CONF.metadata_workers"},{"line_number":56,"context_line":"        if not workers:"},{"line_number":57,"context_line":"            workers \u003d int((processutils.get_worker_count() + 1) / 2)"},{"line_number":58,"context_line":"        self._pool \u003d futures.ThreadPoolExecutor(max_workers\u003dworkers)"}],"source_content_type":"text/x-python","patch_set":7,"id":"7a0639d8_ac96a631","line":55,"range":{"start_line":55,"start_character":27,"end_line":55,"end_character":43},"updated":"2025-11-28 16:23:17.000000000","message":"We are recommending our internal users to set `metadata_workers\u003d0`, within the previous implementation, because of [1]. With this implementation we don\u0027t spawn new processes but threads. In case of setting `metadata_workers\u003d0`, we could\n* Default to the previous implementation.\n* Assign `metadata_workers\u003d1`, that will be similar to the previous implementation.\n\n[1]https://review.opendev.org/c/openstack/neutron/+/861649","commit_id":"5d1ea6b552a204e4334da22c842882faab83c213"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"70c566addcc48e4831db6f3f4f841b5416d1b2cc","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    def __init__(self, *kargs, **kwargs):"},{"line_number":53,"context_line":"        super().__init__(*kargs, **kwargs)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        workers \u003d cfg.CONF.metadata_workers"},{"line_number":56,"context_line":"        if not workers:"},{"line_number":57,"context_line":"            workers \u003d int((processutils.get_worker_count() + 1) / 2)"},{"line_number":58,"context_line":"        self._pool \u003d futures.ThreadPoolExecutor(max_workers\u003dworkers)"}],"source_content_type":"text/x-python","patch_set":7,"id":"acd36292_10c6a9bd","line":55,"range":{"start_line":55,"start_character":27,"end_line":55,"end_character":43},"in_reply_to":"7a0639d8_ac96a631","updated":"2025-12-04 10:44:37.000000000","message":"I checked the old implementation and updated the code to use the in-process handler when metadata_workers\u003d0.","commit_id":"5d1ea6b552a204e4334da22c842882faab83c213"}],"neutron/conf/agent/metadata/config.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"2b949b62fa16b16f695f6f0316b0d4fadc7522bc","unresolved":true,"context_lines":[{"line_number":96,"context_line":"                      \"otherwise.\")),"},{"line_number":97,"context_line":"    cfg.IntOpt(\u0027metadata_workers\u0027,"},{"line_number":98,"context_line":"               sample_default\u003d\u0027\u003cnum_of_cpus\u003e / 2\u0027,"},{"line_number":99,"context_line":"               help\u003d_(\u0027Number of separate worker threads for metadata \u0027"},{"line_number":100,"context_line":"                      \u0027server\u0027)),"},{"line_number":101,"context_line":"    cfg.IntOpt(\u0027metadata_backlog\u0027,"},{"line_number":102,"context_line":"               default\u003d4096,"},{"line_number":103,"context_line":"               help\u003d_(\u0027Number of backlog requests to configure the \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"bc3c8881_eeae2f8e","line":100,"range":{"start_line":99,"start_character":22,"end_line":100,"end_character":29},"updated":"2025-11-26 14:46:46.000000000","message":"That\u0027s the point here: this feature was expecting to have independent processes to handle the metadata requests, not threads inside the same process. This implementation is not the same as with the eventlet socket.\n\nDoes this implementation provide concurrency when multiple requests are executed?","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"70c566addcc48e4831db6f3f4f841b5416d1b2cc","unresolved":false,"context_lines":[{"line_number":96,"context_line":"                      \"otherwise.\")),"},{"line_number":97,"context_line":"    cfg.IntOpt(\u0027metadata_workers\u0027,"},{"line_number":98,"context_line":"               sample_default\u003d\u0027\u003cnum_of_cpus\u003e / 2\u0027,"},{"line_number":99,"context_line":"               help\u003d_(\u0027Number of separate worker threads for metadata \u0027"},{"line_number":100,"context_line":"                      \u0027server\u0027)),"},{"line_number":101,"context_line":"    cfg.IntOpt(\u0027metadata_backlog\u0027,"},{"line_number":102,"context_line":"               default\u003d4096,"},{"line_number":103,"context_line":"               help\u003d_(\u0027Number of backlog requests to configure the \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"0c87e593_a5ca86a1","line":100,"range":{"start_line":99,"start_character":22,"end_line":100,"end_character":29},"in_reply_to":"35cfa8a1_0b584966","updated":"2025-12-04 10:44:37.000000000","message":"Done","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"c9722925d412948a88813ea9d242888e8fbcfc04","unresolved":true,"context_lines":[{"line_number":96,"context_line":"                      \"otherwise.\")),"},{"line_number":97,"context_line":"    cfg.IntOpt(\u0027metadata_workers\u0027,"},{"line_number":98,"context_line":"               sample_default\u003d\u0027\u003cnum_of_cpus\u003e / 2\u0027,"},{"line_number":99,"context_line":"               help\u003d_(\u0027Number of separate worker threads for metadata \u0027"},{"line_number":100,"context_line":"                      \u0027server\u0027)),"},{"line_number":101,"context_line":"    cfg.IntOpt(\u0027metadata_backlog\u0027,"},{"line_number":102,"context_line":"               default\u003d4096,"},{"line_number":103,"context_line":"               help\u003d_(\u0027Number of backlog requests to configure the \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"35cfa8a1_0b584966","line":100,"range":{"start_line":99,"start_character":22,"end_line":100,"end_character":29},"in_reply_to":"48eb8819_5896c79a","updated":"2025-11-28 15:41:44.000000000","message":"I\u0027ve added an upgrade section to describe this. Does it look good to you ?","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":9816,"name":"Takashi Kajinami","email":"kajinamit@oss.nttdata.com","username":"kajinamit"},"change_message_id":"433970b5aaecedfa26538dc887b8fc8138e213d4","unresolved":true,"context_lines":[{"line_number":96,"context_line":"                      \"otherwise.\")),"},{"line_number":97,"context_line":"    cfg.IntOpt(\u0027metadata_workers\u0027,"},{"line_number":98,"context_line":"               sample_default\u003d\u0027\u003cnum_of_cpus\u003e / 2\u0027,"},{"line_number":99,"context_line":"               help\u003d_(\u0027Number of separate worker threads for metadata \u0027"},{"line_number":100,"context_line":"                      \u0027server\u0027)),"},{"line_number":101,"context_line":"    cfg.IntOpt(\u0027metadata_backlog\u0027,"},{"line_number":102,"context_line":"               default\u003d4096,"},{"line_number":103,"context_line":"               help\u003d_(\u0027Number of backlog requests to configure the \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"fdfd2b57_3ec0d4f9","line":100,"range":{"start_line":99,"start_character":22,"end_line":100,"end_character":29},"in_reply_to":"bc3c8881_eeae2f8e","updated":"2025-11-26 15:00:27.000000000","message":"As far as I know threading in python works concurrently for non-CPU bound workload. (For CPU bound workload a single thread may occupy the core and the other threads can\u0027t run due to GIL, but for network-bound or IO-bound traffics context switching should distribute CPU usage across threads.\n\nMetadata services are a kind of web api servers which interacts with nova over network behind it, so threading should provide better concurrency mechanism.","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"092db423dd2faeae2bdfc28b06b0b9e0753110d7","unresolved":true,"context_lines":[{"line_number":96,"context_line":"                      \"otherwise.\")),"},{"line_number":97,"context_line":"    cfg.IntOpt(\u0027metadata_workers\u0027,"},{"line_number":98,"context_line":"               sample_default\u003d\u0027\u003cnum_of_cpus\u003e / 2\u0027,"},{"line_number":99,"context_line":"               help\u003d_(\u0027Number of separate worker threads for metadata \u0027"},{"line_number":100,"context_line":"                      \u0027server\u0027)),"},{"line_number":101,"context_line":"    cfg.IntOpt(\u0027metadata_backlog\u0027,"},{"line_number":102,"context_line":"               default\u003d4096,"},{"line_number":103,"context_line":"               help\u003d_(\u0027Number of backlog requests to configure the \u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"48eb8819_5896c79a","line":100,"range":{"start_line":99,"start_character":22,"end_line":100,"end_character":29},"in_reply_to":"fdfd2b57_3ec0d4f9","updated":"2025-11-27 20:10:28.000000000","message":"For sure, but we need to document this change. I\u0027m not against this change but users need to know how is now implemented.","commit_id":"3f4685e7f4dee0ba6509299e388608215b3367a8"}],"releasenotes/notes/bug-2132348-fix-metadata-opts-34243ab9f77e770a.yaml":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"de6aff3cc839dddf8b827276200095a9d66d2a54","unresolved":true,"context_lines":[{"line_number":8,"context_line":"    - ``[DEFAULT] metadata_workers``"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":""},{"line_number":11,"context_line":"upgrade:"},{"line_number":12,"context_line":"  - |"},{"line_number":13,"context_line":"    In recent releases of neutron metadata server services launch worker"},{"line_number":14,"context_line":"    threads instead of worker processes. (2025.1 for metadata-agent and"}],"source_content_type":"text/x-yaml","patch_set":7,"id":"9f3055d5_1d42639d","line":11,"range":{"start_line":11,"start_character":0,"end_line":11,"end_character":7},"updated":"2025-11-28 16:23:17.000000000","message":"+1, thanks","commit_id":"5d1ea6b552a204e4334da22c842882faab83c213"}]}
