orionis 0.473.0__py3-none-any.whl → 0.475.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orionis/console/tasks/schedule.py +120 -306
- orionis/metadata/framework.py +1 -1
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/METADATA +1 -1
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/RECORD +8 -8
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/WHEEL +0 -0
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/top_level.txt +0 -0
- {orionis-0.473.0.dist-info → orionis-0.475.0.dist-info}/zip-safe +0 -0
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import List, Optional
|
|
5
|
+
import pytz
|
|
4
6
|
from apscheduler.schedulers.asyncio import AsyncIOScheduler as APSAsyncIOScheduler
|
|
5
7
|
from apscheduler.triggers.cron import CronTrigger
|
|
6
8
|
from apscheduler.triggers.date import DateTrigger
|
|
7
9
|
from apscheduler.triggers.interval import IntervalTrigger
|
|
10
|
+
from orionis.app import Orionis
|
|
8
11
|
from orionis.console.contracts.reactor import IReactor
|
|
9
|
-
from datetime import datetime
|
|
10
|
-
import pytz
|
|
11
|
-
import asyncio
|
|
12
|
-
from typing import Union
|
|
13
12
|
from orionis.console.exceptions import CLIOrionisRuntimeError
|
|
14
|
-
from orionis.
|
|
13
|
+
from orionis.services.log.contracts.log_service import ILogger
|
|
15
14
|
|
|
16
15
|
class Scheduler():
|
|
17
16
|
|
|
@@ -23,7 +22,7 @@ class Scheduler():
|
|
|
23
22
|
Initialize a new instance of the Scheduler class.
|
|
24
23
|
|
|
25
24
|
This constructor sets up the internal state required for scheduling commands,
|
|
26
|
-
including references to the application instance,
|
|
25
|
+
including references to the application instance, AsyncIOScheduler, the
|
|
27
26
|
command reactor, and job tracking structures. It also initializes properties
|
|
28
27
|
for managing the current scheduling context.
|
|
29
28
|
|
|
@@ -42,11 +41,18 @@ class Scheduler():
|
|
|
42
41
|
# Store the application instance for configuration access.
|
|
43
42
|
self.__app = Orionis()
|
|
44
43
|
|
|
45
|
-
# Initialize
|
|
46
|
-
self.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
# Initialize AsyncIOScheduler instance with timezone configuration.
|
|
45
|
+
self.__scheduler: APSAsyncIOScheduler = APSAsyncIOScheduler(
|
|
46
|
+
timezone=pytz.timezone(self.__app.config('app.timezone', 'UTC'))
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Clear the APScheduler logger to prevent conflicts with other loggers.
|
|
50
|
+
# This is necessary to avoid duplicate log messages or conflicts with other logging configurations.
|
|
51
|
+
logging.getLogger("apscheduler").handlers.clear()
|
|
52
|
+
logging.getLogger("apscheduler").propagate = False
|
|
53
|
+
|
|
54
|
+
# Initialize the logger from the application instance.
|
|
55
|
+
self.__logger: ILogger = self.__app.make('x-orionis.services.log.log_service')
|
|
50
56
|
|
|
51
57
|
# Store the reactor instance for command management.
|
|
52
58
|
self.__reactor = reactor
|
|
@@ -61,41 +67,9 @@ class Scheduler():
|
|
|
61
67
|
self.__command: str = None # The command signature to be scheduled.
|
|
62
68
|
self.__args: List[str] = None # Arguments for the command.
|
|
63
69
|
self.__purpose: str = None # Purpose or description of the scheduled job.
|
|
64
|
-
self.__type: str = None # Scheduler type (background, blocking, asyncio).
|
|
65
|
-
|
|
66
|
-
def __initScheduler(
|
|
67
|
-
self
|
|
68
|
-
) -> None:
|
|
69
|
-
"""
|
|
70
|
-
Initialize the internal APScheduler instances for background, blocking, and asyncio scheduling.
|
|
71
|
-
|
|
72
|
-
This method creates and configures three types of schedulers:
|
|
73
|
-
- BackgroundScheduler: Runs jobs in the background using threads.
|
|
74
|
-
- BlockingScheduler: Runs jobs in the foreground and blocks the main thread.
|
|
75
|
-
- AsyncIOScheduler: Integrates with asyncio event loops for asynchronous job execution.
|
|
76
|
-
|
|
77
|
-
The timezone for all schedulers is set based on the application's configuration.
|
|
78
|
-
|
|
79
|
-
Returns
|
|
80
|
-
-------
|
|
81
|
-
None
|
|
82
|
-
This method does not return any value. It initializes internal scheduler attributes.
|
|
83
|
-
"""
|
|
84
|
-
|
|
85
|
-
# Initialize the BackgroundScheduler with the application's timezone
|
|
86
|
-
self.__background_scheduler = APSBackgroundScheduler(
|
|
87
|
-
timezone=pytz.timezone(self.__app.config('app.timezone', 'UTC'))
|
|
88
|
-
)
|
|
89
70
|
|
|
90
|
-
#
|
|
91
|
-
self.
|
|
92
|
-
timezone=pytz.timezone(self.__app.config('app.timezone', 'UTC'))
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
# Initialize the AsyncIOScheduler with the application's timezone
|
|
96
|
-
self.__asyncio_scheduler = APSAsyncIOScheduler(
|
|
97
|
-
timezone=pytz.timezone(self.__app.config('app.timezone', 'UTC'))
|
|
98
|
-
)
|
|
71
|
+
# Log the initialization of the Scheduler.
|
|
72
|
+
self.__logger.info("Scheduler initialized.")
|
|
99
73
|
|
|
100
74
|
def __getCommands(
|
|
101
75
|
self
|
|
@@ -130,70 +104,6 @@ class Scheduler():
|
|
|
130
104
|
# Return the commands dictionary
|
|
131
105
|
return commands
|
|
132
106
|
|
|
133
|
-
def background(
|
|
134
|
-
self
|
|
135
|
-
) -> 'Scheduler':
|
|
136
|
-
"""
|
|
137
|
-
Set the scheduler type to 'background' for job scheduling.
|
|
138
|
-
|
|
139
|
-
This method configures the scheduler to use the BackgroundScheduler, which runs jobs in the background using threads.
|
|
140
|
-
It updates the internal type property to indicate that subsequent scheduled jobs should be handled by the background scheduler.
|
|
141
|
-
|
|
142
|
-
Returns
|
|
143
|
-
-------
|
|
144
|
-
Scheduler
|
|
145
|
-
Returns the current instance of the Scheduler to allow method chaining.
|
|
146
|
-
"""
|
|
147
|
-
|
|
148
|
-
# Set the scheduler type to 'background'
|
|
149
|
-
self.__type = 'background'
|
|
150
|
-
|
|
151
|
-
# Return self to support method chaining
|
|
152
|
-
return self
|
|
153
|
-
|
|
154
|
-
def blocking(
|
|
155
|
-
self
|
|
156
|
-
) -> 'Scheduler':
|
|
157
|
-
"""
|
|
158
|
-
Set the scheduler type to 'blocking' for job scheduling.
|
|
159
|
-
|
|
160
|
-
This method configures the scheduler to use the BlockingScheduler, which runs jobs in the foreground and blocks the main thread.
|
|
161
|
-
It updates the internal type property so that subsequent scheduled jobs will be handled by the blocking scheduler.
|
|
162
|
-
|
|
163
|
-
Returns
|
|
164
|
-
-------
|
|
165
|
-
Scheduler
|
|
166
|
-
Returns the current instance of the Scheduler to allow method chaining.
|
|
167
|
-
"""
|
|
168
|
-
|
|
169
|
-
# Set the scheduler type to 'blocking'
|
|
170
|
-
self.__type = 'blocking'
|
|
171
|
-
|
|
172
|
-
# Return self to support method chaining
|
|
173
|
-
return self
|
|
174
|
-
|
|
175
|
-
def asyncio(
|
|
176
|
-
self
|
|
177
|
-
) -> 'Scheduler':
|
|
178
|
-
"""
|
|
179
|
-
Set the scheduler type to 'asyncio' for job scheduling.
|
|
180
|
-
|
|
181
|
-
This method configures the scheduler to use the AsyncIOScheduler, which integrates with
|
|
182
|
-
asyncio event loops for asynchronous job execution. It updates the internal type property
|
|
183
|
-
so that subsequent scheduled jobs will be handled by the asyncio scheduler.
|
|
184
|
-
|
|
185
|
-
Returns
|
|
186
|
-
-------
|
|
187
|
-
Scheduler
|
|
188
|
-
Returns the current instance of the Scheduler to allow method chaining.
|
|
189
|
-
"""
|
|
190
|
-
|
|
191
|
-
# Set the scheduler type to 'asyncio'
|
|
192
|
-
self.__type = 'asyncio'
|
|
193
|
-
|
|
194
|
-
# Return self to support method chaining
|
|
195
|
-
return self
|
|
196
|
-
|
|
197
107
|
def __isAvailable(
|
|
198
108
|
self,
|
|
199
109
|
signature: str
|
|
@@ -254,47 +164,16 @@ class Scheduler():
|
|
|
254
164
|
# Return the description if the command exists, otherwise return None
|
|
255
165
|
return command_entry['description'] if command_entry else None
|
|
256
166
|
|
|
257
|
-
def __getScheduler(
|
|
258
|
-
self
|
|
259
|
-
) -> Optional[Union[APSBackgroundScheduler, APSBlockingScheduler, APSAsyncIOScheduler]]:
|
|
260
|
-
"""
|
|
261
|
-
Retrieve the appropriate APScheduler instance based on the current scheduler type.
|
|
262
|
-
|
|
263
|
-
This method selects and returns the internal scheduler instance corresponding to the
|
|
264
|
-
type specified by the user (background, blocking, or asyncio). The scheduler type is
|
|
265
|
-
determined by the value of the internal `__type` attribute, which is set using the
|
|
266
|
-
`background()`, `blocking()`, or `asyncio()` methods.
|
|
267
|
-
|
|
268
|
-
Returns
|
|
269
|
-
-------
|
|
270
|
-
Optional[Union[APSBackgroundScheduler, APSBlockingScheduler, APSAsyncIOScheduler]]
|
|
271
|
-
The scheduler instance matching the current type, or None if the type is not set
|
|
272
|
-
or does not match any known scheduler.
|
|
273
|
-
"""
|
|
274
|
-
|
|
275
|
-
# Return the BackgroundScheduler if the type is set to 'background'
|
|
276
|
-
if self.__type == 'background':
|
|
277
|
-
return self.__background_scheduler
|
|
278
|
-
|
|
279
|
-
# Return the BlockingScheduler if the type is set to 'blocking'
|
|
280
|
-
elif self.__type == 'blocking':
|
|
281
|
-
return self.__blocking_scheduler
|
|
282
|
-
|
|
283
|
-
# Return the AsyncIOScheduler if the type is set to 'asyncio'
|
|
284
|
-
elif self.__type == 'asyncio':
|
|
285
|
-
return self.__asyncio_scheduler
|
|
286
|
-
|
|
287
167
|
def __reset(
|
|
288
168
|
self
|
|
289
169
|
) -> None:
|
|
290
170
|
"""
|
|
291
171
|
Reset the internal state of the Scheduler instance.
|
|
292
172
|
|
|
293
|
-
This method clears the current command, arguments, purpose
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
settings.
|
|
173
|
+
This method clears the current command, arguments, and purpose attributes,
|
|
174
|
+
effectively resetting the scheduler's configuration to its initial state.
|
|
175
|
+
This can be useful for preparing the scheduler for a new command or job
|
|
176
|
+
scheduling without retaining any previous settings.
|
|
298
177
|
|
|
299
178
|
Returns
|
|
300
179
|
-------
|
|
@@ -305,7 +184,6 @@ class Scheduler():
|
|
|
305
184
|
self.__command = None
|
|
306
185
|
self.__args = None
|
|
307
186
|
self.__purpose = None
|
|
308
|
-
self.__type = None
|
|
309
187
|
|
|
310
188
|
def command(
|
|
311
189
|
self,
|
|
@@ -410,8 +288,8 @@ class Scheduler():
|
|
|
410
288
|
Schedule a command to run once at a specific date and time.
|
|
411
289
|
|
|
412
290
|
This method schedules the currently registered command to execute exactly once at the
|
|
413
|
-
specified datetime
|
|
414
|
-
|
|
291
|
+
specified datetime using the AsyncIOScheduler. The job is registered internally and
|
|
292
|
+
added to the scheduler instance.
|
|
415
293
|
|
|
416
294
|
Parameters
|
|
417
295
|
----------
|
|
@@ -426,8 +304,7 @@ class Scheduler():
|
|
|
426
304
|
Raises
|
|
427
305
|
------
|
|
428
306
|
CLIOrionisRuntimeError
|
|
429
|
-
If the provided date is not a `datetime` instance
|
|
430
|
-
or if there is an error while scheduling the job.
|
|
307
|
+
If the provided date is not a `datetime` instance or if there is an error while scheduling the job.
|
|
431
308
|
"""
|
|
432
309
|
|
|
433
310
|
try:
|
|
@@ -438,30 +315,18 @@ class Scheduler():
|
|
|
438
315
|
"The date must be an instance of datetime."
|
|
439
316
|
)
|
|
440
317
|
|
|
441
|
-
# If no scheduler type is set, default to background scheduler.
|
|
442
|
-
if self.__type is None:
|
|
443
|
-
self.background()
|
|
444
|
-
|
|
445
318
|
# Register the job details internally.
|
|
446
319
|
self.__jobs[self.__command] = {
|
|
447
320
|
'signature': self.__command,
|
|
448
321
|
'args': self.__args,
|
|
449
322
|
'purpose': self.__purpose,
|
|
450
|
-
'type': self.__type,
|
|
451
323
|
'trigger': 'once_at',
|
|
452
324
|
'start_at': date.strftime('%Y-%m-%d %H:%M:%S'),
|
|
453
325
|
'end_at': date.strftime('%Y-%m-%d %H:%M:%S')
|
|
454
326
|
}
|
|
455
327
|
|
|
456
|
-
# Retrieve the appropriate scheduler instance.
|
|
457
|
-
scheduler = self.__getScheduler()
|
|
458
|
-
|
|
459
|
-
# Raise an error if the scheduler is not defined.
|
|
460
|
-
if scheduler is None:
|
|
461
|
-
raise CLIOrionisRuntimeError("No scheduler type has been defined.")
|
|
462
|
-
|
|
463
328
|
# Add the job to the scheduler.
|
|
464
|
-
|
|
329
|
+
self.__scheduler.add_job(
|
|
465
330
|
func= lambda command=self.__command, args=list(self.__args): self.__reactor.call(
|
|
466
331
|
command,
|
|
467
332
|
args
|
|
@@ -474,6 +339,11 @@ class Scheduler():
|
|
|
474
339
|
replace_existing=True
|
|
475
340
|
)
|
|
476
341
|
|
|
342
|
+
# Log the scheduling of the command.
|
|
343
|
+
self.__logger.info(
|
|
344
|
+
f"Scheduled command '{self.__command}' to run once at {date.strftime('%Y-%m-%d %H:%M:%S')}"
|
|
345
|
+
)
|
|
346
|
+
|
|
477
347
|
# Reset the internal state for future scheduling.
|
|
478
348
|
self.__reset()
|
|
479
349
|
|
|
@@ -489,124 +359,142 @@ class Scheduler():
|
|
|
489
359
|
# Wrap and raise any other exceptions as CLIOrionisRuntimeError.
|
|
490
360
|
raise CLIOrionisRuntimeError(f"Error scheduling the job: {str(e)}")
|
|
491
361
|
|
|
492
|
-
def start(self) -> None:
|
|
362
|
+
async def start(self) -> None:
|
|
493
363
|
"""
|
|
494
|
-
Start
|
|
495
|
-
|
|
496
|
-
This method initiates the three scheduler types managed by this Scheduler instance:
|
|
497
|
-
- AsyncIOScheduler: Integrates with asyncio event loops for asynchronous job execution.
|
|
498
|
-
- BackgroundScheduler: Runs jobs in the background using threads.
|
|
499
|
-
- BlockingScheduler: Runs jobs in the foreground and blocks the main thread.
|
|
364
|
+
Start the AsyncIO scheduler instance and keep it running.
|
|
500
365
|
|
|
501
|
-
|
|
366
|
+
This method initiates the AsyncIOScheduler which integrates with asyncio event loops
|
|
367
|
+
for asynchronous job execution. It ensures the scheduler starts properly within
|
|
368
|
+
an asyncio context and maintains the event loop active to process scheduled jobs.
|
|
502
369
|
|
|
503
370
|
Returns
|
|
504
371
|
-------
|
|
505
372
|
None
|
|
506
|
-
This method does not return any value. It starts
|
|
373
|
+
This method does not return any value. It starts the AsyncIO scheduler and keeps it running.
|
|
507
374
|
"""
|
|
508
375
|
|
|
509
376
|
# Start the AsyncIOScheduler to handle asynchronous jobs.
|
|
510
|
-
# Only start if there's an event loop running or we can create one
|
|
511
377
|
try:
|
|
378
|
+
|
|
379
|
+
# Ensure we're in an asyncio context
|
|
512
380
|
asyncio.get_running_loop()
|
|
513
|
-
self.__asyncio_scheduler.start()
|
|
514
|
-
except RuntimeError:
|
|
515
|
-
# No event loop is running, AsyncIOScheduler won't be started
|
|
516
|
-
# This is normal for non-asyncio environments
|
|
517
|
-
pass
|
|
518
381
|
|
|
519
|
-
|
|
520
|
-
|
|
382
|
+
# Start the scheduler
|
|
383
|
+
if not self.__scheduler.running:
|
|
384
|
+
self.__logger.info(f"Orionis Scheduler started. {len(self.__jobs)} jobs scheduled.")
|
|
385
|
+
self.__scheduler.start()
|
|
386
|
+
|
|
387
|
+
# Keep the event loop alive to process scheduled jobs
|
|
388
|
+
try:
|
|
389
|
+
|
|
390
|
+
# Wait for the scheduler to start and keep it running
|
|
391
|
+
while True:
|
|
392
|
+
await asyncio.sleep(1)
|
|
393
|
+
|
|
394
|
+
except KeyboardInterrupt:
|
|
521
395
|
|
|
522
|
-
|
|
523
|
-
|
|
396
|
+
# Handle graceful shutdown on keyboard interrupt
|
|
397
|
+
await self.shutdown()
|
|
524
398
|
|
|
525
|
-
|
|
399
|
+
except Exception as e:
|
|
400
|
+
|
|
401
|
+
# Handle exceptions that may occur during scheduler startup
|
|
402
|
+
raise CLIOrionisRuntimeError(f"Failed to start the scheduler: {str(e)}")
|
|
403
|
+
|
|
404
|
+
async def shutdown(self, wait=True) -> None:
|
|
526
405
|
"""
|
|
527
|
-
Shut down
|
|
406
|
+
Shut down the AsyncIO scheduler instance asynchronously.
|
|
528
407
|
|
|
529
|
-
This method gracefully stops the
|
|
530
|
-
|
|
531
|
-
- BackgroundScheduler: Runs jobs in the background using threads.
|
|
532
|
-
- BlockingScheduler: Runs jobs in the foreground and blocks the main thread.
|
|
408
|
+
This method gracefully stops the AsyncIOScheduler that handles asynchronous job execution.
|
|
409
|
+
Using async ensures proper cleanup in asyncio environments.
|
|
533
410
|
|
|
534
411
|
Parameters
|
|
535
412
|
----------
|
|
536
413
|
wait : bool, optional
|
|
537
|
-
If True, the method will wait until all currently executing jobs are completed before shutting down the
|
|
538
|
-
If False, the
|
|
414
|
+
If True, the method will wait until all currently executing jobs are completed before shutting down the scheduler.
|
|
415
|
+
If False, the scheduler will be shut down immediately without waiting for running jobs to finish. Default is True.
|
|
539
416
|
|
|
540
417
|
Returns
|
|
541
418
|
-------
|
|
542
419
|
None
|
|
543
|
-
This method does not return any value. It shuts down
|
|
420
|
+
This method does not return any value. It shuts down the AsyncIO scheduler.
|
|
544
421
|
"""
|
|
545
422
|
|
|
546
423
|
# Validate that the wait parameter is a boolean.
|
|
547
424
|
if not isinstance(wait, bool):
|
|
548
425
|
raise ValueError("The 'wait' parameter must be a boolean value.")
|
|
549
426
|
|
|
550
|
-
# Shut down the AsyncIOScheduler, waiting for jobs if specified.
|
|
551
427
|
try:
|
|
552
|
-
|
|
553
|
-
|
|
428
|
+
|
|
429
|
+
# Shut down the AsyncIOScheduler, waiting for jobs if specified.
|
|
430
|
+
if self.__scheduler.running:
|
|
431
|
+
|
|
432
|
+
# For AsyncIOScheduler, shutdown can be called normally
|
|
433
|
+
# but we await any pending operations
|
|
434
|
+
self.__scheduler.shutdown(wait=wait)
|
|
435
|
+
|
|
436
|
+
# Give a small delay to ensure proper cleanup
|
|
437
|
+
if wait:
|
|
438
|
+
await asyncio.sleep(0.1)
|
|
439
|
+
|
|
440
|
+
# Log the shutdown of the scheduler
|
|
441
|
+
self.__logger.info("Orionis Scheduler has been shut down.")
|
|
442
|
+
|
|
554
443
|
except Exception:
|
|
444
|
+
|
|
555
445
|
# AsyncIOScheduler may not be running or may have issues in shutdown
|
|
556
446
|
pass
|
|
557
447
|
|
|
558
|
-
|
|
559
|
-
if self.__background_scheduler.running:
|
|
560
|
-
self.__background_scheduler.shutdown(wait=wait)
|
|
561
|
-
|
|
562
|
-
# Shut down the BlockingScheduler, waiting for jobs if specified.
|
|
563
|
-
if self.__blocking_scheduler.running:
|
|
564
|
-
self.__blocking_scheduler.shutdown(wait=wait)
|
|
565
|
-
|
|
566
|
-
def remove(self, signature:str) -> None:
|
|
448
|
+
async def remove(self, signature: str) -> bool:
|
|
567
449
|
"""
|
|
568
|
-
Remove a scheduled job from
|
|
450
|
+
Remove a scheduled job from the AsyncIO scheduler asynchronously.
|
|
569
451
|
|
|
570
|
-
This method
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
the removal request without raising an error.
|
|
452
|
+
This method removes a job with the specified signature from both the internal
|
|
453
|
+
jobs dictionary and the AsyncIOScheduler instance. Using async ensures proper
|
|
454
|
+
cleanup in asyncio environments.
|
|
574
455
|
|
|
575
456
|
Parameters
|
|
576
457
|
----------
|
|
577
458
|
signature : str
|
|
578
|
-
The
|
|
459
|
+
The signature of the command/job to remove from the scheduler.
|
|
579
460
|
|
|
580
461
|
Returns
|
|
581
462
|
-------
|
|
582
|
-
|
|
583
|
-
|
|
463
|
+
bool
|
|
464
|
+
Returns True if the job was successfully removed, False if the job was not found.
|
|
465
|
+
|
|
466
|
+
Raises
|
|
467
|
+
------
|
|
468
|
+
ValueError
|
|
469
|
+
If the signature is not a non-empty string.
|
|
584
470
|
"""
|
|
585
471
|
|
|
586
|
-
# Validate that the
|
|
472
|
+
# Validate that the signature is a non-empty string
|
|
587
473
|
if not isinstance(signature, str) or not signature.strip():
|
|
588
|
-
raise ValueError("
|
|
474
|
+
raise ValueError("Signature must be a non-empty string.")
|
|
589
475
|
|
|
590
|
-
# Remove the job from the AsyncIOScheduler, if it exists.
|
|
591
476
|
try:
|
|
592
|
-
self.__asyncio_scheduler.remove_job(signature)
|
|
593
|
-
except Exception:
|
|
594
|
-
# Job may not exist in this scheduler, continue with others
|
|
595
|
-
pass
|
|
596
477
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
478
|
+
# Remove from the scheduler
|
|
479
|
+
self.__scheduler.remove_job(signature)
|
|
480
|
+
|
|
481
|
+
# Remove from internal jobs dictionary
|
|
482
|
+
if signature in self.__jobs:
|
|
483
|
+
del self.__jobs[signature]
|
|
484
|
+
|
|
485
|
+
# Give a small delay to ensure proper cleanup
|
|
486
|
+
await asyncio.sleep(0.01)
|
|
487
|
+
|
|
488
|
+
# Log the removal of the job
|
|
489
|
+
self.__logger.info(f"Job '{signature}' has been removed from the scheduler.")
|
|
490
|
+
|
|
491
|
+
# Return True to indicate successful removal
|
|
492
|
+
return True
|
|
603
493
|
|
|
604
|
-
# Remove the job from the BlockingScheduler, if it exists.
|
|
605
|
-
try:
|
|
606
|
-
self.__blocking_scheduler.remove_job(signature)
|
|
607
494
|
except Exception:
|
|
608
|
-
|
|
609
|
-
|
|
495
|
+
|
|
496
|
+
# Job not found or other error
|
|
497
|
+
return False
|
|
610
498
|
|
|
611
499
|
def jobs(self) -> dict:
|
|
612
500
|
"""
|
|
@@ -626,78 +514,4 @@ class Scheduler():
|
|
|
626
514
|
"""
|
|
627
515
|
|
|
628
516
|
# Return the internal dictionary holding all scheduled jobs and their details.
|
|
629
|
-
return self.__jobs
|
|
630
|
-
|
|
631
|
-
def start_asyncio_scheduler(self) -> bool:
|
|
632
|
-
"""
|
|
633
|
-
Start the AsyncIOScheduler specifically.
|
|
634
|
-
|
|
635
|
-
This method attempts to start only the AsyncIOScheduler. It's useful when you need
|
|
636
|
-
to start the asyncio scheduler separately or when working in an asyncio environment.
|
|
637
|
-
|
|
638
|
-
Returns
|
|
639
|
-
-------
|
|
640
|
-
bool
|
|
641
|
-
True if the AsyncIOScheduler was started successfully, False otherwise.
|
|
642
|
-
"""
|
|
643
|
-
|
|
644
|
-
try:
|
|
645
|
-
# Check if we're in an asyncio environment
|
|
646
|
-
asyncio.get_running_loop()
|
|
647
|
-
if not self.__asyncio_scheduler.running:
|
|
648
|
-
self.__asyncio_scheduler.start()
|
|
649
|
-
return True
|
|
650
|
-
except RuntimeError:
|
|
651
|
-
# No event loop is running
|
|
652
|
-
return False
|
|
653
|
-
except Exception:
|
|
654
|
-
# Other errors
|
|
655
|
-
return False
|
|
656
|
-
|
|
657
|
-
async def start_asyncio_scheduler_async(self) -> bool:
|
|
658
|
-
"""
|
|
659
|
-
Start the AsyncIOScheduler in an async context.
|
|
660
|
-
|
|
661
|
-
This method is designed to be called from async functions and ensures
|
|
662
|
-
the AsyncIOScheduler is properly started within an asyncio event loop.
|
|
663
|
-
|
|
664
|
-
Returns
|
|
665
|
-
-------
|
|
666
|
-
bool
|
|
667
|
-
True if the AsyncIOScheduler was started successfully, False otherwise.
|
|
668
|
-
"""
|
|
669
|
-
|
|
670
|
-
try:
|
|
671
|
-
if not self.__asyncio_scheduler.running:
|
|
672
|
-
self.__asyncio_scheduler.start()
|
|
673
|
-
return True
|
|
674
|
-
except Exception:
|
|
675
|
-
return False
|
|
676
|
-
|
|
677
|
-
def is_asyncio_scheduler_running(self) -> bool:
|
|
678
|
-
"""
|
|
679
|
-
Check if the AsyncIOScheduler is currently running.
|
|
680
|
-
|
|
681
|
-
Returns
|
|
682
|
-
-------
|
|
683
|
-
bool
|
|
684
|
-
True if the AsyncIOScheduler is running, False otherwise.
|
|
685
|
-
"""
|
|
686
|
-
|
|
687
|
-
return self.__asyncio_scheduler.running if self.__asyncio_scheduler else False
|
|
688
|
-
|
|
689
|
-
def get_scheduler_status(self) -> dict:
|
|
690
|
-
"""
|
|
691
|
-
Get the status of all schedulers.
|
|
692
|
-
|
|
693
|
-
Returns
|
|
694
|
-
-------
|
|
695
|
-
dict
|
|
696
|
-
A dictionary with the running status of each scheduler type.
|
|
697
|
-
"""
|
|
698
|
-
|
|
699
|
-
return {
|
|
700
|
-
'asyncio': self.__asyncio_scheduler.running if self.__asyncio_scheduler else False,
|
|
701
|
-
'background': self.__background_scheduler.running if self.__background_scheduler else False,
|
|
702
|
-
'blocking': self.__blocking_scheduler.running if self.__blocking_scheduler else False
|
|
703
|
-
}
|
|
517
|
+
return self.__jobs
|
orionis/metadata/framework.py
CHANGED
|
@@ -45,7 +45,7 @@ orionis/console/output/contracts/executor.py,sha256=7l3kwnvv6GlH9EYk0v94YE1olex_
|
|
|
45
45
|
orionis/console/output/enums/__init__.py,sha256=LAaAxg-DpArCjf_jqZ0_9s3p8899gntDYkSU_ppTdC8,66
|
|
46
46
|
orionis/console/output/enums/styles.py,sha256=6a4oQCOBOKMh2ARdeq5GlIskJ3wjiylYmh66tUKKmpQ,4053
|
|
47
47
|
orionis/console/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
-
orionis/console/tasks/schedule.py,sha256=
|
|
48
|
+
orionis/console/tasks/schedule.py,sha256=w3S4uZUg6i0EMze4P1B761pl57da2ZdWJFj_SEasarI,18939
|
|
49
49
|
orionis/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
50
|
orionis/container/container.py,sha256=p7kJ-hwnDattTWCArt0ypol4bW3M334hIZ2FAQhID-w,87570
|
|
51
51
|
orionis/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -190,7 +190,7 @@ orionis/foundation/providers/reactor_provider.py,sha256=P0KQcp4AFKTrD6BStGfCTqhG
|
|
|
190
190
|
orionis/foundation/providers/testing_provider.py,sha256=SrJRpdvcblx9WvX7x9Y3zc7OQfiTf7la0HAJrm2ESlE,3725
|
|
191
191
|
orionis/foundation/providers/workers_provider.py,sha256=oa_2NIDH6UxZrtuGkkoo_zEoNIMGgJ46vg5CCgAm7wI,3926
|
|
192
192
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
193
|
-
orionis/metadata/framework.py,sha256=
|
|
193
|
+
orionis/metadata/framework.py,sha256=qz9zbmqbECbLlCEBY3fkC_rY-M5Uq_tCpC6o2gCl-Xk,4109
|
|
194
194
|
orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
|
|
195
195
|
orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
196
196
|
orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -356,7 +356,7 @@ orionis/test/validators/web_report.py,sha256=n9BfzOZz6aEiNTypXcwuWbFRG0OdHNSmCNu
|
|
|
356
356
|
orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnIfJYgc,1206
|
|
357
357
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
358
358
|
orionis/test/view/render.py,sha256=f-zNhtKSg9R5Njqujbg2l2amAs2-mRVESneLIkWOZjU,4082
|
|
359
|
-
orionis-0.
|
|
359
|
+
orionis-0.475.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
|
|
360
360
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
361
361
|
tests/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
362
362
|
tests/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -503,8 +503,8 @@ tests/testing/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
503
503
|
tests/testing/validators/test_testing_validators.py,sha256=WPo5GxTP6xE-Dw3X1vZoqOMpb6HhokjNSbgDsDRDvy4,16588
|
|
504
504
|
tests/testing/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
505
505
|
tests/testing/view/test_render.py,sha256=tnnMBwS0iKUIbogLvu-7Rii50G6Koddp3XT4wgdFEYM,1050
|
|
506
|
-
orionis-0.
|
|
507
|
-
orionis-0.
|
|
508
|
-
orionis-0.
|
|
509
|
-
orionis-0.
|
|
510
|
-
orionis-0.
|
|
506
|
+
orionis-0.475.0.dist-info/METADATA,sha256=HbxMijbYojBubd7QWnfKhzuXEW7GKsIy_mm1STUHVqc,4801
|
|
507
|
+
orionis-0.475.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
508
|
+
orionis-0.475.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
|
509
|
+
orionis-0.475.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
510
|
+
orionis-0.475.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|