From c1a24a0d3ca4b3917c56aa88d06d5cc3f4f6e5f3 Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Sun, 11 Feb 2024 19:20:57 +0100 Subject: [PATCH 01/18] Create cron logic with CronExpression and CronScheduler for @Scheduled --- .../lib/src/application_generator.dart | 2 +- .../lib/src/controller_generator.dart | 2 +- packages/dartness_server/lib/schedule.dart | 7 ++ .../schedule/cron_expression.dart | 87 ++++++++++++++ .../schedule/cron_scheduler.dart | 52 +++++++++ .../src/configuration/schedule/scheduled.dart | 48 ++++++++ .../schedule/system_time_provider.dart | 7 ++ .../configuration/schedule/time_provider.dart | 5 + .../src/configuration/schedule/time_unit.dart | 25 ++++ packages/dartness_server/pubspec.yaml | 3 +- .../schedue/cron_expression_test.dart | 75 ++++++++++++ .../schedue/cron_scheduler_test.dart | 110 ++++++++++++++++++ 12 files changed, 420 insertions(+), 3 deletions(-) create mode 100644 packages/dartness_server/lib/schedule.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/scheduled.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/time_provider.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/time_unit.dart create mode 100644 packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart create mode 100644 packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart diff --git a/packages/dartness_generator/lib/src/application_generator.dart b/packages/dartness_generator/lib/src/application_generator.dart index a08e76e9..fc8cf2f5 100644 --- a/packages/dartness_generator/lib/src/application_generator.dart +++ b/packages/dartness_generator/lib/src/application_generator.dart @@ -41,7 +41,7 @@ class ApplicationGenerator extends GeneratorForAnnotation { final StringBuffer buffer, final ConstantReader annotation, ) { - buffer.writeln('initDependencies(){'); + buffer.writeln('initDependencies() {'); buffer.writeln('final injectRegister = InstanceRegister.instance;'); final applicationModule = annotation.read(_moduleName).objectValue; diff --git a/packages/dartness_generator/lib/src/controller_generator.dart b/packages/dartness_generator/lib/src/controller_generator.dart index 345cdc37..9b96f38e 100644 --- a/packages/dartness_generator/lib/src/controller_generator.dart +++ b/packages/dartness_generator/lib/src/controller_generator.dart @@ -64,7 +64,7 @@ class ControllerGenerator extends GeneratorForAnnotation { : '${element.name}DartnessController'; final dartnessController = Class( - (extensionBuilder) => extensionBuilder + (classBuilder) => classBuilder ..name = className ..constructors.add(Constructor( (constructorBuilder) => constructorBuilder diff --git a/packages/dartness_server/lib/schedule.dart b/packages/dartness_server/lib/schedule.dart new file mode 100644 index 00000000..efb370d5 --- /dev/null +++ b/packages/dartness_server/lib/schedule.dart @@ -0,0 +1,7 @@ +/// Library that exposes the API for the schedule system +library schedule; + +export 'src/configuration/schedule/scheduled.dart'; +export 'src/configuration/schedule/time_unit.dart'; +export 'src/configuration/schedule/cron_expression.dart'; +export 'src/configuration/schedule/cron_scheduler.dart'; diff --git a/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart b/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart new file mode 100644 index 00000000..b8e7b77f --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart @@ -0,0 +1,87 @@ +/// A class representing a cron expression, used for scheduling tasks. +class CronExpression { + final List seconds; + final List minutes; + final List hours; + final List days; + final List months; + final List weekdays; + + CronExpression({ + required this.seconds, + required this.minutes, + required this.hours, + required this.days, + required this.months, + required this.weekdays, + }); + + /// Parses a cron string into its components. + /// + /// The cron string must have 6 parts, separated by spaces, representing: + /// seconds, minutes, hours, day of month, month, and day of week. + factory CronExpression.parse(String cronString) { + final parts = cronString.split(' '); + if (parts.length != 6) { + throw FormatException('Invalid cron string length'); + } + + // Validate and parse each field + return CronExpression( + seconds: _parseField(parts[0], 0, 59), + minutes: _parseField(parts[1], 0, 59), + hours: _parseField(parts[2], 0, 23), + days: _parseField(parts[3], 1, 31), + months: _parseField(parts[4], 1, 12), + weekdays: _parseField(parts[5], 0, 7), + ); + } + + static List _parseField(String field, int min, int max) { + // Wildcard + if (field == '*') { + return [field]; + } + + // Step values + if (field.contains('/')) { + final stepParts = field.split('/'); + if (stepParts[0] != '*' && + !stepParts[0].contains('-') && + int.tryParse(stepParts[1]) == null) { + throw FormatException('Unsupported or malformed step value'); + } + if (stepParts[0] == '*' && int.parse(stepParts[1]) > max) { + throw FormatException('Step value out of range'); + } + return [field]; + } + + // Range values + if (field.contains('-')) { + final rangeParts = field.split('-').map(int.parse).toList(); + if (rangeParts[0] > rangeParts[1]) { + throw FormatException('Invalid range'); + } + if (rangeParts.any((val) => val < min || val > max)) { + throw FormatException('Range value out of bounds'); + } + return [field]; + } + + // List values + final listParts = field.split(','); + for (var part in listParts) { + final value = int.tryParse(part); + if (value == null || value < min || value > max) { + throw FormatException('Value out of bounds'); + } + } + return listParts; + } + + @override + String toString() { + return 'CronExpression(seconds: $seconds, minutes: $minutes, hours: $hours, days: $days, months: $months, weekdays: $weekdays)'; + } +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart b/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart new file mode 100644 index 00000000..30aff331 --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart @@ -0,0 +1,52 @@ +import 'dart:async'; + +import 'cron_expression.dart'; +import 'system_time_provider.dart'; +import 'time_provider.dart'; + +/// Scheduler class that uses a [CronExpression] to execute tasks periodically. +class CronScheduler { + final CronExpression cronExpression; + // TimeProvider allows for injecting a custom time source, facilitating testing. + final TimeProvider timeProvider; + Timer? _timer; + + // Constructor accepts a cron expression and an optional custom TimeProvider. + // If no TimeProvider is provided, it defaults to the system clock. + CronScheduler(this.cronExpression, {TimeProvider? timeProvider}) + : timeProvider = timeProvider ?? SystemTimeProvider(); + + /// Starts the periodic execution of a task based on the cron expression. + /// [task] is a function with no parameters that encapsulates + /// the invocation of the actual task function with its parameters. + void start(void Function() task) { + _timer = Timer.periodic(Duration(seconds: 1), (Timer t) { + var now = timeProvider.now(); + // Checks if the current time matches the cron expression before executing the task. + if (_matches(now)) { + task(); + } + }); + } + + /// Checks if the current time matches the cron expression. + bool _matches(final DateTime dateTime) { + return (cronExpression.seconds.contains('*') || + cronExpression.seconds.contains(dateTime.second.toString())) && + (cronExpression.minutes.contains('*') || + cronExpression.minutes.contains(dateTime.minute.toString())) && + (cronExpression.hours.contains('*') || + cronExpression.hours.contains(dateTime.hour.toString())) && + (cronExpression.days.contains('*') || + cronExpression.days.contains(dateTime.day.toString())) && + (cronExpression.months.contains('*') || + cronExpression.months.contains(dateTime.month.toString())) && + (cronExpression.weekdays.contains('*') || + cronExpression.weekdays.contains(dateTime.weekday.toString())); + } + + /// Stops the periodic execution of the task. + void stop() { + _timer?.cancel(); + } +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart b/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart new file mode 100644 index 00000000..45d80a4a --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart @@ -0,0 +1,48 @@ +import 'package:dartness_server/src/configuration/schedule/time_unit.dart'; + +/// Represents an annotation for scheduling tasks with various parameters. +class Scheduled { + /// A cron-like expression defining the triggers for the scheduled method. + final String? cron; + + /// The fixed delay between the end of the last invocation and the start of the next. + final int? fixedDelay; + + /// The fixed delay between the end of the last invocation and the start of the next, parsed from a string. + final String? fixedDelayString; + + /// The fixed rate of execution, specifying the period between invocations. + final int? fixedRate; + + /// The fixed rate of execution, parsed from a string. + final String? fixedRateString; + + /// The number of units of time to delay before the first execution of a fixed-rate or fixed-delay task. + final int? initialDelay; + + /// The number of units of time to delay before the first execution, parsed from a string. + final String? initialDelayString; + + /// A qualifier for determining a scheduler to run this scheduled method on. + final String? scheduler; + + /// The time unit to use for fixedDelay, fixedDelayString, fixedRate, fixedRateString, initialDelay, and initialDelayString. + final TimeUnit? timeUnit; + + /// A time zone for which the cron expression will be resolved. + final String? zone; + + /// Constructor for the Scheduled annotation. + const Scheduled({ + this.cron, + this.fixedDelay, + this.fixedDelayString, + this.fixedRate, + this.fixedRateString, + this.initialDelay, + this.initialDelayString, + this.scheduler, + this.timeUnit, + this.zone, + }); +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart b/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart new file mode 100644 index 00000000..f829ba6f --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart @@ -0,0 +1,7 @@ +import 'time_provider.dart'; + +// Default implementation of TimeProvider using the system clock. +class SystemTimeProvider implements TimeProvider { + @override + DateTime now() => DateTime.now(); +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart b/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart new file mode 100644 index 00000000..a1d2223e --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart @@ -0,0 +1,5 @@ +// Abstract class defining the interface for a time provider. +abstract class TimeProvider { + // Method that should return the current time. + DateTime now(); +} \ No newline at end of file diff --git a/packages/dartness_server/lib/src/configuration/schedule/time_unit.dart b/packages/dartness_server/lib/src/configuration/schedule/time_unit.dart new file mode 100644 index 00000000..9b22aafb --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/time_unit.dart @@ -0,0 +1,25 @@ +/// A TimeUnit represents time durations at a given unit of granularity and provides utility methods +enum TimeUnit { + /// Time unit representing twenty four hours + days, + + /// Time unit representing sixty minutes + + hours, + + /// Time unit representing one thousandth of a millisecond + microseconds, + + /// Time unit representing one thousandth of a second + + milliseconds, + + /// Time unit representing sixty seconds + minutes, + + /// Time unit representing one thousandth of a microsecond + nanoseconds, + + /// Time unit representing one second + seconds, +} diff --git a/packages/dartness_server/pubspec.yaml b/packages/dartness_server/pubspec.yaml index 8bac33ac..0bdee9d3 100644 --- a/packages/dartness_server/pubspec.yaml +++ b/packages/dartness_server/pubspec.yaml @@ -25,4 +25,5 @@ dev_dependencies: http: ^1.1.0 lints: ^3.0.0 test: ^1.24.9 - build_runner: ^2.4.6 \ No newline at end of file + build_runner: ^2.4.6 + fake_async: ^1.3.1 \ No newline at end of file diff --git a/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart b/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart new file mode 100644 index 00000000..1cb01b51 --- /dev/null +++ b/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart @@ -0,0 +1,75 @@ +import 'package:dartness_server/schedule.dart'; +import 'package:test/test.dart'; + +void main() { + group('CronExpression Parsing', () { + test('parses wildcard expressions correctly', () { + final expression = CronExpression.parse('* * * * * *'); + expect(expression.seconds, equals(['*'])); + expect(expression.minutes, equals(['*'])); + expect(expression.hours, equals(['*'])); + expect(expression.days, equals(['*'])); + expect(expression.months, equals(['*'])); + expect(expression.weekdays, equals(['*'])); + }); + + test('parses specific value expressions correctly', () { + final expression = CronExpression.parse('5 30 2 15 6 3'); + expect(expression.seconds, equals(['5'])); + expect(expression.minutes, equals(['30'])); + expect(expression.hours, equals(['2'])); + expect(expression.days, equals(['15'])); + expect(expression.months, equals(['6'])); + expect(expression.weekdays, equals(['3'])); + }); + + test('parses list expressions correctly', () { + final expression = CronExpression.parse('1,5 10,20,30 * * * *'); + expect(expression.seconds, equals(['1', '5'])); + expect(expression.minutes, equals(['10', '20', '30'])); + expect(expression.hours, contains('*')); + }); + + test('parses range expressions correctly', () { + final expression = CronExpression.parse('1-5 10-12 * * * *'); + expect(expression.seconds, equals(['1-5'])); + expect(expression.minutes, equals(['10-12'])); + }); + + test('parses step values correctly', () { + final expression = CronExpression.parse('*/5 */10 * * * *'); + expect(expression.seconds, equals(['*/5'])); + expect(expression.minutes, equals(['*/10'])); + }); + + test('throws FormatException for invalid cron string length', () { + expect(() => CronExpression.parse('5 4 3 2'), + throwsA(isA())); + }); + + test('throws FormatException for out-of-range values', () { + // Assuming seconds are 0-59, minutes are 0-59, and so on. + // This example checks for an out-of-range minute value. + expect(() => CronExpression.parse('0 60 * * * *'), + throwsA(isA())); + }); + + test('throws FormatException for invalid characters', () { + // This test assumes the parser does not support special characters or letters + expect(() => CronExpression.parse('* * * * * L'), + throwsA(isA())); + }); + + test('throws FormatException for invalid range', () { + // Example: Start of range is greater than end + expect(() => CronExpression.parse('30-5 * * * * *'), + throwsA(isA())); + }); + + test('throws FormatException for unsupported step values', () { + // Example: Step value is used where not supported or is malformed + expect(() => CronExpression.parse('*/60 * * * * *'), + throwsA(isA())); + }); + }); +} diff --git a/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart b/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart new file mode 100644 index 00000000..6e287b09 --- /dev/null +++ b/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart @@ -0,0 +1,110 @@ +import 'package:dartness_server/schedule.dart'; +import 'package:dartness_server/src/configuration/schedule/time_provider.dart'; +import 'package:test/test.dart'; +import 'package:fake_async/fake_async.dart'; + +// Mock implementation of TimeProvider for testing purposes. +class MockTimeProvider implements TimeProvider { + // The mock time to be returned by now(). + DateTime fakeTime; + + MockTimeProvider(this.fakeTime); + + @override + DateTime now() => fakeTime; + + // Allows tests to simulate the passage of time by advancing the fakeTime. + void advanceTime(Duration duration) { + fakeTime = fakeTime.add(duration); + } +} + +void main() { + group('CronScheduler', () { + test('starts and stops without errors', () async { + // Arrange + // Every second + var cronExpression = CronExpression.parse('* * * * * *'); + var scheduler = CronScheduler(cronExpression); + var taskExecuted = false; + + // Act + scheduler.start(() => taskExecuted = true); + // Wait for at least one cycle + await Future.delayed(Duration(seconds: 2)); + scheduler.stop(); + + // Assert + expect(taskExecuted, isTrue); + }); + + test('executes task every second', () async { + // Arrange + var cronExpression = CronExpression.parse('* * * * * *'); // Every second + var scheduler = CronScheduler(cronExpression); + var executionCount = 0; + void task() => executionCount++; + + // Act + // Wait to accumulate executions + scheduler.start(task); + await Future.delayed(Duration( + seconds: 5, + )); + scheduler.stop(); + + // Assert + // Accounting for potential timing issues + expect(executionCount, greaterThanOrEqualTo(4)); + }); + + test('does not execute task after being stopped', () async { + // Arrange + var cronExpression = CronExpression.parse('* * * * * *'); // Every second + var scheduler = CronScheduler(cronExpression); + var executionCount = 0; + void task() => executionCount++; + + // Act + scheduler.start(task); + // Allow some executions + await Future.delayed(Duration(seconds: 2)); + scheduler.stop(); + var countAfterStop = executionCount; + // Wait to see if it stops executing + await Future.delayed(Duration( + seconds: 2, + )); + + // Assert + expect(executionCount, countAfterStop); + }); + }); + + group('CronScheduler with Mock Time', () { + test('executes task when time matches', () { + fakeAsync((async) { + // Arrange + var mockTime = DateTime(2020, 1, 1, 12, 0); + var mockTimeProvider = MockTimeProvider(mockTime); + var cronExpression = CronExpression.parse('* * * * * *'); + var scheduler = CronScheduler( + cronExpression, + timeProvider: mockTimeProvider, + ); + var executionCount = 0; + + scheduler.start(() => executionCount++); + + // Act: Simulate 2 seconds passing + async.elapse(Duration(seconds: 2)); + + // Assert: Task should have executed at least once + expect(executionCount, greaterThanOrEqualTo(1)); + + // Cleanup + scheduler.stop(); + }); + }); + }); +} From 0d009900d506f58391c58710619baf6423a517a1 Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Sun, 11 Feb 2024 19:21:53 +0100 Subject: [PATCH 02/18] Created @Injectable --- .../dartness_server/lib/configuration.dart | 4 ++++ .../lib/src/configuration/injectable.dart | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 packages/dartness_server/lib/configuration.dart create mode 100644 packages/dartness_server/lib/src/configuration/injectable.dart diff --git a/packages/dartness_server/lib/configuration.dart b/packages/dartness_server/lib/configuration.dart new file mode 100644 index 00000000..f15cc064 --- /dev/null +++ b/packages/dartness_server/lib/configuration.dart @@ -0,0 +1,4 @@ +/// Library that exposes the API for the configuration +library configuration; + +export 'src/configuration/injectable.dart'; diff --git a/packages/dartness_server/lib/src/configuration/injectable.dart b/packages/dartness_server/lib/src/configuration/injectable.dart new file mode 100644 index 00000000..ffb2869e --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/injectable.dart @@ -0,0 +1,24 @@ +/// A metadata annotation used to mark a class as available to the dependency injection system. +/// +/// This annotation can be applied to classes which should be instantiated or managed by the DI framework. +/// Marking a class with `@Injectable` indicates to the DI framework that an instance of the class +/// can be created and provided to other parts of the application that require it. +/// +/// Usage: +/// ``` +/// @Injectable() +/// class MyService { +/// MyService(); +/// } +/// ``` +/// +/// The DI framework will then manage the lifecycle of the instantiated `MyService` objects, +/// allowing for dependency management and injection into other classes that depend on `MyService`. +/// +class Injectable { + /// Creates a new instance of `Injectable`. + /// + /// This constructor is typically not invoked directly, but rather the annotation is placed on the class + /// definition to be managed by the DI framework. + const Injectable(); +} From ceb2240642603c38a4cd8fbe82101f65157ef79a Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Sun, 16 Jun 2024 22:11:48 +0200 Subject: [PATCH 03/18] Created scheduler and scheduled annotations --- packages/dartness_generator/build.yaml | 10 +- packages/dartness_generator/lib/builder.dart | 4 + .../lib/src/application_generator.dart | 23 +++- .../lib/src/scheduler_generator.dart | 50 ++++++++ packages/dartness_generator/pubspec.yaml | 3 +- packages/dartness_server/lib/schedule.dart | 4 +- .../schedule/cron_expression.dart | 87 -------------- .../schedule/cron_scheduler.dart | 52 --------- .../src/configuration/schedule/scheduled.dart | 42 +------ .../src/configuration/schedule/scheduler.dart | 4 + .../schedule/scheduler_manager.dart | 23 ++++ .../schedule/system_time_provider.dart | 7 -- .../configuration/schedule/time_provider.dart | 5 - packages/dartness_server/pubspec.yaml | 1 + .../schedue/cron_expression_test.dart | 75 ------------ .../schedue/cron_scheduler_test.dart | 110 ------------------ 16 files changed, 114 insertions(+), 386 deletions(-) create mode 100644 packages/dartness_generator/lib/src/scheduler_generator.dart delete mode 100644 packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart delete mode 100644 packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/scheduler.dart create mode 100644 packages/dartness_server/lib/src/configuration/schedule/scheduler_manager.dart delete mode 100644 packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart delete mode 100644 packages/dartness_server/lib/src/configuration/schedule/time_provider.dart delete mode 100644 packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart delete mode 100644 packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart diff --git a/packages/dartness_generator/build.yaml b/packages/dartness_generator/build.yaml index 614d21f3..f19c142a 100644 --- a/packages/dartness_generator/build.yaml +++ b/packages/dartness_generator/build.yaml @@ -16,10 +16,18 @@ builders: build_to: cache applies_builders: [ "source_gen|combining_builder" ] application: - target: ":error_handler_generator" + target: ":application_generator" import: "package:dartness_generator/builder.dart" builder_factories: [ "application" ] build_extensions: { ".dart": [ ".g.part" ] } auto_apply: dependents build_to: cache + applies_builders: [ "source_gen|combining_builder" ] + scheduler: + target: ":scheduler_generator" + import: "package:dartness_generator/builder.dart" + builder_factories: [ "scheduler" ] + build_extensions: { ".dart": [ ".g.part" ] } + auto_apply: dependents + build_to: cache applies_builders: [ "source_gen|combining_builder" ] \ No newline at end of file diff --git a/packages/dartness_generator/lib/builder.dart b/packages/dartness_generator/lib/builder.dart index 74dbbcfa..e80f6328 100644 --- a/packages/dartness_generator/lib/builder.dart +++ b/packages/dartness_generator/lib/builder.dart @@ -4,6 +4,7 @@ import 'package:source_gen/source_gen.dart'; import 'src/application_generator.dart'; import 'src/controller_generator.dart'; import 'src/error_handler_generator.dart'; +import 'src/scheduler_generator.dart'; Builder controller(BuilderOptions options) => SharedPartBuilder([ControllerGenerator()], 'controller'); @@ -13,3 +14,6 @@ Builder errorHandler(BuilderOptions options) => Builder application(BuilderOptions options) => SharedPartBuilder([ApplicationGenerator()], 'application'); + +Builder scheduler(BuilderOptions options) => + SharedPartBuilder([SchedulerGenerator()], 'scheduler'); diff --git a/packages/dartness_generator/lib/src/application_generator.dart b/packages/dartness_generator/lib/src/application_generator.dart index fc8cf2f5..02bc75b2 100644 --- a/packages/dartness_generator/lib/src/application_generator.dart +++ b/packages/dartness_generator/lib/src/application_generator.dart @@ -3,11 +3,13 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:build/build.dart'; import 'package:collection/collection.dart'; import 'package:dartness_server/dartness.dart'; +import 'package:dartness_server/schedule.dart'; import 'package:source_gen/source_gen.dart'; class ApplicationGenerator extends GeneratorForAnnotation { static final _applicationType = TypeChecker.fromRuntime(Application); static final _injectType = TypeChecker.fromRuntime(Inject); + static final _scheduledType = TypeChecker.fromRuntime(Scheduler); static final _useFactoryName = 'useFactory'; static final _moduleName = 'module'; static final _metadataName = 'metadata'; @@ -128,9 +130,7 @@ class ApplicationGenerator extends GeneratorForAnnotation { buffer.writeln('Function.apply(${useFactoryFunc.name},'); } final resolves = useFactoryFunc.parameters.map((param) { - final String className = param.type.getDisplayString( - withNullability: false, - ); + final String className = param.type.getDisplayString(); final inject = param.metadata .firstWhereOrNull((element) => element.runtimeType == Inject); final injectName = inject @@ -165,9 +165,7 @@ class ApplicationGenerator extends GeneratorForAnnotation { buffer.writeln('${providerElement.name}('); final resolves = constructor.parameters.map((constructorParam) { - final String className = constructorParam.type.getDisplayString( - withNullability: false, - ); + final String className = constructorParam.type.getDisplayString(); final injectType = _injectType.firstAnnotationOfExact(constructorParam); final injectName = injectType?.getField(_fieldNameName)?.toStringValue(); if (injectName != null && injectName.isNotEmpty) { @@ -328,6 +326,19 @@ class ApplicationGenerator extends GeneratorForAnnotation { buffer.writeln(');'); } + final allProviders = _getAllProviders(rootModuleMetadata); + final allSchedulers = allProviders + .map((e) => e.getField('classType')) + .map((e) => e?.toTypeValue()) + .map((e) => e?.element) + .whereNotNull() + .where((e) => _scheduledType.hasAnnotationOfExact(e)); + + for (final scheduler in allSchedulers) { + buffer.writeln( + 'injectRegister.resolve<${scheduler.displayName}>().initSchedules();'); + } + // main end method buffer.writeln('}'); } diff --git a/packages/dartness_generator/lib/src/scheduler_generator.dart b/packages/dartness_generator/lib/src/scheduler_generator.dart new file mode 100644 index 00000000..1a705b14 --- /dev/null +++ b/packages/dartness_generator/lib/src/scheduler_generator.dart @@ -0,0 +1,50 @@ +import 'package:analyzer/dart/element/element.dart'; +import 'package:build/build.dart'; +import 'package:dartness_server/schedule.dart'; +import 'package:source_gen/source_gen.dart'; + +class SchedulerGenerator extends GeneratorForAnnotation { + static final _scheduledType = TypeChecker.fromRuntime(Scheduled); + + @override + String? generateForAnnotatedElement( + final Element element, + final ConstantReader annotation, + final BuildStep buildStep, + ) { + if (element is! ClassElement) { + throw InvalidGenerationSourceError( + '@${element.name} cannot target `${element.runtimeType}`. ' + 'It is not a class.'); + } + + final scheduledList = _findScheduledElements(element); + + final buffer = StringBuffer(); + buffer.writeln('extension ${element.name}Extension on ${element.name} {'); + buffer.writeln('void initSchedules() {'); + int count = 0; + for (final scheduledExpression in scheduledList) { + final scheduledAnnotation = + _scheduledType.firstAnnotationOfExact(scheduledExpression); + + final cron = scheduledAnnotation?.getField('cron')?.toStringValue(); + if (cron != null) { + buffer.writeln('final scheduler$count = SchedulerManager("$cron");'); + buffer.writeln('scheduler$count.start(${scheduledExpression.name});'); + } + count++; + } + // Ends initSchedules + buffer.writeln('}'); + + // Ends extension + buffer.writeln('}'); + return buffer.toString(); + } + + List _findScheduledElements(ClassElement classElement) => [ + ...classElement.methods.where(_scheduledType.hasAnnotationOf), + ...classElement.accessors.where(_scheduledType.hasAnnotationOf) + ]..sort((a, b) => (a.nameOffset).compareTo(b.nameOffset)); +} diff --git a/packages/dartness_generator/pubspec.yaml b/packages/dartness_generator/pubspec.yaml index c2271597..07f81347 100644 --- a/packages/dartness_generator/pubspec.yaml +++ b/packages/dartness_generator/pubspec.yaml @@ -15,7 +15,8 @@ dependencies: source_gen: ^1.4.0 analyzer: ^6.3.0 code_builder: ^4.7.0 - dartness_server: ^0.6.0 + dartness_server: + path: ../dartness_server dev_dependencies: lints: ^3.0.0 diff --git a/packages/dartness_server/lib/schedule.dart b/packages/dartness_server/lib/schedule.dart index efb370d5..8d02c180 100644 --- a/packages/dartness_server/lib/schedule.dart +++ b/packages/dartness_server/lib/schedule.dart @@ -2,6 +2,6 @@ library schedule; export 'src/configuration/schedule/scheduled.dart'; +export 'src/configuration/schedule/scheduler.dart'; export 'src/configuration/schedule/time_unit.dart'; -export 'src/configuration/schedule/cron_expression.dart'; -export 'src/configuration/schedule/cron_scheduler.dart'; +export 'src/configuration/schedule/scheduler_manager.dart'; diff --git a/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart b/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart deleted file mode 100644 index b8e7b77f..00000000 --- a/packages/dartness_server/lib/src/configuration/schedule/cron_expression.dart +++ /dev/null @@ -1,87 +0,0 @@ -/// A class representing a cron expression, used for scheduling tasks. -class CronExpression { - final List seconds; - final List minutes; - final List hours; - final List days; - final List months; - final List weekdays; - - CronExpression({ - required this.seconds, - required this.minutes, - required this.hours, - required this.days, - required this.months, - required this.weekdays, - }); - - /// Parses a cron string into its components. - /// - /// The cron string must have 6 parts, separated by spaces, representing: - /// seconds, minutes, hours, day of month, month, and day of week. - factory CronExpression.parse(String cronString) { - final parts = cronString.split(' '); - if (parts.length != 6) { - throw FormatException('Invalid cron string length'); - } - - // Validate and parse each field - return CronExpression( - seconds: _parseField(parts[0], 0, 59), - minutes: _parseField(parts[1], 0, 59), - hours: _parseField(parts[2], 0, 23), - days: _parseField(parts[3], 1, 31), - months: _parseField(parts[4], 1, 12), - weekdays: _parseField(parts[5], 0, 7), - ); - } - - static List _parseField(String field, int min, int max) { - // Wildcard - if (field == '*') { - return [field]; - } - - // Step values - if (field.contains('/')) { - final stepParts = field.split('/'); - if (stepParts[0] != '*' && - !stepParts[0].contains('-') && - int.tryParse(stepParts[1]) == null) { - throw FormatException('Unsupported or malformed step value'); - } - if (stepParts[0] == '*' && int.parse(stepParts[1]) > max) { - throw FormatException('Step value out of range'); - } - return [field]; - } - - // Range values - if (field.contains('-')) { - final rangeParts = field.split('-').map(int.parse).toList(); - if (rangeParts[0] > rangeParts[1]) { - throw FormatException('Invalid range'); - } - if (rangeParts.any((val) => val < min || val > max)) { - throw FormatException('Range value out of bounds'); - } - return [field]; - } - - // List values - final listParts = field.split(','); - for (var part in listParts) { - final value = int.tryParse(part); - if (value == null || value < min || value > max) { - throw FormatException('Value out of bounds'); - } - } - return listParts; - } - - @override - String toString() { - return 'CronExpression(seconds: $seconds, minutes: $minutes, hours: $hours, days: $days, months: $months, weekdays: $weekdays)'; - } -} diff --git a/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart b/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart deleted file mode 100644 index 30aff331..00000000 --- a/packages/dartness_server/lib/src/configuration/schedule/cron_scheduler.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:async'; - -import 'cron_expression.dart'; -import 'system_time_provider.dart'; -import 'time_provider.dart'; - -/// Scheduler class that uses a [CronExpression] to execute tasks periodically. -class CronScheduler { - final CronExpression cronExpression; - // TimeProvider allows for injecting a custom time source, facilitating testing. - final TimeProvider timeProvider; - Timer? _timer; - - // Constructor accepts a cron expression and an optional custom TimeProvider. - // If no TimeProvider is provided, it defaults to the system clock. - CronScheduler(this.cronExpression, {TimeProvider? timeProvider}) - : timeProvider = timeProvider ?? SystemTimeProvider(); - - /// Starts the periodic execution of a task based on the cron expression. - /// [task] is a function with no parameters that encapsulates - /// the invocation of the actual task function with its parameters. - void start(void Function() task) { - _timer = Timer.periodic(Duration(seconds: 1), (Timer t) { - var now = timeProvider.now(); - // Checks if the current time matches the cron expression before executing the task. - if (_matches(now)) { - task(); - } - }); - } - - /// Checks if the current time matches the cron expression. - bool _matches(final DateTime dateTime) { - return (cronExpression.seconds.contains('*') || - cronExpression.seconds.contains(dateTime.second.toString())) && - (cronExpression.minutes.contains('*') || - cronExpression.minutes.contains(dateTime.minute.toString())) && - (cronExpression.hours.contains('*') || - cronExpression.hours.contains(dateTime.hour.toString())) && - (cronExpression.days.contains('*') || - cronExpression.days.contains(dateTime.day.toString())) && - (cronExpression.months.contains('*') || - cronExpression.months.contains(dateTime.month.toString())) && - (cronExpression.weekdays.contains('*') || - cronExpression.weekdays.contains(dateTime.weekday.toString())); - } - - /// Stops the periodic execution of the task. - void stop() { - _timer?.cancel(); - } -} diff --git a/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart b/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart index 45d80a4a..43feaccd 100644 --- a/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart +++ b/packages/dartness_server/lib/src/configuration/schedule/scheduled.dart @@ -1,48 +1,10 @@ -import 'package:dartness_server/src/configuration/schedule/time_unit.dart'; - /// Represents an annotation for scheduling tasks with various parameters. class Scheduled { /// A cron-like expression defining the triggers for the scheduled method. - final String? cron; - - /// The fixed delay between the end of the last invocation and the start of the next. - final int? fixedDelay; - - /// The fixed delay between the end of the last invocation and the start of the next, parsed from a string. - final String? fixedDelayString; - - /// The fixed rate of execution, specifying the period between invocations. - final int? fixedRate; - - /// The fixed rate of execution, parsed from a string. - final String? fixedRateString; - - /// The number of units of time to delay before the first execution of a fixed-rate or fixed-delay task. - final int? initialDelay; - - /// The number of units of time to delay before the first execution, parsed from a string. - final String? initialDelayString; - - /// A qualifier for determining a scheduler to run this scheduled method on. - final String? scheduler; - - /// The time unit to use for fixedDelay, fixedDelayString, fixedRate, fixedRateString, initialDelay, and initialDelayString. - final TimeUnit? timeUnit; - - /// A time zone for which the cron expression will be resolved. - final String? zone; + final String cron; /// Constructor for the Scheduled annotation. const Scheduled({ - this.cron, - this.fixedDelay, - this.fixedDelayString, - this.fixedRate, - this.fixedRateString, - this.initialDelay, - this.initialDelayString, - this.scheduler, - this.timeUnit, - this.zone, + required this.cron, }); } diff --git a/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart b/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart new file mode 100644 index 00000000..d7c2461c --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart @@ -0,0 +1,4 @@ +/// Represents an annotation for scheduling tasks with various parameters. +class Scheduler { + const Scheduler(); +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/scheduler_manager.dart b/packages/dartness_server/lib/src/configuration/schedule/scheduler_manager.dart new file mode 100644 index 00000000..b8e8e47d --- /dev/null +++ b/packages/dartness_server/lib/src/configuration/schedule/scheduler_manager.dart @@ -0,0 +1,23 @@ +import 'package:cron/cron.dart'; + +/// Scheduler class that uses a [CronExpression] to execute tasks periodically. +class SchedulerManager { + final String cronExpression; + final Cron cron; + + // Constructor accepts a cron expression and an optional custom TimeProvider. + // If no TimeProvider is provided, it defaults to the system clock. + SchedulerManager(this.cronExpression) : cron = Cron(); + + /// Starts the periodic execution of a task based on the cron expression. + /// [task] is a function with no parameters that encapsulates + /// the invocation of the actual task function with its parameters. + void start(void Function() task) { + cron.schedule(Schedule.parse(cronExpression), task); + } + + /// Stops the periodic execution of the task. + void stop() { + cron.close(); + } +} diff --git a/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart b/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart deleted file mode 100644 index f829ba6f..00000000 --- a/packages/dartness_server/lib/src/configuration/schedule/system_time_provider.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'time_provider.dart'; - -// Default implementation of TimeProvider using the system clock. -class SystemTimeProvider implements TimeProvider { - @override - DateTime now() => DateTime.now(); -} diff --git a/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart b/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart deleted file mode 100644 index a1d2223e..00000000 --- a/packages/dartness_server/lib/src/configuration/schedule/time_provider.dart +++ /dev/null @@ -1,5 +0,0 @@ -// Abstract class defining the interface for a time provider. -abstract class TimeProvider { - // Method that should return the current time. - DateTime now(); -} \ No newline at end of file diff --git a/packages/dartness_server/pubspec.yaml b/packages/dartness_server/pubspec.yaml index 0bdee9d3..43a38853 100644 --- a/packages/dartness_server/pubspec.yaml +++ b/packages/dartness_server/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: shelf_plus: ^1.7.0 shelf_router: ^1.1.4 injector: ^3.0.0 + cron: ^0.6.0 dev_dependencies: http: ^1.1.0 diff --git a/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart b/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart deleted file mode 100644 index 1cb01b51..00000000 --- a/packages/dartness_server/test/lib/src/configuration/schedue/cron_expression_test.dart +++ /dev/null @@ -1,75 +0,0 @@ -import 'package:dartness_server/schedule.dart'; -import 'package:test/test.dart'; - -void main() { - group('CronExpression Parsing', () { - test('parses wildcard expressions correctly', () { - final expression = CronExpression.parse('* * * * * *'); - expect(expression.seconds, equals(['*'])); - expect(expression.minutes, equals(['*'])); - expect(expression.hours, equals(['*'])); - expect(expression.days, equals(['*'])); - expect(expression.months, equals(['*'])); - expect(expression.weekdays, equals(['*'])); - }); - - test('parses specific value expressions correctly', () { - final expression = CronExpression.parse('5 30 2 15 6 3'); - expect(expression.seconds, equals(['5'])); - expect(expression.minutes, equals(['30'])); - expect(expression.hours, equals(['2'])); - expect(expression.days, equals(['15'])); - expect(expression.months, equals(['6'])); - expect(expression.weekdays, equals(['3'])); - }); - - test('parses list expressions correctly', () { - final expression = CronExpression.parse('1,5 10,20,30 * * * *'); - expect(expression.seconds, equals(['1', '5'])); - expect(expression.minutes, equals(['10', '20', '30'])); - expect(expression.hours, contains('*')); - }); - - test('parses range expressions correctly', () { - final expression = CronExpression.parse('1-5 10-12 * * * *'); - expect(expression.seconds, equals(['1-5'])); - expect(expression.minutes, equals(['10-12'])); - }); - - test('parses step values correctly', () { - final expression = CronExpression.parse('*/5 */10 * * * *'); - expect(expression.seconds, equals(['*/5'])); - expect(expression.minutes, equals(['*/10'])); - }); - - test('throws FormatException for invalid cron string length', () { - expect(() => CronExpression.parse('5 4 3 2'), - throwsA(isA())); - }); - - test('throws FormatException for out-of-range values', () { - // Assuming seconds are 0-59, minutes are 0-59, and so on. - // This example checks for an out-of-range minute value. - expect(() => CronExpression.parse('0 60 * * * *'), - throwsA(isA())); - }); - - test('throws FormatException for invalid characters', () { - // This test assumes the parser does not support special characters or letters - expect(() => CronExpression.parse('* * * * * L'), - throwsA(isA())); - }); - - test('throws FormatException for invalid range', () { - // Example: Start of range is greater than end - expect(() => CronExpression.parse('30-5 * * * * *'), - throwsA(isA())); - }); - - test('throws FormatException for unsupported step values', () { - // Example: Step value is used where not supported or is malformed - expect(() => CronExpression.parse('*/60 * * * * *'), - throwsA(isA())); - }); - }); -} diff --git a/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart b/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart deleted file mode 100644 index 6e287b09..00000000 --- a/packages/dartness_server/test/lib/src/configuration/schedue/cron_scheduler_test.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:dartness_server/schedule.dart'; -import 'package:dartness_server/src/configuration/schedule/time_provider.dart'; -import 'package:test/test.dart'; -import 'package:fake_async/fake_async.dart'; - -// Mock implementation of TimeProvider for testing purposes. -class MockTimeProvider implements TimeProvider { - // The mock time to be returned by now(). - DateTime fakeTime; - - MockTimeProvider(this.fakeTime); - - @override - DateTime now() => fakeTime; - - // Allows tests to simulate the passage of time by advancing the fakeTime. - void advanceTime(Duration duration) { - fakeTime = fakeTime.add(duration); - } -} - -void main() { - group('CronScheduler', () { - test('starts and stops without errors', () async { - // Arrange - // Every second - var cronExpression = CronExpression.parse('* * * * * *'); - var scheduler = CronScheduler(cronExpression); - var taskExecuted = false; - - // Act - scheduler.start(() => taskExecuted = true); - // Wait for at least one cycle - await Future.delayed(Duration(seconds: 2)); - scheduler.stop(); - - // Assert - expect(taskExecuted, isTrue); - }); - - test('executes task every second', () async { - // Arrange - var cronExpression = CronExpression.parse('* * * * * *'); // Every second - var scheduler = CronScheduler(cronExpression); - var executionCount = 0; - void task() => executionCount++; - - // Act - // Wait to accumulate executions - scheduler.start(task); - await Future.delayed(Duration( - seconds: 5, - )); - scheduler.stop(); - - // Assert - // Accounting for potential timing issues - expect(executionCount, greaterThanOrEqualTo(4)); - }); - - test('does not execute task after being stopped', () async { - // Arrange - var cronExpression = CronExpression.parse('* * * * * *'); // Every second - var scheduler = CronScheduler(cronExpression); - var executionCount = 0; - void task() => executionCount++; - - // Act - scheduler.start(task); - // Allow some executions - await Future.delayed(Duration(seconds: 2)); - scheduler.stop(); - var countAfterStop = executionCount; - // Wait to see if it stops executing - await Future.delayed(Duration( - seconds: 2, - )); - - // Assert - expect(executionCount, countAfterStop); - }); - }); - - group('CronScheduler with Mock Time', () { - test('executes task when time matches', () { - fakeAsync((async) { - // Arrange - var mockTime = DateTime(2020, 1, 1, 12, 0); - var mockTimeProvider = MockTimeProvider(mockTime); - var cronExpression = CronExpression.parse('* * * * * *'); - var scheduler = CronScheduler( - cronExpression, - timeProvider: mockTimeProvider, - ); - var executionCount = 0; - - scheduler.start(() => executionCount++); - - // Act: Simulate 2 seconds passing - async.elapse(Duration(seconds: 2)); - - // Assert: Task should have executed at least once - expect(executionCount, greaterThanOrEqualTo(1)); - - // Cleanup - scheduler.stop(); - }); - }); - }); -} From 524cc3900a5a8ea5f2a6d1510b106c8d647aa54e Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Sun, 16 Jun 2024 22:12:03 +0200 Subject: [PATCH 04/18] Created example with scheduler --- .../.vscode/launch.json | 42 +++++++++++++++++++ examples/dartness_simple/lib/src/app.dart | 4 ++ examples/dartness_simple/lib/src/app.g.dart | 2 + .../lib/src/schedulers/example_scheduler.dart | 11 +++++ .../src/schedulers/example_scheduler.g.dart | 14 +++++++ examples/dartness_simple/pubspec.yaml | 8 ++-- 6 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 examples/dartness_flutter_melos/.vscode/launch.json create mode 100644 examples/dartness_simple/lib/src/schedulers/example_scheduler.dart create mode 100644 examples/dartness_simple/lib/src/schedulers/example_scheduler.g.dart diff --git a/examples/dartness_flutter_melos/.vscode/launch.json b/examples/dartness_flutter_melos/.vscode/launch.json new file mode 100644 index 00000000..a9c1b03c --- /dev/null +++ b/examples/dartness_flutter_melos/.vscode/launch.json @@ -0,0 +1,42 @@ +{ + // Use IntelliSense para saber los atributos posibles. + // Mantenga el puntero para ver las descripciones de los existentes atributos. + // Para más información, visite: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "dartness_flutter_melos", + "request": "launch", + "type": "dart" + }, + { + "name": "my_app", + "cwd": "apps\\my_app", + "request": "launch", + "program": "lib/main.dart", + "flutterMode": "debug", + "type": "dart" + }, + { + "name": "my_app (profile mode)", + "cwd": "apps\\my_app", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "my_app (release mode)", + "cwd": "apps\\my_app", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "my_server", + "cwd": "servers\\my_server", + "request": "launch", + "program": "bin\\my_server.dart", + "type": "dart" + } + ] +} diff --git a/examples/dartness_simple/lib/src/app.dart b/examples/dartness_simple/lib/src/app.dart index e9d8f5df..8169bf7c 100644 --- a/examples/dartness_simple/lib/src/app.dart +++ b/examples/dartness_simple/lib/src/app.dart @@ -2,6 +2,7 @@ import 'package:dartness_server/dartness.dart'; import 'package:dartness_server/modules.dart'; import 'package:dartness_server/server.dart'; import 'package:dio/dio.dart'; +import 'package:example/src/schedulers/example_scheduler.dart'; import 'controllers/city_controller.dart'; import 'controllers/todos_controller.dart'; @@ -28,6 +29,9 @@ Dio createDio() => Dio(); classType: Dio, useFactory: createDio, ), + ProviderMetadata( + classType: ExampleScheduler, + ) ], imports: [ userModule, diff --git a/examples/dartness_simple/lib/src/app.g.dart b/examples/dartness_simple/lib/src/app.g.dart index 0fc08d57..6bff9052 100644 --- a/examples/dartness_simple/lib/src/app.g.dart +++ b/examples/dartness_simple/lib/src/app.g.dart @@ -24,6 +24,7 @@ extension AppExtension on App { injectRegister.register( TodosController(injectRegister.resolve())); injectRegister.register(ExampleErrorHandler()); + injectRegister.register(ExampleScheduler()); } Future init() async { @@ -41,5 +42,6 @@ extension AppExtension on App { port: 8080, ), ); + injectRegister.resolve().initSchedules(); } } diff --git a/examples/dartness_simple/lib/src/schedulers/example_scheduler.dart b/examples/dartness_simple/lib/src/schedulers/example_scheduler.dart new file mode 100644 index 00000000..17afb9c5 --- /dev/null +++ b/examples/dartness_simple/lib/src/schedulers/example_scheduler.dart @@ -0,0 +1,11 @@ +import 'package:dartness_server/schedule.dart'; + +part 'example_scheduler.g.dart'; + +@Scheduler() +class ExampleScheduler { + @Scheduled(cron: "* * * * *") + void example() { + print("${DateTime.now()} Hello world"); + } +} diff --git a/examples/dartness_simple/lib/src/schedulers/example_scheduler.g.dart b/examples/dartness_simple/lib/src/schedulers/example_scheduler.g.dart new file mode 100644 index 00000000..a9a4b589 --- /dev/null +++ b/examples/dartness_simple/lib/src/schedulers/example_scheduler.g.dart @@ -0,0 +1,14 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'example_scheduler.dart'; + +// ************************************************************************** +// SchedulerGenerator +// ************************************************************************** + +extension ExampleSchedulerExtension on ExampleScheduler { + void initSchedules() { + final scheduler0 = SchedulerManager("* * * * *"); + scheduler0.start(example); + } +} diff --git a/examples/dartness_simple/pubspec.yaml b/examples/dartness_simple/pubspec.yaml index 76e8363e..de6bfde8 100644 --- a/examples/dartness_simple/pubspec.yaml +++ b/examples/dartness_simple/pubspec.yaml @@ -8,11 +8,13 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - dartness_server: ^0.6.0 + dartness_server: + path: ../../packages/dartness_server dio: ^5.3.3 dev_dependencies: build_runner: ^2.4.6 - dartness_generator: ^0.6.0 - lints: ^3.0.0 + dartness_generator: + path: ../../packages/dartness_generator + lints: ^4.0.0 test: ^1.24.9 From df4b617aeee3aacefb95c786d445bad12ea68574 Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Mon, 17 Jun 2024 22:09:20 +0200 Subject: [PATCH 05/18] Updated dependencies --- melos.yaml | 1 + packages/dartness_generator/pubspec.yaml | 14 +++++++------- packages/dartness_server/pubspec.yaml | 14 ++++++-------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/melos.yaml b/melos.yaml index 1a77b4fd..3e2378fe 100644 --- a/melos.yaml +++ b/melos.yaml @@ -11,6 +11,7 @@ packages: scripts: get: melos exec --no-private -- dart pub get . analyze: melos exec --no-private -- dart analyze + upgrade: melos exec --no-private -- dart pub upgrade --major-versions format: melos exec --no-private -- dart format . format:check: dart format --set-exit-if-changed . diff --git a/packages/dartness_generator/pubspec.yaml b/packages/dartness_generator/pubspec.yaml index 07f81347..81e33f7e 100644 --- a/packages/dartness_generator/pubspec.yaml +++ b/packages/dartness_generator/pubspec.yaml @@ -10,16 +10,16 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - collection: ^1.18.0 + collection: ^1.19.0 build: ^2.4.1 - source_gen: ^1.4.0 - analyzer: ^6.3.0 - code_builder: ^4.7.0 + source_gen: ^1.5.0 + analyzer: ^6.5.0 + code_builder: ^4.10.0 dartness_server: path: ../dartness_server dev_dependencies: - lints: ^3.0.0 - build_runner: ^2.4.6 - test: ^1.24.9 + lints: ^4.0.0 + build_runner: ^2.4.11 + test: ^1.25.7 source_gen_test: ^1.0.6 diff --git a/packages/dartness_server/pubspec.yaml b/packages/dartness_server/pubspec.yaml index 43a38853..1a36c576 100644 --- a/packages/dartness_server/pubspec.yaml +++ b/packages/dartness_server/pubspec.yaml @@ -15,16 +15,14 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - collection: ^1.18.0 + collection: ^1.19.0 shelf: ^1.4.1 - shelf_plus: ^1.7.0 + shelf_plus: ^1.9.2 shelf_router: ^1.1.4 - injector: ^3.0.0 cron: ^0.6.0 dev_dependencies: - http: ^1.1.0 - lints: ^3.0.0 - test: ^1.24.9 - build_runner: ^2.4.6 - fake_async: ^1.3.1 \ No newline at end of file + http: ^1.2.1 + lints: ^4.0.0 + test: ^1.25.7 + build_runner: ^2.4.11 \ No newline at end of file From 0ec97a76d5f8547a57eadaf4161dd8d5aeb45303 Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Mon, 17 Jun 2024 22:11:21 +0200 Subject: [PATCH 06/18] Updated docs --- .../lib/src/configuration/schedule/scheduler.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart b/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart index d7c2461c..980aff7e 100644 --- a/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart +++ b/packages/dartness_server/lib/src/configuration/schedule/scheduler.dart @@ -1,4 +1,4 @@ -/// Represents an annotation for scheduling tasks with various parameters. +/// Represents an annotation for classes with scheduling tasks. class Scheduler { const Scheduler(); } From 852454f0987c2ec4378f33c5a4834b0b416675cc Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Wed, 19 Jun 2024 21:35:41 +0200 Subject: [PATCH 07/18] Updated melos version --- examples/dartness_flutter_melos/pubspec.yaml | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/dartness_flutter_melos/pubspec.yaml b/examples/dartness_flutter_melos/pubspec.yaml index b76ed56d..1ba30181 100644 --- a/examples/dartness_flutter_melos/pubspec.yaml +++ b/examples/dartness_flutter_melos/pubspec.yaml @@ -10,4 +10,4 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - melos: ^3.2.0 + melos: ^6.1.0 diff --git a/pubspec.yaml b/pubspec.yaml index 130fa14b..5b935533 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,4 +10,4 @@ environment: sdk: ">=3.0.0 <4.0.0" dependencies: - melos: ^3.1.1 + melos: ^6.1.0 From f3fa6eab5a13b237be4c7afa2cb3d87a15b7ebd5 Mon Sep 17 00:00:00 2001 From: Ricardo Romero Date: Wed, 19 Jun 2024 21:37:30 +0200 Subject: [PATCH 08/18] Updated dart docs --- .../doc/api/__404error.html | 9 +- .../doc/api/builder/application.html | 10 +- .../api/builder/builder-library-sidebar.html | 2 + .../doc/api/builder/builder-library.html | 56 ++- .../doc/api/builder/controller.html | 10 +- .../doc/api/builder/errorHandler.html | 10 +- .../doc/api/builder/scheduler.html | 129 ++++++ .../dartness_generator-library-sidebar.html | 1 + .../dartness_generator-library.html | 35 +- .../dartness_generator/doc/api/index.html | 9 +- .../dartness_generator/doc/api/index.json | 2 +- .../dartness_generator/doc/api/search.html | 9 +- .../doc/api/static-assets/readme.md | 18 +- .../doc/api/static-assets/styles.css | 102 ++++- .../dartness_server/doc/api/__404error.html | 11 +- .../Injectable-class-sidebar.html | 26 ++ .../api/configuration/Injectable-class.html | 232 +++++++++++ .../configuration/Injectable/Injectable.html | 129 ++++++ .../configuration-library-sidebar.html | 13 + .../configuration/configuration-library.html | 154 ++++++++ .../dartness/Application-class-sidebar.html | 3 + .../doc/api/dartness/Application-class.html | 50 +-- .../api/dartness/Application/Application.html | 15 +- .../doc/api/dartness/Application/module.html | 54 +-- .../doc/api/dartness/Application/options.html | 54 +-- .../api/dartness/Dartness-class-sidebar.html | 3 + .../doc/api/dartness/Dartness-class.html | 44 ++- .../doc/api/dartness/Dartness/Dartness.html | 10 +- .../doc/api/dartness/Dartness/create.html | 24 +- .../api/dartness/Inject-class-sidebar.html | 3 + .../doc/api/dartness/Inject-class.html | 47 +-- .../doc/api/dartness/Inject/Inject.html | 12 +- .../doc/api/dartness/Inject/name.html | 54 +-- .../InstanceRegister-class-sidebar.html | 3 + .../api/dartness/InstanceRegister-class.html | 47 +-- .../dartness/InstanceRegister/instance.html | 54 +-- .../dartness/InstanceRegister/register.html | 24 +- .../dartness/InstanceRegister/resolve.html | 24 +- .../dartness/dartness-library-sidebar.html | 1 + .../doc/api/dartness/dartness-library.html | 45 ++- .../exception/CatchError-class-sidebar.html | 3 + .../doc/api/exception/CatchError-class.html | 47 +-- .../api/exception/CatchError/CatchError.html | 12 +- .../doc/api/exception/CatchError/errors.html | 54 +-- .../DartnessCatchError-class-sidebar.html | 3 + .../exception/DartnessCatchError-class.html | 50 +-- .../DartnessCatchError.html | 12 +- .../DartnessCatchError/canHandle.html | 24 +- .../DartnessCatchError/errorTypes.html | 54 +-- .../exception/DartnessCatchError/handler.html | 54 +-- ...tnessCatchErrorRegister-class-sidebar.html | 3 + .../DartnessCatchErrorRegister-class.html | 44 ++- .../DartnessCatchErrorRegister.html | 10 +- .../addCatchError.html | 24 +- .../DartnessCatchErrorRegister/handle.html | 24 +- .../DartnessErrorHandler-class-sidebar.html | 3 + .../exception/DartnessErrorHandler-class.html | 50 +-- .../DartnessErrorHandler.html | 12 +- .../DartnessErrorHandler/catchErrors.html | 54 +-- .../DartnessErrorHandler/errorHandler.html | 54 +-- .../exception/ErrorHandler-class-sidebar.html | 3 + .../doc/api/exception/ErrorHandler-class.html | 44 ++- .../exception/ErrorHandler/ErrorHandler.html | 12 +- ...HttpStatusCodeException-class-sidebar.html | 3 + .../HttpStatusCodeException-class.html | 50 +-- .../HttpStatusCodeException.html | 12 +- .../HttpStatusCodeException/message.html | 54 +-- .../HttpStatusCodeException/statusCode.html | 54 +-- .../exception/exception-library-sidebar.html | 1 + .../doc/api/exception/exception-library.html | 49 ++- packages/dartness_server/doc/api/index.html | 25 +- packages/dartness_server/doc/api/index.json | 2 +- .../doc/api/modules/Module-class-sidebar.html | 3 + .../doc/api/modules/Module-class.html | 47 +-- .../doc/api/modules/Module/Module.html | 12 +- .../doc/api/modules/Module/metadata.html | 54 +-- .../modules/ModuleMetadata-class-sidebar.html | 3 + .../doc/api/modules/ModuleMetadata-class.html | 56 +-- .../ModuleMetadata/ModuleMetadata.html | 20 +- .../modules/ModuleMetadata/controllers.html | 54 +-- .../api/modules/ModuleMetadata/exports.html | 54 +-- .../api/modules/ModuleMetadata/imports.html | 54 +-- .../api/modules/ModuleMetadata/providers.html | 54 +-- .../ProviderMetadata-class-sidebar.html | 3 + .../api/modules/ProviderMetadata-class.html | 53 +-- .../ProviderMetadata/ProviderMetadata.html | 16 +- .../modules/ProviderMetadata/classType.html | 54 +-- .../api/modules/ProviderMetadata/name.html | 54 +-- .../modules/ProviderMetadata/useFactory.html | 54 +-- .../api/modules/modules-library-sidebar.html | 1 + .../doc/api/modules/modules-library.html | 43 +- .../doc/api/route/Bind-class-sidebar.html | 3 + .../doc/api/route/Bind-class.html | 74 ++-- .../doc/api/route/Bind/Bind.html | 12 +- .../doc/api/route/Bind/method.html | 54 +-- .../doc/api/route/Bind/path.html | 54 +-- .../doc/api/route/Body-class-sidebar.html | 3 + .../doc/api/route/Body-class.html | 44 ++- .../doc/api/route/Body/Body.html | 12 +- .../doc/api/route/Connect-class-sidebar.html | 3 + .../doc/api/route/Connect-class.html | 50 +-- .../doc/api/route/Connect/Connect.html | 12 +- .../api/route/Controller-class-sidebar.html | 3 + .../doc/api/route/Controller-class.html | 47 +-- .../doc/api/route/Controller/Controller.html | 12 +- .../doc/api/route/Controller/path.html | 54 +-- .../route/ControllerRoute-class-sidebar.html | 3 + .../doc/api/route/ControllerRoute-class.html | 62 +-- .../ControllerRoute/ControllerRoute.html | 19 +- .../api/route/ControllerRoute/handler.html | 54 +-- .../api/route/ControllerRoute/headers.html | 54 +-- .../api/route/ControllerRoute/httpCode.html | 54 +-- .../doc/api/route/ControllerRoute/method.html | 54 +-- .../doc/api/route/ControllerRoute/params.html | 54 +-- .../doc/api/route/ControllerRoute/path.html | 54 +-- .../DartnessController-class-sidebar.html | 3 + .../api/route/DartnessController-class.html | 50 +-- .../DartnessController.html | 12 +- .../route/DartnessController/controller.html | 54 +-- .../api/route/DartnessController/routes.html | 54 +-- .../route/DartnessParam-class-sidebar.html | 3 + .../doc/api/route/DartnessParam-class.html | 74 ++-- .../route/DartnessParam/DartnessParam.html | 23 +- .../api/route/DartnessParam/defaultValue.html | 54 +-- .../doc/api/route/DartnessParam/fromJson.html | 54 +-- .../doc/api/route/DartnessParam/isBody.html | 54 +-- .../doc/api/route/DartnessParam/isNamed.html | 54 +-- .../api/route/DartnessParam/isOptional.html | 54 +-- .../doc/api/route/DartnessParam/isPath.html | 54 +-- .../api/route/DartnessParam/isPositional.html | 54 +-- .../doc/api/route/DartnessParam/isQuery.html | 54 +-- .../doc/api/route/DartnessParam/name.html | 54 +-- .../doc/api/route/DartnessParam/type.html | 54 +-- .../route/DartnessRouter-class-sidebar.html | 3 + .../doc/api/route/DartnessRouter-class.html | 55 +-- .../route/DartnessRouter/DartnessRouter.html | 10 +- .../doc/api/route/DartnessRouter/add.html | 24 +- .../doc/api/route/DartnessRouter/router.html | 58 +-- .../DartnessRouterHandler-class-sidebar.html | 3 + .../route/DartnessRouterHandler-class.html | 44 ++- .../DartnessRouterHandler.html | 12 +- .../DartnessRouterHandler/handleRoute.html | 24 +- .../DefaultDartnessRouter-class-sidebar.html | 3 + .../route/DefaultDartnessRouter-class.html | 47 +-- .../DefaultDartnessRouter.html | 14 +- .../api/route/DefaultDartnessRouter/add.html | 24 +- .../route/DefaultDartnessRouter/router.html | 58 +-- .../doc/api/route/Delete-class-sidebar.html | 3 + .../doc/api/route/Delete-class.html | 50 +-- .../doc/api/route/Delete/Delete.html | 12 +- .../doc/api/route/Get-class-sidebar.html | 3 + .../doc/api/route/Get-class.html | 50 +-- .../doc/api/route/Get/Get.html | 12 +- .../doc/api/route/Head-class-sidebar.html | 3 + .../doc/api/route/Head-class.html | 50 +-- .../doc/api/route/Head/Head.html | 12 +- .../doc/api/route/Header-class-sidebar.html | 3 + .../doc/api/route/Header-class.html | 50 +-- .../doc/api/route/Header/Header.html | 12 +- .../doc/api/route/Header/key.html | 54 +-- .../doc/api/route/Header/value.html | 54 +-- .../doc/api/route/Headers-class-sidebar.html | 3 + .../doc/api/route/Headers-class.html | 47 +-- .../doc/api/route/Headers/Headers.html | 12 +- .../doc/api/route/Headers/values.html | 54 +-- .../doc/api/route/HttpCode-class-sidebar.html | 3 + .../doc/api/route/HttpCode-class.html | 47 +-- .../doc/api/route/HttpCode/HttpCode.html | 12 +- .../doc/api/route/HttpCode/code.html | 54 +-- .../doc/api/route/Options-class-sidebar.html | 3 + .../doc/api/route/Options-class.html | 50 +-- .../doc/api/route/Options/Options.html | 12 +- .../doc/api/route/Patch-class-sidebar.html | 3 + .../doc/api/route/Patch-class.html | 50 +-- .../doc/api/route/Patch/Patch.html | 12 +- .../api/route/PathParam-class-sidebar.html | 3 + .../doc/api/route/PathParam-class.html | 47 +-- .../doc/api/route/PathParam/PathParam.html | 12 +- .../doc/api/route/PathParam/name.html | 54 +-- .../doc/api/route/Post-class-sidebar.html | 3 + .../doc/api/route/Post-class.html | 50 +-- .../doc/api/route/Post/Post.html | 12 +- .../doc/api/route/Put-class-sidebar.html | 3 + .../doc/api/route/Put-class.html | 50 +-- .../doc/api/route/Put/Put.html | 12 +- .../api/route/QueryParam-class-sidebar.html | 3 + .../doc/api/route/QueryParam-class.html | 47 +-- .../doc/api/route/QueryParam/QueryParam.html | 12 +- .../doc/api/route/QueryParam/name.html | 54 +-- .../doc/api/route/Trace-class-sidebar.html | 3 + .../doc/api/route/Trace-class.html | 50 +-- .../doc/api/route/Trace/Trace.html | 12 +- .../doc/api/route/route-library-sidebar.html | 1 + .../doc/api/route/route-library.html | 83 ++-- .../api/schedule/Scheduled-class-sidebar.html | 27 ++ .../doc/api/schedule/Scheduled-class.html | 233 +++++++++++ .../doc/api/schedule/Scheduled/Scheduled.html | 130 +++++++ .../doc/api/schedule/Scheduled/cron.html | 128 ++++++ .../api/schedule/Scheduler-class-sidebar.html | 26 ++ .../doc/api/schedule/Scheduler-class.html | 221 +++++++++++ .../doc/api/schedule/Scheduler/Scheduler.html | 124 ++++++ .../SchedulerManager-class-sidebar.html | 30 ++ .../api/schedule/SchedulerManager-class.html | 272 +++++++++++++ .../SchedulerManager/SchedulerManager.html | 125 ++++++ .../api/schedule/SchedulerManager/cron.html | 125 ++++++ .../SchedulerManager/cronExpression.html | 125 ++++++ .../api/schedule/SchedulerManager/start.html | 137 +++++++ .../api/schedule/SchedulerManager/stop.html | 133 +++++++ .../api/schedule/TimeUnit-enum-sidebar.html | 37 ++ .../doc/api/schedule/TimeUnit.html | 366 ++++++++++++++++++ .../doc/api/schedule/TimeUnit/TimeUnit.html | 120 ++++++ .../schedule/TimeUnit/values-constant.html | 124 ++++++ .../schedule/schedule-library-sidebar.html | 17 + .../doc/api/schedule/schedule-library.html | 184 +++++++++ packages/dartness_server/doc/api/search.html | 11 +- ...tnessApplicationOptions-class-sidebar.html | 3 + .../DartnessApplicationOptions-class.html | 53 +-- .../DartnessApplicationOptions.html | 18 +- .../internetAddress.html | 58 +-- .../logRequest.html | 58 +-- .../DartnessApplicationOptions/port.html | 58 +-- .../DartnessInterceptor-class-sidebar.html | 3 + .../api/server/DartnessInterceptor-class.html | 52 +-- .../DartnessInterceptor.html | 10 +- .../server/DartnessInterceptor/onError.html | 24 +- .../server/DartnessInterceptor/onRequest.html | 24 +- .../DartnessInterceptor/onResponse.html | 24 +- .../DartnessMiddleware-class-sidebar.html | 3 + .../api/server/DartnessMiddleware-class.html | 44 ++- .../DartnessMiddleware.html | 10 +- .../api/server/DartnessMiddleware/handle.html | 24 +- .../DartnessPipeline-class-sidebar.html | 3 + .../api/server/DartnessPipeline-class.html | 52 +-- .../DartnessPipeline/DartnessPipeline.html | 10 +- .../DartnessPipeline/addErrorHandler.html | 24 +- .../server/DartnessPipeline/addHandler.html | 24 +- .../DartnessPipeline/addInterceptor.html | 24 +- .../DartnessPipeline/addMiddleware.html | 24 +- .../server/DartnessRequest-class-sidebar.html | 3 + .../doc/api/server/DartnessRequest-class.html | 56 +-- .../DartnessRequest.fromShelf.html | 10 +- .../DartnessRequest/DartnessRequest.html | 26 +- .../doc/api/server/DartnessRequest/body.html | 24 +- .../doc/api/server/DartnessRequest/bytes.html | 24 +- .../api/server/DartnessRequest/headers.html | 58 +-- .../api/server/DartnessRequest/method.html | 58 +-- .../server/DartnessRequest/requestedUri.html | 58 +-- .../doc/api/server/DartnessRequest/url.html | 58 +-- .../DartnessResponse-class-sidebar.html | 3 + .../api/server/DartnessResponse-class.html | 50 +-- .../DartnessResponse.fromShelf.html | 10 +- .../DartnessResponse/DartnessResponse.html | 24 +- .../doc/api/server/DartnessResponse/body.html | 24 +- .../api/server/DartnessResponse/bytes.html | 24 +- .../api/server/DartnessResponse/headers.html | 58 +-- .../server/DartnessResponse/statusCode.html | 58 +-- .../server/DartnessServer-class-sidebar.html | 3 + .../doc/api/server/DartnessServer-class.html | 52 +-- .../server/DartnessServer/DartnessServer.html | 10 +- .../server/DartnessServer/addController.html | 24 +- .../DartnessServer/addErrorHandler.html | 24 +- .../server/DartnessServer/addInterceptor.html | 24 +- .../server/DartnessServer/addMiddleware.html | 24 +- .../api/server/DartnessServer/getAddress.html | 24 +- .../api/server/DartnessServer/getPort.html | 24 +- .../doc/api/server/DartnessServer/start.html | 24 +- .../doc/api/server/DartnessServer/stop.html | 24 +- ...DefaultDartnessPipeline-class-sidebar.html | 3 + .../server/DefaultDartnessPipeline-class.html | 44 ++- .../DefaultDartnessPipeline.html | 17 +- .../addErrorHandler.html | 24 +- .../DefaultDartnessPipeline/addHandler.html | 24 +- .../addInterceptor.html | 24 +- .../addMiddleware.html | 24 +- .../DefaultDartnessServer-class-sidebar.html | 3 + .../server/DefaultDartnessServer-class.html | 50 +-- .../DefaultDartnessServer.html | 15 +- .../DefaultDartnessServer/addController.html | 24 +- .../addErrorHandler.html | 24 +- .../DefaultDartnessServer/addInterceptor.html | 24 +- .../DefaultDartnessServer/addMiddleware.html | 24 +- .../DefaultDartnessServer/controllers.html | 58 +-- .../DefaultDartnessServer/getAddress.html | 24 +- .../server/DefaultDartnessServer/getPort.html | 24 +- .../DefaultDartnessServer/isStarted.html | 58 +-- .../server/DefaultDartnessServer/start.html | 24 +- .../server/DefaultDartnessServer/stop.html | 24 +- .../LogRequestsInterceptor-class-sidebar.html | 3 + .../server/LogRequestsInterceptor-class.html | 56 +-- .../LogRequestsInterceptor.html | 10 +- .../server/LogRequestsInterceptor/method.html | 54 +-- .../LogRequestsInterceptor/onError.html | 24 +- .../LogRequestsInterceptor/onRequest.html | 24 +- .../LogRequestsInterceptor/onResponse.html | 24 +- .../LogRequestsInterceptor/startTime.html | 54 +-- .../server/LogRequestsInterceptor/uri.html | 54 +-- .../server/LogRequestsInterceptor/watch.html | 54 +-- .../api/server/server-library-sidebar.html | 1 + .../doc/api/server/server-library.html | 57 +-- .../doc/api/static-assets/readme.md | 18 +- .../doc/api/static-assets/styles.css | 102 ++++- .../src/configuration/schedule/scheduled.dart | 2 +- .../schedule/scheduler_manager.dart | 5 +- 303 files changed, 7879 insertions(+), 3809 deletions(-) create mode 100644 packages/dartness_generator/doc/api/builder/scheduler.html create mode 100644 packages/dartness_server/doc/api/configuration/Injectable-class-sidebar.html create mode 100644 packages/dartness_server/doc/api/configuration/Injectable-class.html create mode 100644 packages/dartness_server/doc/api/configuration/Injectable/Injectable.html create mode 100644 packages/dartness_server/doc/api/configuration/configuration-library-sidebar.html create mode 100644 packages/dartness_server/doc/api/configuration/configuration-library.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduled-class-sidebar.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduled-class.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduled/Scheduled.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduled/cron.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduler-class-sidebar.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduler-class.html create mode 100644 packages/dartness_server/doc/api/schedule/Scheduler/Scheduler.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager-class-sidebar.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager-class.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager/SchedulerManager.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager/cron.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager/cronExpression.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager/start.html create mode 100644 packages/dartness_server/doc/api/schedule/SchedulerManager/stop.html create mode 100644 packages/dartness_server/doc/api/schedule/TimeUnit-enum-sidebar.html create mode 100644 packages/dartness_server/doc/api/schedule/TimeUnit.html create mode 100644 packages/dartness_server/doc/api/schedule/TimeUnit/TimeUnit.html create mode 100644 packages/dartness_server/doc/api/schedule/TimeUnit/values-constant.html create mode 100644 packages/dartness_server/doc/api/schedule/schedule-library-sidebar.html create mode 100644 packages/dartness_server/doc/api/schedule/schedule-library.html diff --git a/packages/dartness_generator/doc/api/__404error.html b/packages/dartness_generator/doc/api/__404error.html index 6403fc20..f92452bc 100644 --- a/packages/dartness_generator/doc/api/__404error.html +++ b/packages/dartness_generator/doc/api/__404error.html @@ -4,7 +4,6 @@ - dartness_generator - Dart API docs @@ -12,7 +11,7 @@ - + @@ -35,14 +34,14 @@ -
+
diff --git a/packages/dartness_generator/doc/api/builder/application.html b/packages/dartness_generator/doc/api/builder/application.html index 20ecadd5..cab892f7 100644 --- a/packages/dartness_generator/doc/api/builder/application.html +++ b/packages/dartness_generator/doc/api/builder/application.html @@ -11,7 +11,7 @@ - + @@ -29,21 +29,21 @@ menu
application
-
+
diff --git a/packages/dartness_generator/doc/api/builder/builder-library-sidebar.html b/packages/dartness_generator/doc/api/builder/builder-library-sidebar.html index 11645313..76f02844 100644 --- a/packages/dartness_generator/doc/api/builder/builder-library-sidebar.html +++ b/packages/dartness_generator/doc/api/builder/builder-library-sidebar.html @@ -4,10 +4,12 @@ +
  • Functions
  • application
  • controller
  • errorHandler
  • +
  • scheduler
  • diff --git a/packages/dartness_generator/doc/api/builder/builder-library.html b/packages/dartness_generator/doc/api/builder/builder-library.html index 1983f915..bdfb79cd 100644 --- a/packages/dartness_generator/doc/api/builder/builder-library.html +++ b/packages/dartness_generator/doc/api/builder/builder-library.html @@ -11,7 +11,7 @@ - + @@ -29,36 +29,42 @@ menu
    builder
    -
    +
    -
    +
    + +
    -
    -

    builder library + +

    + builder + library -

    + + +
    @@ -68,11 +74,13 @@

    builder library + +

    Functions

    -
    +
    application(BuilderOptions options) Builder @@ -85,7 +93,7 @@

    Functions

    -
    +
    controller(BuilderOptions options) Builder @@ -98,7 +106,7 @@

    Functions

    -
    +
    errorHandler(BuilderOptions options) Builder @@ -109,6 +117,19 @@

    Functions

    + + +
    + scheduler(BuilderOptions options) + Builder + + + +
    +
    + + +
    @@ -116,7 +137,6 @@

    Functions

    -