Skip to content

Commit cf8bf12

Browse files
authored
Add PySpring Scheduler Documentation (#1)
1 parent c44de17 commit cf8bf12

File tree

2 files changed

+250
-0
lines changed

2 files changed

+250
-0
lines changed

docs/guide/scheduling/scheduler.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
PySpring Scheduler
2+
=================
3+
4+
The PySpring Scheduler provides a robust and flexible way to manage scheduled tasks in your applications, seamlessly integrating with the PySpring framework.
5+
6+
Installation
7+
-----------
8+
9+
Since the package is under active development, it can only be installed directly from the git repository:
10+
11+
```bash
12+
pip install git+ssh://git@github.com/PythonSpring/pyspring-scheduler.git
13+
```
14+
15+
* * * * *
16+
17+
Overview
18+
--------
19+
20+
The scheduler is built on top of APScheduler and provides a component-based approach to scheduling tasks. It supports various trigger types, timezone-aware scheduling, and integrates with PySpring's dependency injection system.
21+
22+
* * * * *
23+
24+
Configuration
25+
------------
26+
27+
The scheduler can be configured through your application's properties file:
28+
29+
```json
30+
{
31+
"scheduler": {
32+
"number_of_workers": 20,
33+
"max_instances": 3,
34+
"timezone": "UTC",
35+
"coalesce": false
36+
}
37+
}
38+
```
39+
40+
### Configuration Options
41+
42+
- `number_of_workers`: Number of threads in the scheduler's thread pool
43+
- `max_instances`: Maximum number of concurrent instances of a job
44+
- `timezone`: Default timezone for all jobs
45+
- `coalesce`: Whether to run missed jobs when the scheduler resumes
46+
47+
* * * * *
48+
49+
Setting Up the Scheduler
50+
-----------------------
51+
52+
1. Add the scheduler provider to your application:
53+
54+
```python
55+
from py_spring_core import PySpringApplication
56+
from py_spring_scheduler import provide_scheduler
57+
58+
def main():
59+
app = PySpringApplication("./app-config.json", entity_providers=[provide_scheduler()])
60+
app.run()
61+
62+
if __name__ == "__main__":
63+
main()
64+
```
65+
66+
* * * * *
67+
68+
Creating Scheduled Tasks
69+
----------------------
70+
71+
### Using the @Scheduled Decorator
72+
73+
The `@Scheduled` decorator is the primary way to create scheduled tasks. It supports multiple trigger types:
74+
75+
#### Interval Trigger
76+
77+
```python
78+
from py_spring_scheduler import Scheduled, IntervalTrigger
79+
80+
@Scheduled(trigger=IntervalTrigger(seconds=5))
81+
def my_interval_task():
82+
# Runs every 5 seconds
83+
pass
84+
```
85+
86+
#### Cron Trigger
87+
88+
```python
89+
from py_spring_scheduler import Scheduled, CronTrigger
90+
91+
@Scheduled(trigger=CronTrigger(cron="0 0 * * *"))
92+
def my_cron_task():
93+
# Runs daily at midnight
94+
pass
95+
```
96+
97+
#### Combining Triggers
98+
99+
You can combine multiple triggers using `AndTrigger` and `OrTrigger`:
100+
101+
```python
102+
from py_spring_scheduler import Scheduled, IntervalTrigger, CronTrigger, AndTrigger, OrTrigger
103+
104+
# Using OrTrigger (runs if either trigger condition is met)
105+
@Scheduled(trigger=OrTrigger([
106+
IntervalTrigger(seconds=3),
107+
CronTrigger(minute=0)
108+
]))
109+
def my_or_task():
110+
# Runs every 3 seconds OR at the start of every hour
111+
pass
112+
113+
# Using AndTrigger (runs only if all trigger conditions are met)
114+
@Scheduled(trigger=AndTrigger([
115+
CronTrigger(hour=9), # Only during 9 AM
116+
CronTrigger(minute=0) # Only at minute 0
117+
]))
118+
def my_and_task():
119+
# Runs only at 9:00 AM
120+
pass
121+
```
122+
123+
* * * * *
124+
125+
Component-based Scheduling
126+
------------------------
127+
128+
Scheduled tasks can be defined within PySpring components, allowing you to leverage dependency injection:
129+
130+
```python
131+
from py_spring_core import Component
132+
from py_spring_scheduler import Scheduled, IntervalTrigger
133+
134+
class MyComponent(Component):
135+
@Scheduled(trigger=IntervalTrigger(seconds=3))
136+
def scheduled_method(self):
137+
# Runs every 3 seconds
138+
pass
139+
```
140+
141+
### Using Dependencies in Scheduled Tasks
142+
143+
Components can be injected and used within scheduled tasks:
144+
145+
```python
146+
from py_spring_core import Component
147+
from py_spring_scheduler import Scheduled, IntervalTrigger
148+
149+
class Service(Component):
150+
def do_something(self):
151+
print("Service method called")
152+
153+
class TaskComponent(Component):
154+
service: Service # Dependency injection
155+
156+
@Scheduled(trigger=IntervalTrigger(seconds=5))
157+
def scheduled_task(self):
158+
self.service.do_something()
159+
```
160+
161+
* * * * *
162+
163+
Best Practices
164+
-------------
165+
166+
1. **Resource Management**
167+
- Set appropriate `max_instances` to prevent resource exhaustion
168+
- Use `coalesce` carefully to avoid overwhelming the system after downtime
169+
170+
2. **Error Handling**
171+
- Implement proper error handling in scheduled tasks
172+
- Consider using PySpring's logging system for task monitoring
173+
174+
3. **Timezone Awareness**
175+
- Always specify timezones explicitly for cron jobs
176+
- Be mindful of daylight saving time transitions
177+
178+
4. **Component Design**
179+
- Keep scheduled tasks focused and single-purpose
180+
- Use dependency injection for better testability
181+
182+
* * * * *
183+
184+
Common Use Cases
185+
---------------
186+
187+
1. **Periodic Data Processing**
188+
```python
189+
@Scheduled(trigger=IntervalTrigger(minutes=30))
190+
def process_data():
191+
# Process data every 30 minutes
192+
pass
193+
```
194+
195+
2. **Daily Maintenance Tasks**
196+
```python
197+
@Scheduled(trigger=CronTrigger(cron="0 2 * * *")) # 2 AM daily
198+
def maintenance_task():
199+
# Perform daily maintenance
200+
pass
201+
```
202+
203+
3. **Health Checks**
204+
```python
205+
@Scheduled(trigger=IntervalTrigger(minutes=5))
206+
def health_check():
207+
# Check system health every 5 minutes
208+
pass
209+
```
210+
211+
* * * * *
212+
213+
Troubleshooting
214+
--------------
215+
216+
### Common Issues
217+
218+
1. **Tasks Not Running**
219+
- Check if the scheduler is properly initialized
220+
- Verify timezone settings
221+
- Ensure the task is properly decorated
222+
223+
2. **Resource Exhaustion**
224+
- Monitor thread pool usage
225+
- Adjust `number_of_workers` based on workload
226+
- Review `max_instances` settings
227+
228+
3. **Timezone Issues**
229+
- Verify timezone configuration
230+
- Check for daylight saving time transitions
231+
- Use explicit timezone settings in triggers
232+
233+
* * * * *
234+
235+
Summary
236+
-------
237+
238+
The PySpring Scheduler provides:
239+
240+
- Seamless integration with PySpring framework
241+
- Flexible scheduling options (Interval, Cron)
242+
- Component-based task management
243+
- Dependency injection support
244+
- Configurable thread pool
245+
- Timezone-aware scheduling
246+
- Job coalescing and instance limits
247+
248+
By following the patterns and best practices outlined in this guide, you can effectively implement scheduled tasks in your PySpring applications.

mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ nav:
3939
- Dependency Injection:
4040
- What is Dependency Injection: guide/dependency-injection/what-is-denpendency-injection.md
4141
- Auto Dependency Injection: guide/dependency-injection/auto-deppendency-injection.md
42+
- Scheduling:
43+
- Scheduler: guide/scheduling/scheduler.md
4244

4345
markdown_extensions:
4446
- pymdownx.highlight:

0 commit comments

Comments
 (0)