diff --git a/assets/scheduler.yaml b/assets/scheduler.yaml index 2707bf0..17874ef 100644 --- a/assets/scheduler.yaml +++ b/assets/scheduler.yaml @@ -1,7 +1,8 @@ --- scheduler: alias: test - cron: '* * * * *' + # cron: '* * * * *' + interval: 3000 # ms enableLog: true # (Optional) default: false property: diff --git a/lib/cli/commands/scheduler/scheduler_interval.dart b/lib/cli/commands/scheduler/scheduler_interval.dart new file mode 100644 index 0000000..bf0a99e --- /dev/null +++ b/lib/cli/commands/scheduler/scheduler_interval.dart @@ -0,0 +1,32 @@ +import 'package:oto_cli/oto/data/command_data.dart'; + +class SchedulerInterval { + + int interval; + bool activate = true; + bool progress = false; + DataBuild build; + + Future Function(DataBuild build) executeFunc; + + SchedulerInterval(this.interval, this.build, this.executeFunc) { + startInterval(); + } + + void startInterval() async { + while(activate) { + await Future.delayed(Duration(milliseconds: interval)); + if(!progress) { + execute(); + } + } + } + + void execute() async { + if(activate) { + progress = true; + await executeFunc(build); + progress = false; + } + } +} \ No newline at end of file diff --git a/lib/cli/commands/scheduler/scheduler_isolate.dart b/lib/cli/commands/scheduler/scheduler_isolate.dart index f0d5ced..baf8b06 100644 --- a/lib/cli/commands/scheduler/scheduler_isolate.dart +++ b/lib/cli/commands/scheduler/scheduler_isolate.dart @@ -7,6 +7,7 @@ import 'package:dart_framework/platform/isolate_manager.dart'; import 'package:dart_framework/utils/string_util.dart'; import 'package:dart_framework/utils/system_util.dart'; import 'package:file_hasher/file_hasher.dart'; +import 'package:oto_cli/cli/commands/scheduler/scheduler_interval.dart'; import 'package:oto_cli/oto/application.dart'; import 'package:oto_cli/oto/data/command_data.dart'; @@ -21,8 +22,10 @@ class IsolateScheduler extends IsolateBase { bool logEnable = false; bool notProgress = true; bool cronClosed = true; + int? interval; + String? cronExpress; late DataBuild build; - late String cronExpress; + SchedulerInterval? schedulerInterval; Cron? cron; int nextStartTime = 0; @@ -40,13 +43,15 @@ class IsolateScheduler extends IsolateBase { await Future.delayed(Duration(seconds: 1)); if(file.existsSync()) { + var updated = false; var hash = await FileHasher.hash(file); if(hash != fileHash) { + updated = true; fileHash = hash; //파일 내용이 바뀔때 마다 새로 읽어 들임 var map = Application.getMapFromYamlA(await file.readAsString()); - //Validate yaml format + //============ Validate yaml format ============// try { build = DataBuild.fromJson(map!); } on Exception catch(e, stacktace) { @@ -58,25 +63,49 @@ class IsolateScheduler extends IsolateBase { return; } - try { - Schedule.parse(build.scheduler!.cron); - cronExpress = build.scheduler!.cron; - } on Error catch(e, stacktace) { - onError("Cron express '${build.scheduler!.cron}' is not a suitable format."); + var scheduler = build.scheduler!; + if(scheduler.cron == null && scheduler.interval == null) { + onError('A scheduler script must have either a cron entry or an interval entry.'); return; } + + if(scheduler.cron != null) { + try { + Schedule.parse(scheduler.cron!); + cronExpress = scheduler.cron!; + } on Error catch(e, stacktace) { + onError("Cron express '${build.scheduler!.cron}' is not a suitable format."); + return; + } + } + + if(scheduler.interval != null) { + interval = scheduler.interval!; + } } - if(cronClosed) { - cronClosed = false; - cron = Cron(); - cron!.schedule(Schedule.parse(cronExpress), () async { - if(notProgress) { - await execute(build); - cronClosed = true; - await cron!.close(); + //============ execute cron/interval ============// + if(cronExpress != null) { + //Use cron + if(cronClosed) { + cronClosed = false; + cron = Cron(); + cron!.schedule(Schedule.parse(cronExpress!), () async { + if(notProgress) { + await execute(build); + cronClosed = true; + await cron!.close(); + } + }); + } + } else { + //Use interval + if(updated) { + if(schedulerInterval != null) { + schedulerInterval!.activate = false; } - }); + schedulerInterval = SchedulerInterval(interval!, build, execute); + } } } else { //file이 없을시 종료 @@ -93,7 +122,7 @@ class IsolateScheduler extends IsolateBase { logFile = File('$logsPath/${alias}_${getDate()}_${getTime().replaceAll(':', '')}_[$pid].txt'); log('Start process on pid [$pid]'); } - await Future.delayed(Duration(seconds: 30)); //To-do: delete test, exe task + await Future.delayed(Duration(seconds: 1)); //To-do: delete test, exe task notProgress = true; return simpleFuture; } @@ -117,4 +146,4 @@ class IsolateScheduler extends IsolateBase { void sendTerminated(String type, String message) { send(IsoMessege('terminated', data: {'type': type, 'message': message, 'alias': alias})); } -} +} \ No newline at end of file diff --git a/lib/cli/commands/scheduler/scheduler_manager.dart b/lib/cli/commands/scheduler/scheduler_manager.dart index ece97bb..b3c5908 100644 --- a/lib/cli/commands/scheduler/scheduler_manager.dart +++ b/lib/cli/commands/scheduler/scheduler_manager.dart @@ -123,6 +123,7 @@ class SchedulerManager { print(''); print('[alias]'.padRight(8) + alias); print('[path]'.padRight(8) + newPath); + print(''); //update settings var local = _localData; @@ -172,7 +173,7 @@ class SchedulerManager { } print(''); } - _checkProcess(); + await _checkProcess(); return simpleFuture; } diff --git a/lib/oto/data/command_data.dart b/lib/oto/data/command_data.dart index dc57c20..58de5e0 100644 --- a/lib/oto/data/command_data.dart +++ b/lib/oto/data/command_data.dart @@ -27,7 +27,8 @@ class DataBuild { @JsonSerializable() class DataScheduler { late String alias; - late String cron; + late String? cron; + late int? interval; late bool? enableLog; DataScheduler(); diff --git a/lib/oto/data/command_data.g.dart b/lib/oto/data/command_data.g.dart index c26e1f2..6b1e2a1 100644 --- a/lib/oto/data/command_data.g.dart +++ b/lib/oto/data/command_data.g.dart @@ -28,13 +28,15 @@ Map _$DataBuildToJson(DataBuild instance) => { DataScheduler _$DataSchedulerFromJson(Map json) => DataScheduler() ..alias = json['alias'] as String - ..cron = json['cron'] as String + ..cron = json['cron'] as String? + ..interval = (json['interval'] as num?)?.toInt() ..enableLog = json['enableLog'] as bool?; Map _$DataSchedulerToJson(DataScheduler instance) => { 'alias': instance.alias, 'cron': instance.cron, + 'interval': instance.interval, 'enableLog': instance.enableLog, };