fsspec / fsspec/filesystem_spec

concurrent.futures.ProcessPoolExecutor fails for HTTPFileSystem

Open
#1,298 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.4k
Forks
490
Avg merge
2d 3h
Merged PRs (30d)
38

Description

@CodyCBakerPhD and I have been exploring different ways of parallelizing with http fsspec. We have found that you can use multiple processes in joblib (1), and parallelizing over threads using concurrent.futures.ThreadPoolExecutor works (2), but concurrent.futures.ProcessPoolExecutor stalls.

1. Parallel, asynchronous access with joblib

this works:

from joblib import Parallel, delayed

def get_subject_ids_and_session_start_times(s3_url: str) -> tuple:
    file_system_per_run = fsspec.filesystem("http")

    with (
        file_system_per_run.open(path=s3_url, mode="rb") as name,
        h5py.File(name=name) as file,
    ):
        return str(file.keys())

results = Parallel(n_jobs=3)(delayed(get_subject_ids_and_session_start_times)(s3_url) for s3_url in s3_urls)
for output in results:
    print(output)

2. Parallel, asynchronous access with concurrent.futures.ThreadPoolExecutor

this works:

import concurrent.futures

def get_subject_ids_and_session_start_times(s3_url: str) -> tuple:
    file_system_per_run = fsspec.filesystem("http")

    with (
        file_system_per_run.open(path=s3_url, mode="rb") as name,
        h5py.File(name=name) as file,
    ):
        return str(file.keys())

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    futures = [executor.submit(get_subject_ids_and_session_start_times, s3_url) for s3_url in s3_urls]
for future in concurrent.futures.as_completed(futures):
    print(future.result())

3. Parallel, asynchronous access with concurrent.futures.ProcessPoolExecutor

this stalls:

import concurrent.futures

def get_subject_ids_and_session_start_times(s3_url: str) -> tuple:
    file_system_per_run = fsspec.filesystem("http")

    with (    
        file_system_per_run.open(path=s3_url, mode="rb") as name,
        h5py.File(name=name) as file,
    ):
        return str(file.keys())

with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
    futures = [executor.submit(get_subject_ids_and_session_start_times, s3_url) for s3_url in s3_urls]
for future in concurrent.futures.as_completed(futures):
    print(future.result())

@martindurant , any idea why this third method might fail where the other two succeed? Is this third approach in scope for fsspec?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the HTTPFileSystem example with ProcessPoolExecutor, then compare it with the working ThreadPoolExecutor and joblib examples. Inspect the HTTPFileSystem process-pool interaction and determine whether the stall is a defect or an unsupported usage; done means the cause and supported behavior are established, with a regression test or documentation change if appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.