Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 45
feat: add TTL-based cleanup strategy for DatabaseTriggers collection#464
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
c20ec6a16434a65a9893a63665b8b1a9279094dd436dad1a7021e4d5f1362e78831b5b0f7098a8af1c5dbbcb7b0File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -14,4 +14,5 @@ YML | ||
| SDK | ||
| S3 | ||
| Kusto | ||
| NotIn | ||
| NotIn | ||
| nin | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -6,13 +6,14 @@ | ||
| class Settings(BaseModel): | ||
| """Application settings loaded from environment variables.""" | ||
| # MongoDB Configuration | ||
| mongo_uri: str = Field(..., description="MongoDB connection URI" ) | ||
| mongo_database_name: str = Field(default="exosphere-state-manager", description="MongoDB database name") | ||
| state_manager_secret: str = Field(..., description="Secret key for API authentication") | ||
| secrets_encryption_key: str = Field(..., description="Key for encrypting secrets") | ||
| trigger_workers: int = Field(default=1, description="Number of workers to run the trigger cron") | ||
| trigger_retention_hours: int = Field(default=720, description="Number of hours to retain completed/failed triggers before cleanup") | ||
| @classmethod | ||
| def from_env(cls) -> "Settings": | ||
| @@ -21,7 +22,8 @@ def from_env(cls) -> "Settings": | ||
| mongo_database_name=os.getenv("MONGO_DATABASE_NAME", "exosphere-state-manager"), # type: ignore | ||
| state_manager_secret=os.getenv("STATE_MANAGER_SECRET"), # type: ignore | ||
| secrets_encryption_key=os.getenv("SECRETS_ENCRYPTION_KEY"), # type: ignore | ||
| trigger_workers=int(os.getenv("TRIGGER_WORKERS", 1)) # type: ignore | ||
| trigger_workers=int(os.getenv("TRIGGER_WORKERS", 1)), # type: ignore | ||
| trigger_retention_hours=int(os.getenv("TRIGGER_RETENTION_HOURS", 720)) # type: ignore | ||
| ) | ||
NiveditJain marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -38,6 +38,9 @@ | ||
| from apscheduler.schedulers.asyncio import AsyncIOScheduler | ||
| from apscheduler.triggers.cron import CronTrigger | ||
| from .tasks.trigger_cron import trigger_cron | ||
| # init tasks | ||
| from .tasks.init_tasks import init_tasks | ||
| # Define models list | ||
| DOCUMENT_MODELS = [State, GraphTemplate, RegisteredNode, Store, Run, DatabaseTriggers] | ||
| @@ -59,6 +62,10 @@ async def lifespan(app: FastAPI): | ||
| await init_beanie(db, document_models=DOCUMENT_MODELS) | ||
| logger.info("beanie dbs initialized") | ||
| # performing init tasks | ||
| await init_tasks() | ||
| logger.info("init tasks completed") | ||
NiveditJain marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| # initialize secret | ||
| if not settings.state_manager_secret: | ||
| raise ValueError("STATE_MANAGER_SECRET is not set") | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -13,8 +13,9 @@ class DatabaseTriggers(Document): | ||
| namespace: str = Field(..., description="Namespace of the graph") | ||
| trigger_time: datetime = Field(..., description="Trigger time of the trigger") | ||
| trigger_status: TriggerStatusEnum = Field(..., description="Status of the trigger") | ||
| expires_at: Optional[datetime] = Field(default=None, description="Expiration time for automatic cleanup of completed triggers") | ||
NiveditJain marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| class Settings: | ||
| class Settings: | ||
| indexes = [ | ||
| IndexModel( | ||
| [ | ||
| @@ -32,5 +33,20 @@ class Settings: | ||
| ], | ||
| name="uniq_graph_type_expr_time", | ||
| unique=True | ||
| ), | ||
| IndexModel( | ||
| [ | ||
| ("expires_at", 1), | ||
| ], | ||
| name="ttl_expires_at", | ||
| expireAfterSeconds=0, # Delete immediately when expires_at is reached | ||
| partialFilterExpression={ | ||
| "trigger_status": { | ||
| "$in": [ | ||
| TriggerStatusEnum.TRIGGERED, | ||
| TriggerStatusEnum.FAILED | ||
| ] | ||
| } | ||
| } | ||
| ) | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # tasks to run when the server starts | ||
| from app.models.db.trigger import DatabaseTriggers | ||
| from app.models.trigger_models import TriggerStatusEnum | ||
| import asyncio | ||
| async def delete_old_triggers(): | ||
| await DatabaseTriggers.get_pymongo_collection().delete_many( | ||
| { | ||
| "trigger_status": { | ||
| "$in": [TriggerStatusEnum.TRIGGERED, TriggerStatusEnum.FAILED] | ||
| }, | ||
| "expires_at": None | ||
| } | ||
| ) | ||
NiveditJain marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| async def init_tasks(): | ||
| await asyncio.gather( | ||
| *[ | ||
| delete_old_triggers() | ||
| ]) | ||
NiveditJain marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.