shareddata 6.83.7__tar.gz → 6.83.8__tar.gz
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.
- {shareddata-6.83.7/src/shareddata.egg-info → shareddata-6.83.8}/PKG-INFO +1 -1
- {shareddata-6.83.7 → shareddata-6.83.8}/setup.py +1 -1
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Logger.py +4 -4
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/Schedule.py +25 -10
- shareddata-6.83.8/src/SharedData/Routines/Scheduler.py +109 -0
- {shareddata-6.83.7 → shareddata-6.83.8/src/shareddata.egg-info}/PKG-INFO +1 -1
- shareddata-6.83.7/src/SharedData/Routines/Scheduler.py +0 -60
- {shareddata-6.83.7 → shareddata-6.83.8}/LICENSE +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/MANIFEST.in +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/README.md +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/pyproject.toml +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/setup.cfg +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/ServerGunicorn.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/ServerWaitress.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/__init__.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/auth.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/constants.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/__init__.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/cache.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/collections.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/metadata.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/system.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/tables.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/timeseries.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/routes/workers.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/API/utils.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/CacheRedis.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/CollectionMongoDB.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Database.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Defaults.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/AWSEC2.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/AWSS3.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/AutoDocstrings.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/ClientAPI.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/ClientSocket.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/ClientWebSocket.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/LogHandlerAPI.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/MongoDBClient.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/SaveTables.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/ServerSocket.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/ServerWebSocket.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/StreamsCache.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/StreamsPersist.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/SyncTable.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/TunnelWebSocket.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/IO/__init__.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Metadata.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/MultiProc.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/OpenFIGI.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/BatchJob.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/ScheduleMonitor.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/Worker.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/WorkerLib.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/WorkerPool.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Routines/__init__.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/SharedData.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/SharedNumpy.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/StreamKafka.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Symbol.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Table.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableDisk.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndex.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndexJitFunctions.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndexJitFunctionsManual.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndexJitGenerate.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndexJitHash.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TableIndexJitLoc.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TimeSeriesDisk.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/TimeseriesContainer.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Users.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/Utils.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/__init__.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/SharedData/sharedmutexwin.pyd +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/shareddata.egg-info/SOURCES.txt +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/shareddata.egg-info/dependency_links.txt +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/shareddata.egg-info/requires.txt +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/src/shareddata.egg-info/top_level.txt +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_api_collection.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_api_collection_loopback.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_api_table.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_api_table_schemaless.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_api_table_schemaless_extend.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_bson_last_pos_reuse.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_cache_redis.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_extend_rt.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_loc.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_metadata.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_read_write_tail.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_stream_loopback_async.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_timeseries.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_timeseries_api.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_upsert_unordered_get_date_loc_d1.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_upsert_unordered_get_date_loc_m1.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_upsert_unordered_get_date_loc_m15.py +0 -0
- {shareddata-6.83.7 → shareddata-6.83.8}/tests/test_upsert_unordered_positions_m1.py +0 -0
|
@@ -34,7 +34,7 @@ install_requires = [
|
|
|
34
34
|
|
|
35
35
|
setup(
|
|
36
36
|
name='shareddata',
|
|
37
|
-
version='6.83.
|
|
37
|
+
version='6.83.8',
|
|
38
38
|
description='Memory Mapped / Shared Memory Database with S3 repository',
|
|
39
39
|
long_description=open('README.md').read(),
|
|
40
40
|
long_description_content_type='text/markdown',
|
|
@@ -390,10 +390,10 @@ class Logger:
|
|
|
390
390
|
dfnewlines_sorted = dfnewlines.sort_values(['asctime', 'sequence_number'])
|
|
391
391
|
if need_full_sort:
|
|
392
392
|
Logger.dflogs = pd.concat([Logger.dflogs, dfnewlines_sorted], ignore_index=True)
|
|
393
|
-
Logger.dflogs['asctime'] = pd.to_datetime(Logger.dflogs['asctime'])
|
|
393
|
+
Logger.dflogs['asctime'] = pd.to_datetime(Logger.dflogs['asctime'], format='ISO8601', errors='coerce')
|
|
394
394
|
Logger.dflogs = Logger.dflogs.sort_values(['asctime', 'sequence_number'], ignore_index=True)
|
|
395
|
-
Logger._sorted_until = len(Logger.dflogs)
|
|
396
|
-
Logger._max_asctime =
|
|
395
|
+
Logger._sorted_until = len(Logger.dflogs)
|
|
396
|
+
Logger._max_asctime = Logger.dflogs['asctime'].max()
|
|
397
397
|
else:
|
|
398
398
|
# Append new lines and sort only the new part
|
|
399
399
|
Logger.dflogs = pd.concat([Logger.dflogs, dfnewlines_sorted], ignore_index=True)
|
|
@@ -452,7 +452,7 @@ class Logger:
|
|
|
452
452
|
pd.DataFrame: DataFrame containing the updated last log entries for the affected (user_name, logger_name) groups.
|
|
453
453
|
"""
|
|
454
454
|
_dflast = df.groupby(['user_name', 'logger_name']).last()
|
|
455
|
-
_dflast['asctime'] = pd.to_datetime(_dflast['asctime'])
|
|
455
|
+
_dflast['asctime'] = pd.to_datetime(_dflast['asctime'], format='ISO8601', errors='coerce')
|
|
456
456
|
|
|
457
457
|
notinidx = _dflast.index.difference(Logger.dflast.index)
|
|
458
458
|
Logger.dflast = Logger.dflast.reindex(_dflast.index.union(Logger.dflast.index))
|
|
@@ -222,11 +222,26 @@ class Schedule:
|
|
|
222
222
|
def update(self):
|
|
223
223
|
"""
|
|
224
224
|
Updates the object's logs, batch status, and realtime status, then merges the realtime and batch DataFrames into a single schedule DataFrame with a reset index.
|
|
225
|
+
|
|
226
|
+
Each stage is isolated: a failure in UpdateLogs must not prevent
|
|
227
|
+
UpdateBatchStatus from running, and vice versa, so a single malformed
|
|
228
|
+
log row (or a pandas parser hiccup) cannot stall the whole scheduler.
|
|
225
229
|
"""
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
+
for stage_name, stage_fn in (
|
|
231
|
+
('UpdateLogs', self.UpdateLogs),
|
|
232
|
+
('UpdateBatchStatus', self.UpdateBatchStatus),
|
|
233
|
+
('UpdateRealtimeStatus', self.UpdateRealtimeStatus),
|
|
234
|
+
):
|
|
235
|
+
try:
|
|
236
|
+
stage_fn()
|
|
237
|
+
except Exception as e:
|
|
238
|
+
Logger.log.error(
|
|
239
|
+
'Schedule.%s[%s] failed: %s' % (stage_name, self.schedule_name, e))
|
|
240
|
+
try:
|
|
241
|
+
self.schedule = pd.concat([self.realtime, self.batch]).reset_index()
|
|
242
|
+
except Exception as e:
|
|
243
|
+
Logger.log.error(
|
|
244
|
+
'Schedule.update merge[%s] failed: %s' % (self.schedule_name, e))
|
|
230
245
|
|
|
231
246
|
def UpdateLogs(self):
|
|
232
247
|
"""
|
|
@@ -252,7 +267,7 @@ class Schedule:
|
|
|
252
267
|
if not Logger.dfrun.empty:
|
|
253
268
|
df = Logger.dfrun.copy()
|
|
254
269
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
255
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
270
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
256
271
|
df = df.sort_values('asctime')
|
|
257
272
|
df = df.groupby('routine').last()
|
|
258
273
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -267,7 +282,7 @@ class Schedule:
|
|
|
267
282
|
if not Logger.dfstarted.empty:
|
|
268
283
|
df = Logger.dfstarted.copy()
|
|
269
284
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
270
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
285
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
271
286
|
df = df.sort_values('asctime')
|
|
272
287
|
df = df.groupby('routine').last()
|
|
273
288
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -281,7 +296,7 @@ class Schedule:
|
|
|
281
296
|
if not Logger.dferror.empty:
|
|
282
297
|
df = Logger.dferror.copy()
|
|
283
298
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
284
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
299
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
285
300
|
df = df.sort_values('asctime')
|
|
286
301
|
df = df.groupby('routine').last()
|
|
287
302
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -293,7 +308,7 @@ class Schedule:
|
|
|
293
308
|
if not Logger.dfcompleted.empty:
|
|
294
309
|
df = Logger.dfcompleted.copy()
|
|
295
310
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
296
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
311
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
297
312
|
df = df.sort_values('asctime')
|
|
298
313
|
df = df.groupby('routine').last()
|
|
299
314
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -305,7 +320,7 @@ class Schedule:
|
|
|
305
320
|
if not Logger.dflast.empty:
|
|
306
321
|
df = Logger.dflast.copy().reset_index()
|
|
307
322
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
308
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
323
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
309
324
|
df = df.sort_values('asctime')
|
|
310
325
|
df = df.groupby('routine').last()
|
|
311
326
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -320,7 +335,7 @@ class Schedule:
|
|
|
320
335
|
if not Logger.dfheartbeats.empty:
|
|
321
336
|
df = Logger.dfheartbeats.copy().reset_index()
|
|
322
337
|
df['routine'] = df['user_name']+':'+df['logger_name']
|
|
323
|
-
df['asctime'] = pd.to_datetime(df['asctime'])
|
|
338
|
+
df['asctime'] = pd.to_datetime(df['asctime'], format='ISO8601', errors='coerce')
|
|
324
339
|
df = df.sort_values('asctime')
|
|
325
340
|
df = df.groupby('routine').last()
|
|
326
341
|
idisin = dfsched.index[dfsched.index.isin(df.index)]
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import faulthandler
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
import pytz
|
|
7
|
+
from tzlocal import get_localzone
|
|
8
|
+
local_tz = pytz.timezone(str(get_localzone()))
|
|
9
|
+
|
|
10
|
+
# Capture a Python-level traceback if a C extension (pandas_parser, numpy,
|
|
11
|
+
# pyarrow, ...) crashes the interpreter with SIGSEGV/SIGABRT/SIGFPE/SIGBUS.
|
|
12
|
+
# Without this, a crash leaves only a kernel segfault line with a raw IP.
|
|
13
|
+
faulthandler.enable()
|
|
14
|
+
|
|
15
|
+
# PROPRIETARY LIBS
|
|
16
|
+
from SharedData.Routines.Schedule import Schedule
|
|
17
|
+
from SharedData.Logger import Logger
|
|
18
|
+
from SharedData.SharedData import SharedData
|
|
19
|
+
shdata = SharedData('SharedData.Routines.Scheduler', user='master')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _safe(desc, fn, *args, **kwargs):
|
|
23
|
+
"""Run fn(*args, **kwargs), log any exception, never propagate."""
|
|
24
|
+
try:
|
|
25
|
+
return fn(*args, **kwargs)
|
|
26
|
+
except Exception as e:
|
|
27
|
+
Logger.log.error('Scheduler %s failed: %s' % (desc, e))
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if len(sys.argv) >= 2:
|
|
32
|
+
ARGS = str(sys.argv[1])
|
|
33
|
+
else:
|
|
34
|
+
Logger.log.error('Schedules not provided, please specify!')
|
|
35
|
+
raise SystemExit(2)
|
|
36
|
+
|
|
37
|
+
Logger.log.info(
|
|
38
|
+
'SharedData Routines Scheduler starting for %s...' % (ARGS))
|
|
39
|
+
|
|
40
|
+
schedule_names = ARGS.split(',')
|
|
41
|
+
|
|
42
|
+
lastheartbeat = time.time()
|
|
43
|
+
Logger.log.info('ROUTINE STARTED!')
|
|
44
|
+
|
|
45
|
+
# Boot each schedule independently — one bad SCHEDULES/<name> must not
|
|
46
|
+
# prevent the others from running.
|
|
47
|
+
schedules = {}
|
|
48
|
+
for schedule_name in schedule_names:
|
|
49
|
+
try:
|
|
50
|
+
sched = Schedule(schedule_name)
|
|
51
|
+
sched.update()
|
|
52
|
+
sched.save()
|
|
53
|
+
schedules[schedule_name] = sched
|
|
54
|
+
except Exception as e:
|
|
55
|
+
Logger.log.error(
|
|
56
|
+
'Scheduler failed to load schedule %s: %s' % (schedule_name, e))
|
|
57
|
+
|
|
58
|
+
if not schedules:
|
|
59
|
+
Logger.log.error('Scheduler has no loadable schedules — retrying in main loop')
|
|
60
|
+
|
|
61
|
+
while True:
|
|
62
|
+
try:
|
|
63
|
+
if time.time() - lastheartbeat > 15:
|
|
64
|
+
lastheartbeat = time.time()
|
|
65
|
+
Logger.log.debug('#heartbeat#schedule:%s' % (ARGS))
|
|
66
|
+
|
|
67
|
+
# Retry failed schedule loads every tick so a transient MongoDB / metadata
|
|
68
|
+
# outage doesn't leave a schedule permanently dark.
|
|
69
|
+
for schedule_name in schedule_names:
|
|
70
|
+
if schedule_name not in schedules:
|
|
71
|
+
try:
|
|
72
|
+
sched = Schedule(schedule_name)
|
|
73
|
+
sched.update()
|
|
74
|
+
sched.save()
|
|
75
|
+
schedules[schedule_name] = sched
|
|
76
|
+
Logger.log.info(
|
|
77
|
+
'Scheduler recovered schedule %s' % (schedule_name))
|
|
78
|
+
except Exception as e:
|
|
79
|
+
Logger.log.error(
|
|
80
|
+
'Scheduler still cannot load %s: %s' % (schedule_name, e))
|
|
81
|
+
|
|
82
|
+
now = datetime.now().astimezone(tz=local_tz)
|
|
83
|
+
for s in list(schedules.keys()):
|
|
84
|
+
sched = schedules[s]
|
|
85
|
+
try:
|
|
86
|
+
if (
|
|
87
|
+
sched.schedule is not None
|
|
88
|
+
and len(sched.schedule) > 0
|
|
89
|
+
and 'runtimes' in sched.schedule.columns
|
|
90
|
+
and len(sched.schedule['runtimes']) > 0
|
|
91
|
+
and now.date() > sched.schedule['runtimes'][0].date()
|
|
92
|
+
):
|
|
93
|
+
Logger.log.info(
|
|
94
|
+
'Reloading Schedule %s %s' % (s, str(datetime.now())))
|
|
95
|
+
_safe('%s.load' % s, sched.load)
|
|
96
|
+
|
|
97
|
+
_safe('%s.update' % s, sched.update)
|
|
98
|
+
_safe('%s.run' % s, sched.run)
|
|
99
|
+
_safe('%s.save' % s, sched.save)
|
|
100
|
+
except Exception as e:
|
|
101
|
+
# Belt-and-suspenders: even with per-stage _safe above, one
|
|
102
|
+
# bad schedule cannot stop others from running this tick.
|
|
103
|
+
Logger.log.error(
|
|
104
|
+
'Scheduler schedule %s tick failed: %s' % (s, e))
|
|
105
|
+
|
|
106
|
+
time.sleep(5)
|
|
107
|
+
except Exception as e:
|
|
108
|
+
Logger.log.error('Scheduler Loop Exception: %s' % (str(e)))
|
|
109
|
+
time.sleep(60)
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
import time
|
|
4
|
-
from datetime import datetime
|
|
5
|
-
import pytz
|
|
6
|
-
from tzlocal import get_localzone
|
|
7
|
-
local_tz = pytz.timezone(str(get_localzone()))
|
|
8
|
-
|
|
9
|
-
# PROPRIETARY LIBS
|
|
10
|
-
from SharedData.Routines.Schedule import Schedule
|
|
11
|
-
from SharedData.Logger import Logger
|
|
12
|
-
from SharedData.SharedData import SharedData
|
|
13
|
-
shdata = SharedData('SharedData.Routines.Scheduler', user='master')
|
|
14
|
-
|
|
15
|
-
try:
|
|
16
|
-
if len(sys.argv) >= 2:
|
|
17
|
-
ARGS = str(sys.argv[1])
|
|
18
|
-
else:
|
|
19
|
-
Logger.log.error('Schedules not provided, please specify!')
|
|
20
|
-
raise Exception('Schedules not provided, please specify!')
|
|
21
|
-
|
|
22
|
-
Logger.log.info(
|
|
23
|
-
'SharedData Routines Scheduler starting for %s...' % (ARGS))
|
|
24
|
-
|
|
25
|
-
schedule_names = ARGS.split(',')
|
|
26
|
-
|
|
27
|
-
lastheartbeat = time.time()
|
|
28
|
-
Logger.log.info('ROUTINE STARTED!')
|
|
29
|
-
|
|
30
|
-
schedules = {}
|
|
31
|
-
for schedule_name in schedule_names:
|
|
32
|
-
schedules[schedule_name] = Schedule(schedule_name)
|
|
33
|
-
schedules[schedule_name].update()
|
|
34
|
-
schedules[schedule_name].save()
|
|
35
|
-
|
|
36
|
-
while (True):
|
|
37
|
-
try:
|
|
38
|
-
if time.time()-lastheartbeat>15:
|
|
39
|
-
lastheartbeat=time.time()
|
|
40
|
-
Logger.log.debug('#heartbeat#schedule:%s' % (ARGS))
|
|
41
|
-
|
|
42
|
-
now = datetime.now().astimezone(tz=local_tz)
|
|
43
|
-
for s in schedules:
|
|
44
|
-
sched = schedules[s]
|
|
45
|
-
if now.date() > sched.schedule['runtimes'][0].date():
|
|
46
|
-
Logger.log.info('Reloading Schedule %s' % (str(datetime.now())))
|
|
47
|
-
sched.load()
|
|
48
|
-
|
|
49
|
-
sched.update()
|
|
50
|
-
sched.run()
|
|
51
|
-
sched.save()
|
|
52
|
-
|
|
53
|
-
time.sleep(5)
|
|
54
|
-
except Exception as e:
|
|
55
|
-
Logger.log.error('Scheduler Loop Exception: %s' % (str(e)))
|
|
56
|
-
time.sleep(60)
|
|
57
|
-
|
|
58
|
-
except Exception as e:
|
|
59
|
-
Logger.log.error('Scheduler Routine Exception: %s' % (str(e)))
|
|
60
|
-
time.sleep(60)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|