Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static file generation makes app startup indeterminate #1486

Open
naglepuff opened this issue Dec 6, 2024 · 0 comments · May be fixed by #1504
Open

Static file generation makes app startup indeterminate #1486

naglepuff opened this issue Dec 6, 2024 · 0 comments · May be fixed by #1504

Comments

@naglepuff
Copy link
Collaborator

While looking at the logs of a portal-backend pod in the midst of spinning up, I see the following stack trace:

[2024-12-06 17:36:39 +0000] [40] [ERROR] Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 693, in lifespan
    async with self.lifespan_context(app) as maybe_state:
  File "/usr/local/lib/python3.9/contextlib.py", line 181, in __aenter__
    return await self.gen.__anext__()
  File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 133, in merged_lifespan
    async with original_context(app) as maybe_original_state:
  File "/usr/local/lib/python3.9/contextlib.py", line 181, in __aenter__
    return await self.gen.__anext__()
  File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 133, in merged_lifespan
    async with original_context(app) as maybe_original_state:
  File "/usr/local/lib/python3.9/contextlib.py", line 181, in __aenter__
2024-12-06T17:36:39.975833334Z     return await self.gen.__anext__()
  File "/app/nmdc_server/app.py", line 45, in lifespan
    generate_and_mount_static_files()
  File "/app/nmdc_server/app.py", line 40, in generate_and_mount_static_files
2024-12-06T17:36:39.975869755Z     generate_submission_schema_files(directory=static_path)
  File "/app/nmdc_server/static_files.py", line 43, in generate_submission_schema_files
    shutil.copyfile(str(gold_tree_path), out_dir / "GoldEcosystemTree.json")
  File "/usr/local/lib/python3.9/shutil.py", line 266, in copyfile
    with open(dst, 'wb') as fdst:
FileNotFoundError: [Errno 2] No such file or directory: 'static/submission_schema/GoldEcosystemTree.json'

This is also getting caught by sentry.

I believe that what's happening is several workers are all trying to generate and mount the static files into a directory, but one of the steps taken to do so is to delete the existing directory. This would lead to a race condition between the workers:

  1. Worker A starts by removing the existing static files directory
  2. Worker A creates a new static files directory
  3. Worker B starts by removing the existing static files directory
  4. Worker A tries to add a file to the not-yet-created static files directory

The functions in question are located in nmdc_server/static_files.py, and get called in nmdc_server/app.py::create_app.

One quick fix might be to enable creating parent directories when creating the submission schema directory, i.e.

out_dir = directory / "submission_schema"
out_dir.mkdir(exist_ok=True

becomes

out_dir = directory / "submission_schema"
out_dir.mkdir(parents=True, exist_ok=True)

A better approach might be to move the creating of the static directory and static submission schema files into a CLI subcommand, and call that in prestart.sh, this way the static mounting only happens once.

@naglepuff naglepuff linked a pull request Jan 8, 2025 that will close this issue
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 a pull request may close this issue.

1 participant