Conversation
There was a problem hiding this comment.
Pull request overview
This PR advances the “Adaptive Reminder Service” proposal by extending Orleans reminders with cron-based scheduling and adaptive metadata (next-due, last-fire, priority/action), adding management/paging APIs and iterators, and updating multiple storage providers plus tests to round-trip the new fields.
Changes:
- Add cron scheduling support and adaptive reminder metadata (CronExpression, NextDueUtc, LastFireUtc, Priority, Action) across reminder contracts and storage providers.
- Introduce reminder management paging/filtering APIs plus iterator/extension helpers and new validation/registration conveniences (including
[RegisterReminder]activation registration). - Update timer infrastructure and expand test coverage across NonSilo + provider-specific reminder table tests, plus add SQL migrations.
Reviewed changes
Copilot reviewed 86 out of 86 changed files in this pull request and generated 22 comments.
Show a summary per file
| File | Description |
|---|---|
| test/TesterInternal/RemindersTest/ReminderTableTestsBase.cs | Adds round-trip tests for cron + adaptive fields in reminder table providers. |
| test/NonSilo.Tests/Reminders/SiloBuilderReminderExtensionsTests.cs | Verifies DI registrations for legacy vs adaptive reminder services and options wiring. |
| test/NonSilo.Tests/Reminders/ReminderStressTests.cs | Adds high-load paging/iterator stress coverage for reminder management APIs. |
| test/NonSilo.Tests/Reminders/ReminderRegistryValidationTests.cs | Adds validation tests for new registry overloads (cron/absolute/priority/action). |
| test/NonSilo.Tests/Reminders/ReminderRegistrationExtensionsTests.cs | Tests typed cron builder/expression extension overloads for registry/service/grain. |
| test/NonSilo.Tests/Reminders/ReminderOptionsValidatorTests.cs | Adds validation coverage for new adaptive reminder options. |
| test/NonSilo.Tests/Reminders/ReminderManagementGrainExtensionsTests.cs | Tests paging enumeration extension helpers and iterator factory. |
| test/NonSilo.Tests/Reminders/ReminderIteratorTests.cs | Tests ReminderIterator paging behavior and large-streaming scenario. |
| test/NonSilo.Tests/Reminders/RegisterReminderAttributeTests.cs | Tests [RegisterReminder] attribute ctor behavior and validation. |
| test/NonSilo.Tests/Reminders/RegisterReminderActivationConfiguratorProviderTests.cs | Tests activation-time reminder registration behavior using lifecycle hooks. |
| test/NonSilo.Tests/NonSilo.Tests.csproj | Adds project reference to Orleans.Reminders for new reminder APIs/tests. |
| test/Grains/TestGrainInterfaces/IReminderTestGrain2.cs | Extends test grain interface to exercise new reminder options/cron/raw upserts. |
| test/Extensions/TesterAzureUtils/AzureRemindersTableTests.cs | Adds Azure reminder table round-trip tests for cron + adaptive fields. |
| test/Extensions/TesterAdoNet/StorageTests/DbExtensionsInt32ConversionTests.cs | Adds coverage for widened GetInt32 conversions and overflow behavior. |
| test/Extensions/TesterAdoNet/Reminders/SqlServerRemindersTableTests.cs | Adds SQL Server reminder table round-trip tests for new fields. |
| test/Extensions/TesterAdoNet/Reminders/PostgreSqlRemindersTableTests.cs | Adds PostgreSQL reminder table round-trip tests for new fields. |
| test/Extensions/TesterAdoNet/Reminders/MySqlRemindersTableTests.cs | Adds MySQL reminder table round-trip tests for new fields. |
| test/Extensions/Tester.Redis/Reminders/RedisReminderTableTests.cs | Adds Redis reminder table round-trip tests for new fields. |
| test/Extensions/Tester.Redis/Reminders/RedisReminderTableSerializationTests.cs | Adds Redis serialization/parsing tests for enums + temporal formatting. |
| test/Extensions/AWSUtils.Tests/Reminder/DynamoDBRemindersTableTests.cs | Adds DynamoDB reminder table round-trip tests for new fields. |
| test/Extensions/AWSUtils.Tests/Reminder/DynamoDBReminderTableEnumParsingTests.cs | Adds DynamoDB enum parsing tests for missing/invalid/valid values. |
| src/Redis/Orleans.Reminders.Redis/Storage/RedisReminderTable.cs | Extends Redis reminder payload format to include cron/temporal/enums with robust parsing. |
| src/Orleans.Runtime/Timers/AsyncTimerFactory.cs | Adds TimeProvider support to async timers via factory injection. |
| src/Orleans.Runtime/Timers/AsyncTimer.cs | Switches timer time sources/delays to TimeProvider for testability/determinism. |
| src/Orleans.Reminders/Timers/ReminderQueryFilter.cs | Adds server-side filter DTO + status mask enum for management paging queries. |
| src/Orleans.Reminders/Timers/ReminderManagementPage.cs | Introduces page DTO for reminder management results. |
| src/Orleans.Reminders/Timers/ReminderManagementGrainExtensions.cs | Adds IAsyncEnumerable helpers for paging through management APIs. |
| src/Orleans.Reminders/Timers/ReminderIterator.cs | Implements iterator facade over reminder management paging APIs. |
| src/Orleans.Reminders/Timers/IReminderRegistry.cs | Adds new registry overloads (absolute due, cron, priority/action). |
| src/Orleans.Reminders/Timers/IReminderManagementGrain.cs | Adds management grain interface with paging/filtering and administrative operations. |
| src/Orleans.Reminders/Timers/IReminderIterator.cs | Adds iterator interface for streaming pages without full materialization. |
| src/Orleans.Reminders/Timers/IRemindable.cs | Adds schedule kind + priority/action + cron surface area to reminder contracts. |
| src/Orleans.Reminders/SystemTargetInterfaces/IReminderTable.cs | Extends ReminderEntry + ReminderData to carry cron/temporal/enums. |
| src/Orleans.Reminders/SystemTargetInterfaces/IReminderService.cs | Adds new reminder service overloads (absolute due, cron, priority/action). |
| src/Orleans.Reminders/ReminderService/ReminderRegistry.cs | Adds validation + new overloads for cron/absolute due and priority/action. |
| src/Orleans.Reminders/ReminderService/RegisterReminderActivationConfiguratorProvider.cs | Adds activation-time [RegisterReminder] support via lifecycle observer. |
| src/Orleans.Reminders/ReminderService/LocalReminderService.cs | Adds TimeProvider usage, cron scheduling support, adaptive fields, and legacy suppression behavior. |
| src/Orleans.Reminders/ReminderService/AdaptiveReminderServiceRegistrationMarker.cs | Adds DI marker for suppressing legacy reminder service when adaptive is enabled. |
| src/Orleans.Reminders/ReminderCronRegistrationExtensions.cs | Adds typed-cron overloads for registry/service cron registration. |
| src/Orleans.Reminders/RegisterReminderAttribute.cs | Introduces [RegisterReminder] attribute with validation and priority/action support. |
| src/Orleans.Reminders/Orleans.Reminders.csproj | Enables unsafe blocks to support cron parsing implementation. |
| src/Orleans.Reminders/Options/ReminderOptions.cs | Adds adaptive options (look-ahead, poll interval, bucket size, priority toggle, legacy toggle) + validation. |
| src/Orleans.Reminders/Hosting/SiloBuilderReminderExtensions.cs | Adds overloads to configure ReminderOptions and wires activation configurator provider. |
| src/Orleans.Reminders/Hosting/SiloBuilderAdaptiveReminderExtensions.cs | Adds AddAdaptiveReminderService() DI wiring + idempotency behavior. |
| src/Orleans.Reminders/GrainReminderExtensions.cs | Adds reminder registration overloads for absolute due and priority/action. |
| src/Orleans.Reminders/GrainReminderCronExtensions.cs | Adds grain-level cron reminder registration extension methods. |
| src/Orleans.Reminders/Cron/ReminderCronExpression.cs | Adds typed cron expression wrapper with parsing/format detection and UTC guards. |
| src/Orleans.Reminders/Cron/ReminderCronBuilder.cs | Adds helper builder for common cron schedules and validation. |
| src/Orleans.Reminders/Cron/Internal/TimeZoneHelper.cs | Adds internal DST ambiguity helpers for cron scheduling. |
| src/Orleans.Reminders/Cron/Internal/ReminderCronParser.cs | Adds internal cron parsing helper (5/6 field detection) for runtime use. |
| src/Orleans.Reminders/Cron/Internal/LanguageFeatures.cs | Adds polyfills for compiler/runtime attributes for older target frameworks. |
| src/Orleans.Reminders/Cron/Internal/DateTimeHelper.cs | Adds internal DateTimeOffset rounding helpers for cron logic. |
| src/Orleans.Reminders/Cron/Internal/CronFormatException.cs | Adds custom exception for cron format failures. |
| src/Orleans.Reminders/Cron/Internal/CronFormat.cs | Adds internal enum controlling cron parse format options. |
| src/Orleans.Reminders/Cron/Internal/CronField.cs | Adds cron field metadata (ranges/names) used by parser. |
| src/Orleans.Reminders/Cron/Internal/CronExpressionFlag.cs | Adds internal flags to represent cron expression modifiers. |
| src/Orleans.Reminders/Cron/Internal/CalendarHelper.cs | Adds internal calendar helpers for cron evaluation. |
| src/Orleans.Reminders/Constants/ReminderOptionsDefaults.cs | Adds defaults for look-ahead, poll interval, and bucket size. |
| src/Azure/Shared/Storage/AzureTableDataManager.cs | Adds optional update mode to table upsert, enabling replace semantics when needed. |
| src/Azure/Orleans.Reminders.Cosmos/Models/ReminderEntity.cs | Adds cron/temporal/enums fields to Cosmos reminder entity model. |
| src/Azure/Orleans.Reminders.Cosmos/CosmosReminderTable.cs | Reads/writes cron/temporal/enums fields for Cosmos reminder storage. |
| src/Azure/Orleans.Reminders.AzureStorage/Storage/RemindersTableManager.cs | Adds columns for cron/temporal/enums and switches upsert to Replace mode. |
| src/Azure/Orleans.Reminders.AzureStorage/Storage/AzureBasedReminderTable.cs | Adds parsing/serialization for new fields, with tighter exception handling. |
| src/AdoNet/Shared/Storage/RelationalOrleansQueries.cs | Reads new reminder columns and extends upsert to persist new fields/enums. |
| src/AdoNet/Shared/Storage/DbStoredQueries.cs | Adds new column parameter bindings and simplifies version read using GetInt32. |
| src/AdoNet/Shared/Storage/DbExtensions.cs | Expands GetInt32 conversion support with invariant conversion and nullable variant. |
| src/AdoNet/Orleans.Reminders.AdoNet/SQLServer-Reminders.sql | Adds new columns and index + updates stored queries for SQL Server provider. |
| src/AdoNet/Orleans.Reminders.AdoNet/ReminderService/AdoNetReminderTable.cs | Passes new reminder fields through to relational upsert. |
| src/AdoNet/Orleans.Reminders.AdoNet/PostgreSQL-Reminders.sql | Adds new columns/index and updates upsert function/queries for PostgreSQL provider. |
| src/AdoNet/Orleans.Reminders.AdoNet/Oracle-Reminders.sql | Adds new columns/index and updates function/queries for Oracle provider. |
| src/AdoNet/Orleans.Reminders.AdoNet/MySQL-Reminders.sql | Adds new columns/index and updates stored queries for MySQL provider. |
| src/AdoNet/Orleans.Reminders.AdoNet/Migrations/SQLServer-Reminders-10.0.0.sql | Adds migration script for pre-10.0.0 SQL Server reminder tables. |
| src/AdoNet/Orleans.Reminders.AdoNet/Migrations/PostgreSQL-Reminders-10.0.0.sql | Adds migration script for pre-10.0.0 PostgreSQL reminder tables. |
| src/AdoNet/Orleans.Reminders.AdoNet/Migrations/Oracle-Reminders-10.0.0.sql | Adds migration script for pre-10.0.0 Oracle reminder tables. |
| src/AdoNet/Orleans.Reminders.AdoNet/Migrations/MySQL-Reminders-10.0.0.sql | Adds migration script for pre-10.0.0 MySQL reminder tables. |
| src/AWS/Orleans.Reminders.DynamoDB/Reminders/DynamoDBReminderTable.cs | Adds cron/temporal/enums read/write behavior with robust parsing defaults. |
Comments suppressed due to low confidence (1)
test/Grains/TestInternalGrains/ReminderTestGrain2.cs:287
- The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
The format string ignores this supplied value.
src/Orleans.Reminders/ReminderService/AdaptiveReminderService.cs
Outdated
Show resolved
Hide resolved
test/NonSilo.Tests/Reminders/AdaptiveReminderServiceFunctionalTests.cs
Outdated
Show resolved
Hide resolved
test/NonSilo.Tests/Reminders/AdaptiveReminderServiceFunctionalTests.cs
Outdated
Show resolved
Hide resolved
|
Do we want to be changing the existing Reminder interface as opposed to creating a new one that can exist side by side (with perhaps a separate migration process to move existing reminder instances to the new interface)? Also, I had assumed that new reminders would be built on top of the new DurableJob construct. Was that an expectation or have I misremembered? |
|
@ReubenBond I don't know much about DurableJob but I would love to help here, becase I really want reminders with cron so bad =) |
|
@ReubenBond @rkargMsft shoud I move this into separate project? or just add separete exteions like UseAdaptiveReminders and then add extra extions for registeter for remainders? |
# Conflicts: # test/Extensions/Orleans.AWS.Tests/Reminder/DynamoDBReminderTableEnumParsingTests.cs # test/Extensions/Orleans.AdoNet.Tests/StorageTests/DbExtensionsInt32ConversionTests.cs # test/Extensions/Orleans.Redis.Tests/Reminders/RedisReminderTableSerializationTests.cs # test/Orleans.Core.Tests/Orleans.Core.Tests.csproj # test/Orleans.Runtime.Internal.Tests/TimerTests/AdaptiveReminderTests_TableGrain.cs
|
@pentp comments are resolved Also I gives me an idea to add one more propery TimeZone - in case I want to run remainder each 9 am each morneing in ET time. I found this is usfull. what do you think? |
|
@copilot review |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 138 out of 138 changed files in this pull request and generated 15 comments.
You can also share your feedback on Copilot code review. Take the survey.
Adaptive Reminder Service - Proposal #9586
Microsoft Reviewers: Open in CodeFlow
Reminders v2: split legacy reminders from the new AdvancedReminders stack
Summary
This PR restores the legacy
Orleans.Reminders*stack to its baseline-compatible shape and moves the new reminders work into a separate package family:Microsoft.Orleans.AdvancedReminders*.The new stack lives alongside legacy reminders instead of replacing them in-place.
What changed
Orleans.Reminders*packages to the legacy reminder model for compatibility.Microsoft.Orleans.AdvancedReminderscore package inOrleans.AdvancedReminders.Microsoft.Orleans.AdvancedReminders.AzureStorageMicrosoft.Orleans.AdvancedReminders.CosmosMicrosoft.Orleans.AdvancedReminders.DynamoDBMicrosoft.Orleans.AdvancedReminders.RedisMicrosoft.Orleans.AdvancedReminders.AdoNetOrleans.AdvancedReminders.Cron, including:TimeOnly/TimeSpanbuilder overloadsTimeZoneInfooverloads alongsideInTimeZone(...)ReminderScheduleoverloads so grain code can use the same schedule abstraction as the registry/service APIs.SkipandNotifyshare the same non-fire path, while preservingFireImmediatelybehavior.CronParserlist parsing to avoid recursive stack growth on very large comma-separated expressions.Orleans.DurableJobs.DurableReminderswork toAdvancedRemindersacross packages, namespaces, tests, docs, and checked-in API surface files.src/api/*files so the public API matches the compiled assemblies.Public API shape
The new stack uses
Orleans.AdvancedRemindersnamespaces andAddAdvancedReminders()/Use*AdvancedReminderService(...)entry points.Legacy reminders remain available via the existing
Orleans.Remindersnamespaces andAddReminders()/Use*ReminderService(...)entry points.Testing
Added and updated focused coverage for the new stack, including:
Validated with:
dotnet build src/Orleans.AdvancedReminders/Orleans.AdvancedReminders.csprojdotnet test test/Orleans.Core.Tests/Orleans.Core.Tests.csproj --filter "FullyQualifiedName~UnitTests.AdvancedReminders"188/188onnet8.0188/188onnet10.0