Skip to content

Batch Zarr attribute writes: fixes the split hang in CI - #11

Merged
Claptar merged 1 commit into
mainfrom
fix/zarr-attr-write-batching
Sep 15, 2026
Merged

Claptar merged 1 commit into
mainfrom
fix/zarr-attr-write-batching

Conversation

@Claptar

@Claptar Claptar commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

pytest-timeout earned its place immediately: it caught the intermittent CI hang I couldn't locate before, on the very first run after it was added.

Root cause

The main thread was stuck in zarr's sync-over-async bridge:

cli.py:536 split
split.py:117 split_store
subset.py:654 subset_h5ad
subset.py:194 subset_axis_group
storage/__init__.py:233 copy_attrs
zarr/core/attributes.py:26 __setitem__
zarr/core/group.py:2130 update_attributes
zarr/core/sync.py:204 _sync          <- waiting here

Every attrs[k] = v on a Zarr group persists the whole metadata document through that bridge. copy_attrs was doing one round trip per attribute, and set_encoding two per element. split repeats that once per output group, which is why only that command exhibited it — the thread dump showed 288 threads created and four idle asyncio workers.

Fix

Attributes are written in a single put() on Zarr, falling back to assignment on HDF5, which has no batch API. That removes most of the round trips rather than merely making a collision less likely.

On the previous attempt

I earlier fixed subset_h5ad nesting a Rich Progress inside a console.status on the same console, and suggested that might be the cause. It wasn't — the hang recurred afterwards. That change stands on its own merits (Rich permits one live display per console, and the nesting was plainly wrong), but it should not be credited with fixing this.

Evidence

  • Ten consecutive runs of the split and zarr tests: no hangs, no failures.
  • Full suite green; 1029 tests including the compatibility matrix.

🤖 Generated with Claude Code

pytest-timeout caught the hang I could not locate before. The main thread was
stuck in zarr's sync-over-async bridge:

    split_store -> subset_h5ad -> subset_axis_group -> copy_attrs
      -> zarr Attributes.__setitem__ -> Group.update_attributes
      -> zarr.core.sync.sync

Every `attrs[k] = v` on a Zarr group persists the whole metadata document
through that bridge, so copy_attrs was doing one round trip per attribute and
set_encoding two per element. `split` repeats all of it once per output group,
which is why only that command showed it; the thread dump had 288 threads and
four idle asyncio workers.

Attributes are now written in a single `put()` on Zarr, falling back to
assignment on HDF5, which has no batch API. That removes most of the round
trips rather than just making them less likely to collide.

The earlier Rich live-display fix stands on its own merits -- nesting two live
displays on one console is wrong regardless -- but it was not the cause.

Ten consecutive runs of the split and zarr tests: no hangs, no failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 15, 2026 15:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-15T15:17:14.393206Z 7183235 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown

Test Results (py3.13)

825 tests  +825   825 ✅ +825   1m 11s ⏱️ + 1m 11s
  1 suites +  1     0 💤 ±  0 
  1 files   +  1     0 ❌ ±  0 

Results for commit 7183235. ± Comparison against base commit 0c69116.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown

Test Results (py3.12)

825 tests  ±0   825 ✅ ±0   1m 25s ⏱️ -3s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 7183235. ± Comparison against base commit 0c69116.

♻️ This comment has been updated with latest results.

@Claptar
Claptar merged commit 7f4df63 into main Sep 15, 2026
11 checks passed
@Claptar
Claptar deleted the fix/zarr-attr-write-batching branch September 15, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants