)]}'
{"zuul/configloader.py":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"389ca587d33c04a0b62528495de8ec9227a0e4ee","unresolved":true,"context_lines":[{"line_number":2026,"context_line":"        job.extra_config_dirs \u003d extra_config_dirs"},{"line_number":2027,"context_line":"        job.ltime \u003d ltime"},{"line_number":2028,"context_line":"        job.source_context \u003d source_context"},{"line_number":2029,"context_line":"        jobs.append(job)"},{"line_number":2030,"context_line":""},{"line_number":2031,"context_line":"    def _processCatJobs(self, abide, tenant, loading_errors, jobs, min_ltimes):"},{"line_number":2032,"context_line":"        # Called at the end of _cacheTenantYAML after all cat jobs"}],"source_content_type":"text/x-python","patch_set":6,"id":"b01f9936_03b3d0c7","line":2029,"updated":"2022-06-20 23:10:49.000000000","message":"I think this is currently safe as written because we only ever modify the list itself and not the list contents in the portion of code that will have contention. Thinking out loud we might want to consider using something like queue.Queue to be explicitly thread safe to avoid any problems should the code change in the future?","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"04285cf37b0dae99f17cdc8678f8d2c0c648be71","unresolved":false,"context_lines":[{"line_number":2026,"context_line":"        job.extra_config_dirs \u003d extra_config_dirs"},{"line_number":2027,"context_line":"        job.ltime \u003d ltime"},{"line_number":2028,"context_line":"        job.source_context \u003d source_context"},{"line_number":2029,"context_line":"        jobs.append(job)"},{"line_number":2030,"context_line":""},{"line_number":2031,"context_line":"    def _processCatJobs(self, abide, tenant, loading_errors, jobs, min_ltimes):"},{"line_number":2032,"context_line":"        # Called at the end of _cacheTenantYAML after all cat jobs"}],"source_content_type":"text/x-python","patch_set":6,"id":"2b869552_e30b9808","line":2029,"updated":"2022-06-20 23:18:58.000000000","message":"The basic structure here hasn\u0027t changed for some time, and I think \"accumulate list of jobs to wait on\" is a simple and well-defined enough use case to just rely on the atomicity of job.append (and worth the simplicity in this case).","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"389ca587d33c04a0b62528495de8ec9227a0e4ee","unresolved":true,"context_lines":[{"line_number":2505,"context_line":""},{"line_number":2506,"context_line":"        # Pre-load TenantProjectConfigs so we can get and cache all of a"},{"line_number":2507,"context_line":"        # project\u0027s config files (incl. tenant specific extra config) at once."},{"line_number":2508,"context_line":"        with ThreadPoolExecutor(max_workers\u003d4) as executor:"},{"line_number":2509,"context_line":"            for tenant_name, unparsed_config in tenants_to_load.items():"},{"line_number":2510,"context_line":"                config_tpcs, untrusted_tpcs \u003d ("},{"line_number":2511,"context_line":"                    self.tenant_parser.loadTenantProjects(unparsed_config,"}],"source_content_type":"text/x-python","patch_set":6,"id":"ec2216e4_8256ae67","line":2508,"updated":"2022-06-20 23:10:49.000000000","message":"Nit, in the zuul context an executor is the thing that runs the CI/CD jobs with ansible. Might be more clear to call this tpool or similar just to avoid confusion.","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"04285cf37b0dae99f17cdc8678f8d2c0c648be71","unresolved":false,"context_lines":[{"line_number":2505,"context_line":""},{"line_number":2506,"context_line":"        # Pre-load TenantProjectConfigs so we can get and cache all of a"},{"line_number":2507,"context_line":"        # project\u0027s config files (incl. tenant specific extra config) at once."},{"line_number":2508,"context_line":"        with ThreadPoolExecutor(max_workers\u003d4) as executor:"},{"line_number":2509,"context_line":"            for tenant_name, unparsed_config in tenants_to_load.items():"},{"line_number":2510,"context_line":"                config_tpcs, untrusted_tpcs \u003d ("},{"line_number":2511,"context_line":"                    self.tenant_parser.loadTenantProjects(unparsed_config,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f60e68a_ffb154d3","line":2508,"updated":"2022-06-20 23:18:58.000000000","message":"True.  We call it \"process_worker\" in the executor itself (though that\u0027s also a little misleading, since it\u0027s a ProcessPoolExecutor which itself has workers).  I like tpool/thread_pool (and maybe process_pool) for future work.","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"},{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"389ca587d33c04a0b62528495de8ec9227a0e4ee","unresolved":true,"context_lines":[{"line_number":2594,"context_line":"            return None"},{"line_number":2595,"context_line":""},{"line_number":2596,"context_line":"        unparsed_config \u003d unparsed_abide.tenants[tenant_name]"},{"line_number":2597,"context_line":"        with ThreadPoolExecutor(max_workers\u003d4) as executor:"},{"line_number":2598,"context_line":"            new_tenant \u003d self.tenant_parser.fromYaml("},{"line_number":2599,"context_line":"                abide, unparsed_config, ansible_manager, executor,"},{"line_number":2600,"context_line":"                min_ltimes, layout_uuid, branch_cache_min_ltimes,"}],"source_content_type":"text/x-python","patch_set":6,"id":"00a30810_348f9a41","line":2597,"updated":"2022-06-20 23:10:49.000000000","message":"See above.","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"}],"zuul/zk/__init__.py":[{"author":{"_account_id":4146,"name":"Clark Boylan","email":"cboylan@sapwetik.org","username":"cboylan"},"change_message_id":"389ca587d33c04a0b62528495de8ec9227a0e4ee","unresolved":true,"context_lines":[{"line_number":215,"context_line":"                self.client.create(\"/zuul/ltime\", b\"\", makepath\u003dTrue)"},{"line_number":216,"context_line":"                zstat \u003d self.client.set(\"/zuul/ltime\", b\"\")"},{"line_number":217,"context_line":"            except NodeExistsError:"},{"line_number":218,"context_line":"                zstat \u003d self.client.set(\"/zuul/ltime\", b\"\")"},{"line_number":219,"context_line":"        return zstat.last_modified_transaction_id"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"994a96cc_b52b388a","line":218,"updated":"2022-06-20 23:10:49.000000000","message":"Does this need to happen in a loop? I\u0027m just wondering if there is one race here can there be multiple failures one after another?","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"},{"author":{"_account_id":1,"name":"James E. Blair","email":"jim@acmegating.com","username":"corvus"},"change_message_id":"04285cf37b0dae99f17cdc8678f8d2c0c648be71","unresolved":false,"context_lines":[{"line_number":215,"context_line":"                self.client.create(\"/zuul/ltime\", b\"\", makepath\u003dTrue)"},{"line_number":216,"context_line":"                zstat \u003d self.client.set(\"/zuul/ltime\", b\"\")"},{"line_number":217,"context_line":"            except NodeExistsError:"},{"line_number":218,"context_line":"                zstat \u003d self.client.set(\"/zuul/ltime\", b\"\")"},{"line_number":219,"context_line":"        return zstat.last_modified_transaction_id"},{"line_number":220,"context_line":""},{"line_number":221,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"8f400a41_ef069d2f","line":218,"updated":"2022-06-20 23:18:58.000000000","message":"Shouldn\u0027t be necessary -- the case with threads [A] and [B] is:\n[A] Attempts to update it; fails because it does not exist\n[B] Attempts to update it; fails because it does not exist\n[B] Creates it; succeeds\n[A] Attempts to create it; fails because it does exist\n[A] Updates it; succeeds\n\nAs long as nothing is deleting it (and nothing should), an alternative circumstance shouldn\u0027t arise.","commit_id":"42e1e1e324ac9d29b15dc4c8ba2ca58d9b219e88"}]}
