From 6952110812a970637d50c5b8b738732c9abbfd8a Mon Sep 17 00:00:00 2001 From: William Chen Date: Tue, 17 Jun 2025 02:05:56 +0800 Subject: [PATCH 1/3] feat(docs): Add scheduling guide and integrate into navigation - Introduced a new guide on the PySpring Scheduler, detailing installation, configuration, and usage of scheduled tasks with decorators. - Updated `mkdocs.yml` to include the new Scheduling section in the documentation navigation. --- docs/guide/scheduling/scheduler.md | 248 +++++++++++++++++++++++++++++ mkdocs.yml | 2 + 2 files changed, 250 insertions(+) create mode 100644 docs/guide/scheduling/scheduler.md diff --git a/docs/guide/scheduling/scheduler.md b/docs/guide/scheduling/scheduler.md new file mode 100644 index 0000000..19da254 --- /dev/null +++ b/docs/guide/scheduling/scheduler.md @@ -0,0 +1,248 @@ +PySpring Scheduler +================= + +The PySpring Scheduler provides a robust and flexible way to manage scheduled tasks in your applications, seamlessly integrating with the PySpring framework. + +Installation +----------- + +Install the package using pip: + +```bash +pip install py-spring-scheduler +``` + +* * * * * + +Overview +-------- + +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. + +* * * * * + +Configuration +------------ + +The scheduler can be configured through your application's properties file: + +```json +{ + "scheduler": { + "number_of_workers": 20, + "max_instances": 3, + "timezone": "UTC", + "coalesce": false + } +} +``` + +### Configuration Options + +- `number_of_workers`: Number of threads in the scheduler's thread pool +- `max_instances`: Maximum number of concurrent instances of a job +- `timezone`: Default timezone for all jobs +- `coalesce`: Whether to run missed jobs when the scheduler resumes + +* * * * * + +Setting Up the Scheduler +----------------------- + +1. Add the scheduler provider to your application: + +```python +from py_spring_core import PySpringApplication +from py_spring_scheduler import provide_scheduler + +def main(): + app = PySpringApplication("./app-config.json", entity_providers=[provide_scheduler()]) + app.run() + +if __name__ == "__main__": + main() +``` + +* * * * * + +Creating Scheduled Tasks +---------------------- + +### Using the @Scheduled Decorator + +The `@Scheduled` decorator is the primary way to create scheduled tasks. It supports multiple trigger types: + +#### Interval Trigger + +```python +from pyspring_scheduler import Scheduled, IntervalTrigger + +@Scheduled(trigger=IntervalTrigger(seconds=5)) +def my_interval_task(): + # Runs every 5 seconds + pass +``` + +#### Cron Trigger + +```python +from pyspring_scheduler import Scheduled, CronTrigger + +@Scheduled(trigger=CronTrigger(cron="0 0 * * *")) +def my_cron_task(): + # Runs daily at midnight + pass +``` + +#### Combining Triggers + +You can combine multiple triggers using `AndTrigger` and `OrTrigger`: + +```python +from pyspring_scheduler import Scheduled, IntervalTrigger, CronTrigger, AndTrigger, OrTrigger + +# Using OrTrigger (runs if either trigger condition is met) +@Scheduled(trigger=OrTrigger([ + IntervalTrigger(seconds=3), + CronTrigger(minute=0) +])) +def my_or_task(): + # Runs every 3 seconds OR at the start of every hour + pass + +# Using AndTrigger (runs only if all trigger conditions are met) +@Scheduled(trigger=AndTrigger([ + CronTrigger(hour=9), # Only during 9 AM + CronTrigger(minute=0) # Only at minute 0 +])) +def my_and_task(): + # Runs only at 9:00 AM + pass +``` + +* * * * * + +Component-based Scheduling +------------------------ + +Scheduled tasks can be defined within PySpring components, allowing you to leverage dependency injection: + +```python +from py_spring_core import Component +from pyspring_scheduler import Scheduled, IntervalTrigger + +class MyComponent(Component): + @Scheduled(trigger=IntervalTrigger(seconds=3)) + def scheduled_method(self): + # Runs every 3 seconds + pass +``` + +### Using Dependencies in Scheduled Tasks + +Components can be injected and used within scheduled tasks: + +```python +from py_spring_core import Component +from pyspring_scheduler import Scheduled, IntervalTrigger + +class Service(Component): + def do_something(self): + print("Service method called") + +class TaskComponent(Component): + service: Service # Dependency injection + + @Scheduled(trigger=IntervalTrigger(seconds=5)) + def scheduled_task(self): + self.service.do_something() +``` + +* * * * * + +Best Practices +------------- + +1. **Resource Management** + - Set appropriate `max_instances` to prevent resource exhaustion + - Use `coalesce` carefully to avoid overwhelming the system after downtime + +2. **Error Handling** + - Implement proper error handling in scheduled tasks + - Consider using PySpring's logging system for task monitoring + +3. **Timezone Awareness** + - Always specify timezones explicitly for cron jobs + - Be mindful of daylight saving time transitions + +4. **Component Design** + - Keep scheduled tasks focused and single-purpose + - Use dependency injection for better testability + +* * * * * + +Common Use Cases +--------------- + +1. **Periodic Data Processing** + ```python + @Scheduled(trigger=IntervalTrigger(minutes=30)) + def process_data(): + # Process data every 30 minutes + pass + ``` + +2. **Daily Maintenance Tasks** + ```python + @Scheduled(trigger=CronTrigger(cron="0 2 * * *")) # 2 AM daily + def maintenance_task(): + # Perform daily maintenance + pass + ``` + +3. **Health Checks** + ```python + @Scheduled(trigger=IntervalTrigger(minutes=5)) + def health_check(): + # Check system health every 5 minutes + pass + ``` + +* * * * * + +Troubleshooting +-------------- + +### Common Issues + +1. **Tasks Not Running** + - Check if the scheduler is properly initialized + - Verify timezone settings + - Ensure the task is properly decorated + +2. **Resource Exhaustion** + - Monitor thread pool usage + - Adjust `number_of_workers` based on workload + - Review `max_instances` settings + +3. **Timezone Issues** + - Verify timezone configuration + - Check for daylight saving time transitions + - Use explicit timezone settings in triggers + +* * * * * + +Summary +------- + +The PySpring Scheduler provides: + +- Seamless integration with PySpring framework +- Flexible scheduling options (Interval, Cron) +- Component-based task management +- Dependency injection support +- Configurable thread pool +- Timezone-aware scheduling +- Job coalescing and instance limits + +By following the patterns and best practices outlined in this guide, you can effectively implement scheduled tasks in your PySpring applications. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index eb7c2e4..bd43aa4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -39,6 +39,8 @@ nav: - Dependency Injection: - What is Dependency Injection: guide/dependency-injection/what-is-denpendency-injection.md - Auto Dependency Injection: guide/dependency-injection/auto-deppendency-injection.md + - Scheduling: + - Scheduler: guide/scheduling/scheduler.md markdown_extensions: - pymdownx.highlight: From 5d37a5600246bbbef61b29bc229fde054759cef0 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 18 Jun 2025 01:30:13 +0800 Subject: [PATCH 2/3] fix(docs): Correct import paths in scheduling guide - Updated import statements in the scheduling guide to reflect the correct module name `py_spring_scheduler` instead of `pyspring_scheduler` for consistency and accuracy. --- docs/guide/scheduling/scheduler.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/guide/scheduling/scheduler.md b/docs/guide/scheduling/scheduler.md index 19da254..e68e18b 100644 --- a/docs/guide/scheduling/scheduler.md +++ b/docs/guide/scheduling/scheduler.md @@ -75,7 +75,7 @@ The `@Scheduled` decorator is the primary way to create scheduled tasks. It supp #### Interval Trigger ```python -from pyspring_scheduler import Scheduled, IntervalTrigger +from py_spring_scheduler import Scheduled, IntervalTrigger @Scheduled(trigger=IntervalTrigger(seconds=5)) def my_interval_task(): @@ -86,7 +86,7 @@ def my_interval_task(): #### Cron Trigger ```python -from pyspring_scheduler import Scheduled, CronTrigger +from py_spring_scheduler import Scheduled, CronTrigger @Scheduled(trigger=CronTrigger(cron="0 0 * * *")) def my_cron_task(): @@ -99,7 +99,7 @@ def my_cron_task(): You can combine multiple triggers using `AndTrigger` and `OrTrigger`: ```python -from pyspring_scheduler import Scheduled, IntervalTrigger, CronTrigger, AndTrigger, OrTrigger +from py_spring_scheduler import Scheduled, IntervalTrigger, CronTrigger, AndTrigger, OrTrigger # Using OrTrigger (runs if either trigger condition is met) @Scheduled(trigger=OrTrigger([ @@ -129,7 +129,7 @@ Scheduled tasks can be defined within PySpring components, allowing you to lever ```python from py_spring_core import Component -from pyspring_scheduler import Scheduled, IntervalTrigger +from py_spring_scheduler import Scheduled, IntervalTrigger class MyComponent(Component): @Scheduled(trigger=IntervalTrigger(seconds=3)) @@ -144,7 +144,7 @@ Components can be injected and used within scheduled tasks: ```python from py_spring_core import Component -from pyspring_scheduler import Scheduled, IntervalTrigger +from py_spring_scheduler import Scheduled, IntervalTrigger class Service(Component): def do_something(self): From 059fa19475fbcf35a8dda1d2b0bd5a3d6a82e0e3 Mon Sep 17 00:00:00 2001 From: William Chen Date: Wed, 18 Jun 2025 01:31:39 +0800 Subject: [PATCH 3/3] docs: Update installation instructions for PySpring Scheduler - Changed the installation command to reflect that the package can only be installed directly from the git repository due to active development. --- docs/guide/scheduling/scheduler.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guide/scheduling/scheduler.md b/docs/guide/scheduling/scheduler.md index e68e18b..b7cffca 100644 --- a/docs/guide/scheduling/scheduler.md +++ b/docs/guide/scheduling/scheduler.md @@ -6,10 +6,10 @@ The PySpring Scheduler provides a robust and flexible way to manage scheduled ta Installation ----------- -Install the package using pip: +Since the package is under active development, it can only be installed directly from the git repository: ```bash -pip install py-spring-scheduler +pip install git+ssh://git@github.com/PythonSpring/pyspring-scheduler.git ``` * * * * *