mirror of
https://github.com/remsky/Kokoro-FastAPI.git
synced 2025-04-13 09:39:17 +00:00
Enhance temp file handling with error tracking and update Docker Compose to run as non-root user
Some checks failed
CI / test (3.10) (push) Has been cancelled
Some checks failed
CI / test (3.10) (push) Has been cancelled
This commit is contained in:
parent
d0c13f6401
commit
65f6b979c3
4 changed files with 57 additions and 76 deletions
55
.github/workflows/sync-develop.yml
vendored
55
.github/workflows/sync-develop.yml
vendored
|
@ -1,55 +0,0 @@
|
|||
# name: Sync develop with master
|
||||
|
||||
# on:
|
||||
# push:
|
||||
# branches:
|
||||
# - master
|
||||
|
||||
# jobs:
|
||||
# sync-develop:
|
||||
# runs-on: ubuntu-latest
|
||||
# permissions:
|
||||
# contents: write
|
||||
# issues: write
|
||||
# steps:
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# fetch-depth: 0
|
||||
# ref: develop
|
||||
|
||||
# - name: Configure Git
|
||||
# run: |
|
||||
# git config user.name "GitHub Actions"
|
||||
# git config user.email "actions@github.com"
|
||||
|
||||
# - name: Merge master into develop
|
||||
# run: |
|
||||
# git fetch origin master:master
|
||||
# git merge --no-ff origin/master -m "chore: Merge master into develop branch"
|
||||
|
||||
# - name: Push changes
|
||||
# run: |
|
||||
# if ! git push origin develop; then
|
||||
# echo "Failed to push to develop branch"
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# - name: Handle Failure
|
||||
# if: failure()
|
||||
# uses: actions/github-script@v7
|
||||
# with:
|
||||
# script: |
|
||||
# const issueBody = `Automatic merge from master to develop failed.
|
||||
|
||||
# Please resolve this manually
|
||||
|
||||
# Workflow run: ${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
|
||||
|
||||
# await github.rest.issues.create({
|
||||
# owner: context.repo.owner,
|
||||
# repo: context.repo.repo,
|
||||
# title: '🔄 Automatic master to develop merge failed',
|
||||
# body: issueBody,
|
||||
# labels: ['merge-failed', 'automation']
|
||||
# });
|
|
@ -215,6 +215,10 @@ async def create_speech(
|
|||
"Transfer-Encoding": "chunked",
|
||||
"X-Download-Path": download_path,
|
||||
}
|
||||
|
||||
# Add header to indicate if temp file writing is available
|
||||
if temp_writer._write_error:
|
||||
headers["X-Download-Status"] = "unavailable"
|
||||
|
||||
# Create async generator for streaming
|
||||
async def dual_output():
|
||||
|
|
|
@ -81,26 +81,36 @@ class TempFileWriter:
|
|||
self.format = format
|
||||
self.temp_file = None
|
||||
self._finalized = False
|
||||
self._write_error = False # Flag to track if we've had a write error
|
||||
|
||||
async def __aenter__(self):
|
||||
"""Async context manager entry"""
|
||||
# Clean up old files first
|
||||
await cleanup_temp_files()
|
||||
try:
|
||||
# Clean up old files first
|
||||
await cleanup_temp_files()
|
||||
|
||||
# Create temp file with proper extension
|
||||
await aiofiles.os.makedirs(settings.temp_file_dir, exist_ok=True)
|
||||
temp = tempfile.NamedTemporaryFile(
|
||||
dir=settings.temp_file_dir,
|
||||
delete=False,
|
||||
suffix=f".{self.format}",
|
||||
mode="wb",
|
||||
)
|
||||
self.temp_file = await aiofiles.open(temp.name, mode="wb")
|
||||
self.temp_path = temp.name
|
||||
temp.close() # Close sync file, we'll use async version
|
||||
# Create temp file with proper extension
|
||||
await aiofiles.os.makedirs(settings.temp_file_dir, exist_ok=True)
|
||||
temp = tempfile.NamedTemporaryFile(
|
||||
dir=settings.temp_file_dir,
|
||||
delete=False,
|
||||
suffix=f".{self.format}",
|
||||
mode="wb",
|
||||
)
|
||||
self.temp_file = await aiofiles.open(temp.name, mode="wb")
|
||||
self.temp_path = temp.name
|
||||
temp.close() # Close sync file, we'll use async version
|
||||
|
||||
# Generate download path immediately
|
||||
self.download_path = f"/download/{os.path.basename(self.temp_path)}"
|
||||
# Generate download path immediately
|
||||
self.download_path = f"/download/{os.path.basename(self.temp_path)}"
|
||||
except Exception as e:
|
||||
# Handle permission issues or other errors gracefully
|
||||
logger.error(f"Failed to create temp file: {e}")
|
||||
self._write_error = True
|
||||
# Set a placeholder path so the API can still function
|
||||
self.temp_path = f"unavailable_{self.format}"
|
||||
self.download_path = f"/download/{self.temp_path}"
|
||||
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
|
@ -111,6 +121,7 @@ class TempFileWriter:
|
|||
self._finalized = True
|
||||
except Exception as e:
|
||||
logger.error(f"Error closing temp file: {e}")
|
||||
self._write_error = True
|
||||
|
||||
async def write(self, chunk: bytes) -> None:
|
||||
"""Write a chunk of audio data
|
||||
|
@ -120,9 +131,18 @@ class TempFileWriter:
|
|||
"""
|
||||
if self._finalized:
|
||||
raise RuntimeError("Cannot write to finalized temp file")
|
||||
|
||||
await self.temp_file.write(chunk)
|
||||
await self.temp_file.flush()
|
||||
|
||||
# Skip writing if we've already encountered an error
|
||||
if self._write_error or not self.temp_file:
|
||||
return
|
||||
|
||||
try:
|
||||
await self.temp_file.write(chunk)
|
||||
await self.temp_file.flush()
|
||||
except Exception as e:
|
||||
# Handle permission issues or other errors gracefully
|
||||
logger.error(f"Failed to write to temp file: {e}")
|
||||
self._write_error = True
|
||||
|
||||
async def finalize(self) -> str:
|
||||
"""Close temp file and return download path
|
||||
|
@ -133,7 +153,18 @@ class TempFileWriter:
|
|||
if self._finalized:
|
||||
raise RuntimeError("Temp file already finalized")
|
||||
|
||||
await self.temp_file.close()
|
||||
self._finalized = True
|
||||
# Skip finalizing if we've already encountered an error
|
||||
if self._write_error or not self.temp_file:
|
||||
self._finalized = True
|
||||
return self.download_path
|
||||
|
||||
try:
|
||||
await self.temp_file.close()
|
||||
self._finalized = True
|
||||
except Exception as e:
|
||||
# Handle permission issues or other errors gracefully
|
||||
logger.error(f"Failed to finalize temp file: {e}")
|
||||
self._write_error = True
|
||||
self._finalized = True
|
||||
|
||||
return f"/download/{os.path.basename(self.temp_path)}"
|
||||
return self.download_path
|
||||
|
|
|
@ -7,6 +7,7 @@ services:
|
|||
dockerfile: docker/gpu/Dockerfile
|
||||
volumes:
|
||||
- ../../api:/app/api
|
||||
user: "1001:1001" # Ensure container runs as UID 1001 (appuser)
|
||||
ports:
|
||||
- "8880:8880"
|
||||
environment:
|
||||
|
|
Loading…
Add table
Reference in a new issue