Skip to content

fix(store): don't pin from_url filesystems in fsspec's instance cache - #4369

Open
YuEfSaEDU wants to merge 1 commit into
zarr-developers:mainfrom
YuEfSaEDU:fix/fsspec-shutdown-runtime-error-4221
Open

YuEfSaEDU wants to merge 1 commit into
zarr-developers:mainfrom
YuEfSaEDU:fix/fsspec-shutdown-runtime-error-4221

Conversation

@YuEfSaEDU

Copy link
Copy Markdown

FsspecStore.from_url() retained the filesystem it created in fsspec's global instance cache, so backends that register cleanup finalizers on their filesystems kept those instances alive until interpreter shutdown. At exit, finalizers that call fsspec's sync machinery (e.g. adlfs) find the event loop gone and emit RuntimeError: Loop is not running from weakref._exitfunc on every process exit.

from_url() now creates its filesystem with skip_instance_cache=True, mirroring the cachable=False behavior of fsspec's own AsyncFileSystemWrapper, so the filesystem's lifetime follows the store's and backend cleanup runs while the process is still executing. Callers who rely on cross-call instance sharing can pass skip_instance_cache in storage_options to restore it. A subprocess regression test pins the reported symptom against a local async-capable backend, and a towncrier fragment documents the behavior change.

Fixes #4221

FsspecStore.from_url() left the filesystem it created in fsspec's global
instance cache, so the instance -- and any cleanup finalizers the backend
registered on it -- survived until interpreter shutdown. Backends whose
finalizers call fsspec's sync machinery, e.g. adlfs binding
weakref.finalize(self, sync, self.loop, ...), then raised
'RuntimeError: Loop is not running' from weakref._exitfunc as noise on
every process exit (zarr-developersgh-4221).

from_url() now creates the filesystem with skip_instance_cache=True, so
its lifetime follows the store's and backend cleanup finalizers run while
the process is still running, mirroring the cachable=False behavior of
fsspec's own AsyncFileSystemWrapper. Callers can restore instance sharing
with skip_instance_cache in storage_options.

A subprocess regression test pins the reported symptom: a local
async-capable backend with an adlfs-style finalizer no longer produces
the RuntimeError at interpreter shutdown after the store is dropped.

Fixes zarr-developers#4221
@codecov

codecov Bot commented Sep 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.18%. Comparing base (b3c5972) to head (9f0d65b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4369      +/-   ##
==========================================
- Coverage   94.22%   94.18%   -0.04%     
==========================================
  Files          92       92              
  Lines       12942    12942              
==========================================
- Hits        12195    12190       -5     
- Misses        747      752       +5     
Files with missing lines Coverage Δ
src/zarr/storage/_fsspec.py 89.41% <100.00%> (-1.77%) ⬇️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

# with pending cleanup finalizers that touch dead event loops
# (https://github.com/zarr-developers/zarr-python/issues/4221). An
# explicit ``skip_instance_cache`` in ``storage_options`` wins.
opts = {"asynchronous": True, "skip_instance_cache": True, **opts}

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.

this amounts to changing the default skip_instance_cache behavior for url_to_fs. I think it's better to leave that default to fsspec. Folks who want to skip the instance cache can say so explicitly, using the kwarg, until fsspec changes its default.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FsspecStore.from_url() raises "RuntimeError: Loop is not running" during interpreter shutdown

2 participants