fix caprover log problem

parent 498fa39d
# gunicorn.conf.py
bind = "0.0.0.0:8000"
worker_class = "uvicorn.workers.UvicornWorker"
workers = 4 # Or read from an environment variable
accesslog = "-"
errorlog = "-"
loglevel = "info"
\ No newline at end of file
......@@ -4,6 +4,7 @@ sounddevice
soundfile
fastapi
uvicorn[standard]
gunicorn
python-multipart
openai
psycopg2-binary
......
......@@ -2,8 +2,6 @@
import json
import base64
from typing import Optional, Dict
# Import the Redis client that all workers will share
from .redis_client import redis_client
class ResponseManager:
......@@ -14,70 +12,53 @@ class ResponseManager:
"""
def __init__(self):
"""Initializes by connecting to the shared Redis client."""
if redis_client is None:
raise ConnectionError("ResponseManager requires a valid Redis connection.")
self.redis = redis_client
self.ttl_seconds = 600 # A key will expire 10 mins after the LAST item is added
self.ttl_seconds = 600 # A student's queue will expire 10 mins after the last item is added
def _get_key(self, student_id: str) -> str:
"""Creates a consistent key for the student's queue."""
return f"student_queue:{student_id}"
def store_response(self, student_id: str, text: str, audio_filepath: Optional[str] = None, audio_bytes: Optional[bytes] = None) -> None:
"""
Adds a new response to the END of the queue for a specific student.
"""
"""Adds a new response to the END of the queue for a specific student."""
key = self._get_key(student_id)
encoded_audio = base64.b64encode(audio_bytes).decode('utf-8') if audio_bytes else None
payload = {
"text": text,
"audio_filepath": audio_filepath,
"audio_bytes_b64": encoded_audio
}
# RPUSH adds the new item to the right (end) of the list.
self.redis.rpush(key, json.dumps(payload))
# Reset the expiration time for the whole queue each time a new item is added.
self.redis.expire(key, self.ttl_seconds)
def get_response(self, student_id: str) -> Dict:
"""
Atomically retrieves and removes the OLDEST response from the front of the queue.
"""
"""Atomically retrieves and removes the OLDEST response from the front of the queue."""
key = self._get_key(student_id)
# LPOP atomically retrieves and removes the item from the left (start) of the list.
json_value = self.redis.lpop(key)
if not json_value:
return {"text": None, "audio_filepath": None, "audio_bytes": None}
# Decode the payload.
payload = json.loads(json_value)
if payload.get("audio_bytes_b64"):
payload["audio_bytes"] = base64.b64decode(payload["audio_bytes_b64"])
else:
payload["audio_bytes"] = None
del payload["audio_bytes_b64"]
return payload
def clear_response(self, student_id: str) -> None:
"""
Completely deletes the entire queue for a student. Useful for '/clear' endpoints.
"""
"""Completely deletes the entire queue for a student."""
key = self._get_key(student_id)
self.redis.delete(key)
def is_response_fresh(self, student_id: str) -> bool:
"""
Checks if there are any items in the student's queue.
"""
"""Checks if there are any items in the student's queue."""
key = self._get_key(student_id)
# LLEN gets the length of the list. If it's > 0, there's a response ready.
# LLEN gets the length of the list. If it's > 0, a response is ready.
return self.redis.llen(key) > 0
\ No newline at end of file
......@@ -13,4 +13,4 @@ echo "Curriculum structure setup complete."
sleep 5
# Start the web server and keep it as the main process
exec uvicorn main:app --host 0.0.0.0 --port 8000
\ No newline at end of file
exec gunicorn -c gunicorn.conf.py main:app
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment