Commit a2c06a0
feat: add TTL-based cleanup strategy for DatabaseTriggers collection (#464)
* feat: add TTL-based cleanup strategy for DatabaseTriggers collection
Implements automatic cleanup of completed/failed triggers using MongoDB TTL index
to prevent unbounded growth of the DatabaseTriggers collection.
Changes:
- Added expires_at field to DatabaseTriggers model for TTL tracking
- Created MongoDB TTL index on expires_at with expireAfterSeconds=0
- Added TRIGGER_RETENTION_DAYS setting (default: 30 days, configurable via env)
- Updated mark_as_triggered() to set expiration time on completed triggers
- Updated mark_as_failed() to set expiration time on failed triggers
- PENDING/TRIGGERING triggers remain without expiration (never cleaned up)
Implementation:
- MongoDB automatically deletes documents when expires_at timestamp is reached
- TTL runs in background every 60 seconds (MongoDB default)
- Retention period configurable via TRIGGER_RETENTION_DAYS environment variable
- Only terminal states (TRIGGERED, FAILED) are marked for cleanup
Tests:
- Added comprehensive unit tests for TTL expiration logic
- Tests verify expires_at is set correctly for both TRIGGERED and FAILED states
- Tests verify custom retention periods are respected
- All 4 new tests passing
Also bumped python-sdk version to 0.0.3b2
Resolves #433
* perf: optimize settings access and fix timezone handling for TTL
Performance optimization:
- Fetch settings once at trigger_cron() level instead of per-trigger
- Pass retention_days as parameter to mark functions
- Prevents repeated environment variable reads in high-volume scenarios
- Eliminates performance degradation when processing triggers in loops
Timezone fix (critical):
- Use timezone-aware datetime.now(timezone.utc) instead of naive datetime.now()
- Prevents shifted expirations on non-UTC hosts
- PyMongo treats naive datetimes as UTC, causing incorrect TTL windows
- All expires_at timestamps now explicitly UTC for consistency
CANCELLED trigger cleanup:
- Added mark_as_cancelled() function for future cancellation logic
- CANCELLED triggers now expire under same retention policy as TRIGGERED/FAILED
- Ensures all terminal states (TRIGGERED, FAILED, CANCELLED) are cleaned up
Test improvements:
- Refactored using pytest.mark.parametrize to reduce duplication
- Added timezone-awareness assertions to verify UTC timestamps
- Combined similar tests for all 3 terminal states
- Reduced test code from ~120 lines to ~85 lines while increasing coverage
- 6 parameterized tests passing (3 states × 2 test scenarios)
Signed-off-by: Sparsh <sparsh.raj30@gmail.com>
* docs: add docstring to mark_as_cancelled and improve test coverage
- Add comprehensive docstring to mark_as_cancelled() explaining it's reserved
for future cancellation feature implementation
- Rename test_trigger_ttl.py to test_trigger_cron.py to match module name
- Expand parametrized tests: test all 3 mark functions with 3 retention periods
(9 combinations) for consistent coverage
- Add 9 new tests covering all trigger_cron.py functions:
- get_due_triggers (with/without triggers)
- call_trigger_graph
- create_next_triggers (success, DuplicateKeyError, other exceptions)
- handle_trigger (success and failure paths)
- trigger_cron orchestration
- Total: 18 comprehensive tests with timezone-aware datetime assertions
Signed-off-by: Sparsh <sparsh.raj30@gmail.com>
* Removed Cancelled state from partial index
Signed-off-by: Sparsh <sparsh.raj30@gmail.com>
* refactor: update trigger status filtering and add expiration logic
- Changed the partial filter expression in DatabaseTriggers to exclude PENDING and TRIGGERING statuses.
- Introduced an expires_at field in create_crons to set expiration time for triggers based on retention settings, ensuring proper cleanup of triggers after their designated retention period.
This enhances the management of trigger states and ensures that only relevant triggers are retained in the database.
* chore: update codespell ignore words list
- Added "nin" to the list of ignored words in .codespellignorewords.
- Ensured consistency by maintaining the existing format of the file.
* nin->in
* fix: update trigger retention hours to 720
- Changed the default value of trigger_retention_hours from 24 to 720 in settings.py to extend the retention period for triggers, allowing for better management of trigger states.
* docs: add TRIGGER_WORKERS and TRIGGER_RETENTION_HOURS to state manager setup
- Updated the state manager setup documentation to include new environment variables: TRIGGER_WORKERS (default: 1) and TRIGGER_RETENTION_HOURS (default: 720) for better configuration of trigger management.
* feat: add initialization tasks for server startup
- Introduced a new module for initialization tasks that run when the server starts.
- Implemented a task to delete old triggers from the DatabaseTriggers collection based on their status.
- Updated the main application file to call the new initialization tasks during the lifespan of the FastAPI app, ensuring proper cleanup of outdated triggers at startup.
* feat: enhance create_next_triggers with expiration logic
- Updated create_next_triggers function to accept retention_hours as a parameter.
- Introduced expires_at calculation to set expiration time for triggers based on retention settings.
- Ensured proper handling of trigger creation with expiration in the database, improving trigger management.
* docs: update MongoDB database name in state manager setup
- Changed the default value of MONGO_DATABASE_NAME from 'exosphere' to 'exosphere-state-manager' in the state manager setup documentation for clarity and accuracy in configuration.
* fix: update trigger retention hours in tests and settings
- Changed the default value of trigger_retention_hours in settings.py from 24 to 720 to extend the retention period for triggers.
- Updated test cases in test_main.py and test_trigger_cron.py to reflect the new retention_hours parameter in create_next_triggers function, ensuring consistency in trigger management across the application.
---------
Signed-off-by: Sparsh <sparsh.raj30@gmail.com>
Co-authored-by: NiveditJain <nivedit@aikin.club>1 parent 2747e24 commit a2c06a0
10 files changed
Lines changed: 389 additions & 21 deletions
File tree
- .github
- docs/docs/exosphere
- state-manager
- app
- config
- models/db
- tasks
- tests/unit
- tasks
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
32 | 34 | | |
33 | 35 | | |
34 | 36 | | |
| |||
84 | 86 | | |
85 | 87 | | |
86 | 88 | | |
| 89 | + | |
| 90 | + | |
87 | 91 | | |
88 | 92 | | |
89 | 93 | | |
| |||
151 | 155 | | |
152 | 156 | | |
153 | 157 | | |
| 158 | + | |
| 159 | + | |
154 | 160 | | |
155 | 161 | | |
156 | 162 | | |
| |||
182 | 188 | | |
183 | 189 | | |
184 | 190 | | |
| 191 | + | |
| 192 | + | |
185 | 193 | | |
186 | 194 | | |
187 | 195 | | |
| |||
212 | 220 | | |
213 | 221 | | |
214 | 222 | | |
215 | | - | |
| 223 | + | |
216 | 224 | | |
217 | 225 | | |
| 226 | + | |
| 227 | + | |
218 | 228 | | |
219 | 229 | | |
220 | 230 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
21 | 22 | | |
22 | 23 | | |
23 | 24 | | |
24 | | - | |
| 25 | + | |
| 26 | + | |
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
41 | 44 | | |
42 | 45 | | |
43 | 46 | | |
| |||
59 | 62 | | |
60 | 63 | | |
61 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
62 | 69 | | |
63 | 70 | | |
64 | 71 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | | - | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
35 | 51 | | |
36 | 52 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
38 | 40 | | |
39 | 41 | | |
40 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
41 | 46 | | |
42 | 47 | | |
43 | | - | |
| 48 | + | |
44 | 49 | | |
45 | 50 | | |
46 | 51 | | |
47 | 52 | | |
48 | 53 | | |
| 54 | + | |
49 | 55 | | |
50 | 56 | | |
51 | 57 | | |
| |||
54 | 60 | | |
55 | 61 | | |
56 | 62 | | |
57 | | - | |
| 63 | + | |
| 64 | + | |
58 | 65 | | |
59 | 66 | | |
60 | 67 | | |
| |||
65 | 72 | | |
66 | 73 | | |
67 | 74 | | |
68 | | - | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
69 | 78 | | |
70 | 79 | | |
71 | | - | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
72 | 84 | | |
73 | 85 | | |
74 | | - | |
| 86 | + | |
75 | 87 | | |
76 | 88 | | |
77 | 89 | | |
78 | | - | |
| 90 | + | |
79 | 91 | | |
80 | | - | |
| 92 | + | |
81 | 93 | | |
82 | 94 | | |
83 | | - | |
| 95 | + | |
84 | 96 | | |
85 | 97 | | |
86 | 98 | | |
| 99 | + | |
87 | 100 | | |
88 | | - | |
| 101 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
| 14 | + | |
13 | 15 | | |
14 | 16 | | |
15 | 17 | | |
| 18 | + | |
| 19 | + | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
| |||
110 | 114 | | |
111 | 115 | | |
112 | 116 | | |
| 117 | + | |
113 | 118 | | |
114 | 119 | | |
115 | 120 | | |
| |||
118 | 123 | | |
119 | 124 | | |
120 | 125 | | |
121 | | - | |
| 126 | + | |
| 127 | + | |
122 | 128 | | |
123 | 129 | | |
124 | 130 | | |
| |||
0 commit comments