From 71b3aa960238fa35fe2b4a094a5a388ad3adf697 Mon Sep 17 00:00:00 2001 From: krivchenko_kv Date: Wed, 15 Jan 2025 11:10:27 +0300 Subject: [PATCH] first commit Create dotnet.yml refolder sln move to src Update dotnet.yml refolder sln move to src Delete .vs directory --- .dockerignore | 30 ++ .github/workflows/dotnet.yml | 31 ++ .gitignore | 401 ++++++++++++++++- src/.gitignore | 400 +++++++++++++++++ src/Common.Properties.xml | 22 + src/Sa.Data.Cache/Sa.Data.Cache.csproj | 13 + src/Sa.Data.Cache/Setup.cs | 32 ++ src/Sa.Data.PostgreSql.Migration/ITodo.cs | 7 + .../Sa.Data.PostgreSql.Migration.csproj | 13 + .../IPgDataSourceSettingsBuilder.cs | 10 + .../Configuration/PgDataSourceSettings.cs | 6 + .../PgDataSourceSettingsBuilder.cs | 28 ++ src/Sa.Data.PostgreSql/GlobalSuppressions.cs | 8 + src/Sa.Data.PostgreSql/IPgDataSource.cs | 83 ++++ src/Sa.Data.PostgreSql/IPgDistributedLock.cs | 6 + src/Sa.Data.PostgreSql/PgDataSource.cs | 71 +++ src/Sa.Data.PostgreSql/PgDistributedLock.cs | 63 +++ src/Sa.Data.PostgreSql/Readme.md | 87 ++++ .../Sa.Data.PostgreSql.csproj | 13 + src/Sa.Data.PostgreSql/Setup.cs | 17 + src/Sa.Media/Sa.Media.csproj | 9 + src/Sa.Media/Wav/WavFile.cs | 404 ++++++++++++++++++ .../IOutboxPayloadMessage.cs | 18 + .../OutboxMessageAttribute.cs | 21 + src/Sa.Outbox.Attributes/PingMessage.cs | 10 + .../Sa.Outbox.Support.csproj | 9 + .../Commands/ErrorDeliveryCommand.cs | 58 +++ .../Commands/ExtendDeliveryCommand.cs | 32 ++ .../Commands/FinishDeliveryCommand.cs | 86 ++++ .../Commands/IErrorDeliveryCommand.cs | 11 + .../Commands/IExtendDeliveryCommand.cs | 7 + .../Commands/IFinishDeliveryCommand.cs | 6 + .../Commands/IOutboxBulkCommand.cs | 6 + .../Commands/IStartDeliveryCommand.cs | 6 + .../Commands/OutboxBulkCommand.cs | 70 +++ src/Sa.Outbox.PostgreSql/Commands/Setup.cs | 17 + .../Commands/SqlCacheSplitter.cs | 49 +++ .../Commands/StartDeliveryCommand.cs | 94 ++++ .../Configuration/IPgOutboxConfiguration.cs | 9 + .../Configuration/PgOutboxConfiguration.cs | 62 +++ .../Configuration/PgOutboxSettings.cs | 171 ++++++++ .../Configuration/Setup.cs | 19 + .../GlobalSuppressions.cs | 8 + .../IdGen/IIdGenerator.cs | 6 + src/Sa.Outbox.PostgreSql/IdGen/IdGenerator.cs | 6 + src/Sa.Outbox.PostgreSql/IdGen/Setup.cs | 14 + .../Interceptors/DeliveryJobInterceptor.cs | 18 + .../Interceptors/Setup.cs | 14 + .../Partitional/OutboxMigrationSupport.cs | 19 + src/Sa.Outbox.PostgreSql/Partitional/Setup.cs | 66 +++ src/Sa.Outbox.PostgreSql/Readme.md | 118 +++++ .../Repository/DeliveryRepository.cs | 47 ++ .../Repository/IMsgTypeRepository.cs | 7 + .../Repository/IOutboxPartRepository.cs | 11 + .../Repository/MsgTypeRepository.cs | 24 ++ .../Repository/OutboxPartRepository.cs | 42 ++ .../Repository/OutboxRepository.cs | 18 + src/Sa.Outbox.PostgreSql/Repository/Setup.cs | 16 + .../Sa.Outbox.PostgreSql.csproj | 18 + .../Serialization/IOutboxMessageSerializer.cs | 12 + .../Serialization/OutboxMessageSerializer.cs | 56 +++ .../Serialization/Setup.cs | 14 + src/Sa.Outbox.PostgreSql/Setup.cs | 40 ++ src/Sa.Outbox.PostgreSql/SqlOutboxTemplate.cs | 260 +++++++++++ .../TypeHashResolve/IMsgTypeCache.cs | 9 + .../TypeHashResolve/IMsgTypeHashResolver.cs | 7 + .../TypeHashResolve/MsgTypeCache.cs | 77 ++++ .../TypeHashResolve/MsgTypeHashResolver.cs | 44 ++ .../TypeHashResolve/Setup.cs | 23 + .../Configuration/DeliveryBuilder.cs | 14 + .../Configuration/IDeliveryBuilder.cs | 19 + src/Sa.Outbox/Configuration/IOutboxBuilder.cs | 19 + src/Sa.Outbox/Configuration/OutboxBuilder.cs | 34 ++ src/Sa.Outbox/Configuration/OutboxSettings.cs | 109 +++++ src/Sa.Outbox/Delivery/DeliveryCourier.cs | 70 +++ src/Sa.Outbox/Delivery/DeliveryProcessor.cs | 19 + src/Sa.Outbox/Delivery/DeliveryRelay.cs | 135 ++++++ src/Sa.Outbox/Delivery/IDeliveryCourier.cs | 6 + src/Sa.Outbox/Delivery/IDeliveryProcessor.cs | 6 + src/Sa.Outbox/Delivery/IDeliveryRelay.cs | 6 + src/Sa.Outbox/Delivery/Setup.cs | 25 ++ src/Sa.Outbox/DeliveryStatusCode.cs | 61 +++ src/Sa.Outbox/Exceptions/DeliveryException.cs | 8 + .../Exceptions/DeliveryPermanentException.cs | 6 + .../Exceptions/OutboxMessageException.cs | 16 + src/Sa.Outbox/GlobalSuppressions.cs | 9 + src/Sa.Outbox/IConsumer.cs | 25 ++ .../IOutboxMessagePluginPublisher.cs | 31 ++ src/Sa.Outbox/Job/DeliveryJob.cs | 19 + src/Sa.Outbox/Job/IOutboxJobInterceptor.cs | 7 + src/Sa.Outbox/Job/OutboxJobInterceptor.cs | 21 + src/Sa.Outbox/Job/Setup.cs | 56 +++ .../Partitional/IOutboxPartitionalSupport.cs | 25 ++ .../Partitional/IPartitionalSupportCache.cs | 15 + .../Partitional/OutboxPartitionalSupport.cs | 64 +++ .../Partitional/PartitionalSettings.cs | 26 ++ .../Partitional/PartitionalSupportCache.cs | 34 ++ src/Sa.Outbox/Partitional/Setup.cs | 27 ++ .../Publication/OutboxMessagePublisher.cs | 71 +++ .../Publication/OutboxMessageTypeHelper.cs | 29 ++ src/Sa.Outbox/Publication/Setup.cs | 13 + src/Sa.Outbox/Readme.md | 255 +++++++++++ .../Repositories/IDeliveryRepository.cs | 22 + src/Sa.Outbox/Repositories/IOutboxContext.cs | 93 ++++ .../Repositories/IOutboxRepository.cs | 17 + src/Sa.Outbox/Repositories/OutboxContext.cs | 65 +++ src/Sa.Outbox/Repositories/OutboxMessage.cs | 102 +++++ .../Repositories/OutboxMessageFilter.cs | 39 ++ src/Sa.Outbox/Sa.Outbox.csproj | 15 + src/Sa.Outbox/Setup.cs | 14 + .../Cache/IPartCache.cs | 10 + .../Cache/PartCache.cs | 78 ++++ .../Cache/PartCacheSettings.cs | 8 + src/Sa.Partitional.PostgreSql/Cache/Setup.cs | 26 ++ .../Cleaning/IPartCleanupService.cs | 26 ++ .../Cleaning/PartCleanupJob.cs | 11 + .../Cleaning/PartCleanupScheduleSettings.cs | 34 ++ .../Cleaning/PartCleanupService.cs | 27 ++ .../Cleaning/Setup.cs | 69 +++ .../Configuration/Builder/ISchemaBuilder.cs | 8 + .../Configuration/Builder/ISettingsBuilder.cs | 9 + .../Configuration/Builder/ITableBuilder.cs | 31 ++ .../Configuration/Builder/SchemaBuilder.cs | 19 + .../Configuration/Builder/SettingsBuilder.cs | 32 ++ .../Configuration/Builder/Setup.cs | 40 ++ .../Configuration/Builder/TableBuilder.cs | 125 ++++++ .../Configuration/IPartConfiguration.cs | 11 + .../Configuration/PartConfiguration.cs | 51 +++ .../GlobalSuppressions.cs | 9 + .../IPartitionManager.cs | 35 ++ .../Migration/IPartMigrationService.cs | 18 + .../Migration/MigrationJobConstance.cs | 7 + .../Migration/PartMigrationJob.cs | 11 + .../PartMigrationScheduleSettings.cs | 16 + .../Migration/PartMigrationService.cs | 59 +++ .../Migration/Setup.cs | 70 +++ src/Sa.Partitional.PostgreSql/Part.cs | 10 + src/Sa.Partitional.PostgreSql/PartByRange.cs | 20 + .../PartitionManager.cs | 23 + src/Sa.Partitional.PostgreSql/PgPartBy.cs | 82 ++++ src/Sa.Partitional.PostgreSql/Readme.md | 226 ++++++++++ .../Repositories/IPartRepository.cs | 27 ++ .../Repositories/PartRepository.cs | 209 +++++++++ .../Repositories/Setup.cs | 13 + .../Sa.Partitional.PostgreSql.csproj | 15 + .../Settings/IPartTableMigrationSupport.cs | 8 + .../Settings/ITableSettings.cs | 68 +++ .../Settings/ITableSettingsStorage.cs | 8 + .../Settings/TableSettings.cs | 69 +++ .../Settings/TableSettingsStorage.cs | 13 + src/Sa.Partitional.PostgreSql/Setup.cs | 23 + .../SqlBuilder/ISqlBuilder.cs | 22 + .../SqlBuilder/ISqlBuilderFactory.cs | 6 + .../SqlBuilder/ISqlTableBuilder.cs | 17 + .../SqlBuilder/Setup.cs | 15 + .../SqlBuilder/SqlBuilder.cs | 89 ++++ .../SqlBuilder/SqlBuilderFactory.cs | 6 + .../SqlBuilder/SqlPartListBuilder.cs | 18 + .../SqlBuilder/SqlPartRangeBuilder.cs | 12 + .../SqlBuilder/SqlRootBuilder.cs | 12 + .../SqlBuilder/SqlTableBuilder.cs | 47 ++ .../SqlBuilder/SqlTemplate.cs | 159 +++++++ src/Sa.Partitional.Support/Part.cs | 10 + src/Sa.Partitional.Support/PartByRange.cs | 8 + .../Sa.Partitional.Support.csproj | 13 + src/Sa.Schedule/Engine/JobContext.cs | 59 +++ src/Sa.Schedule/Engine/JobController.cs | 132 ++++++ src/Sa.Schedule/Engine/JobErrorHandler.cs | 91 ++++ src/Sa.Schedule/Engine/JobFactory.cs | 13 + src/Sa.Schedule/Engine/JobPipeline.cs | 47 ++ src/Sa.Schedule/Engine/JobRunner.cs | 44 ++ src/Sa.Schedule/Engine/JobScheduler.cs | 99 +++++ src/Sa.Schedule/Engine/JobTiming.cs | 12 + src/Sa.Schedule/Engine/ScheduleHost.cs | 17 + src/Sa.Schedule/Engine/Scheduler.cs | 33 ++ src/Sa.Schedule/ErrorHandlingAction.cs | 20 + src/Sa.Schedule/IJob.cs | 15 + src/Sa.Schedule/IJobBuilder.cs | 96 +++++ src/Sa.Schedule/IJobContext.cs | 33 ++ src/Sa.Schedule/IJobController.cs | 29 ++ src/Sa.Schedule/IJobErrorHandler.cs | 14 + src/Sa.Schedule/IJobErrorHandling.cs | 32 ++ src/Sa.Schedule/IJobErrorHandlingBuilder.cs | 36 ++ src/Sa.Schedule/IJobFactory.cs | 7 + src/Sa.Schedule/IJobInterceptor.cs | 17 + src/Sa.Schedule/IJobProperties.cs | 47 ++ src/Sa.Schedule/IJobRunner.cs | 6 + src/Sa.Schedule/IJobScheduler.cs | 41 ++ src/Sa.Schedule/IJobSettings.cs | 24 ++ src/Sa.Schedule/IJobTiming.cs | 20 + src/Sa.Schedule/IScheduleBuilder.cs | 50 +++ src/Sa.Schedule/IScheduleSettings.cs | 22 + src/Sa.Schedule/IScheduler.cs | 36 ++ src/Sa.Schedule/JobException.cs | 7 + src/Sa.Schedule/JobInterceptorSettings.cs | 3 + src/Sa.Schedule/JobStatus.cs | 10 + src/Sa.Schedule/Readme.md | 113 +++++ src/Sa.Schedule/Sa.Schedule.csproj | 13 + .../Settings/IInterceptorSettings.cs | 7 + .../Settings/InterceptorSettings.cs | 19 + src/Sa.Schedule/Settings/Job.cs | 7 + src/Sa.Schedule/Settings/JobBuilder.cs | 71 +++ src/Sa.Schedule/Settings/JobErrorHandling.cs | 60 +++ src/Sa.Schedule/Settings/JobProperies.cs | 40 ++ src/Sa.Schedule/Settings/JobSettings.cs | 33 ++ src/Sa.Schedule/Settings/NullJobServices.cs | 8 + src/Sa.Schedule/Settings/ScheduleBuilder.cs | 96 +++++ src/Sa.Schedule/Settings/ScheduleSettings.cs | 29 ++ src/Sa.Schedule/Setup.cs | 31 ++ src/Sa.StateMachine/ISettingsBuilder.cs | 8 + src/Sa.StateMachine/ISmContext.cs | 9 + src/Sa.StateMachine/ISmProcessor.cs | 7 + src/Sa.StateMachine/ISmSettings.cs | 9 + src/Sa.StateMachine/ITransition.cs | 8 + src/Sa.StateMachine/ITransitionGraph.cs | 17 + .../Internal/SettingsBulder.cs | 55 +++ src/Sa.StateMachine/Internal/SmSettings.cs | 8 + .../Internal/TransitionGraph.cs | 78 ++++ src/Sa.StateMachine/Sa.StateMachine.csproj | 13 + src/Sa.StateMachine/SmEnumerable.cs | 77 ++++ src/Sa.StateMachine/SmLongProcess.cs | 52 +++ src/Sa.StateMachine/SmState.cs | 45 ++ src/Sa.StateMachine/SmStateId.cs | 13 + src/Sa.StateMachine/StateKind.cs | 9 + src/Sa.sln | 201 +++++++++ src/Sa/Classes/ArrayPooler.cs | 28 ++ src/Sa/Classes/Enumeration.cs | 67 +++ src/Sa/Classes/KeepLocker.cs | 41 ++ src/Sa/Classes/MurmurHash3.cs | 57 +++ src/Sa/Classes/Quartz.cs | 120 ++++++ src/Sa/Classes/ResetLazy.cs | 105 +++++ src/Sa/Classes/Retry.cs | 227 ++++++++++ src/Sa/Classes/Section.cs | 239 +++++++++++ src/Sa/Classes/StrOrNum.cs | 83 ++++ src/Sa/Classes/WorkQueue.cs | 150 +++++++ src/Sa/Extensions/DateTimeExtensions.cs | 29 ++ src/Sa/Extensions/EnumerableExtensions.cs | 29 ++ src/Sa/Extensions/ExceptionExtensions.cs | 33 ++ src/Sa/Extensions/JsonExtensions.cs | 20 + src/Sa/Extensions/NumericExtensions.cs | 50 +++ src/Sa/Extensions/SpanExtensions.cs | 126 ++++++ src/Sa/Extensions/StrToExtensions.cs | 158 +++++++ src/Sa/Extensions/StringExtensions.cs | 14 + src/Sa/GlobalSuppressions.cs | 8 + src/Sa/Host/InstanceIdProvider.cs | 16 + ...ssemblyQualifiedNameMessageTypeResolver.cs | 71 +++ .../IMessageTypeResolver.cs | 8 + src/Sa/Infrastructure/IHasId.cs | 12 + src/Sa/Sa.csproj | 15 + .../ObjectToInferredTypesConverter.cs | 42 ++ src/Sa/Setup.cs | 28 ++ .../Timing/Providers/CurrentTimeProvider.cs | 11 + .../Timing/Providers/ICurrentTimeProvider.cs | 6 + .../Schedule.Console/GlobalSuppressions.cs | 9 + src/Samples/Schedule.Console/Program.cs | 109 +++++ .../Properties/launchSettings.json | 14 + .../Schedule.Console/Schedule.Console.csproj | 28 ++ src/Samples/Schedule.Console/appsettings.json | 9 + .../StateMachine.Console/LongProcess.cs | 22 + src/Samples/StateMachine.Console/Program.cs | 33 ++ .../StateMachine.Console.csproj | 18 + .../PgDataSourceCollection.cs | 7 + .../PgDataSourceFixture.cs | 38 ++ .../PostgreSqlFixture.cs | 42 ++ .../PostgreSqlFixtureSettings.cs | 11 + .../Sa.Data.PostgreSql.Fixture.csproj | 16 + .../Fixtures/Sa.Fixture/Sa.Fixture.csproj | 3 + src/Tests/Fixtures/Sa.Fixture/SaFixture.cs | 63 +++ src/Tests/Host.Test.Properties.xml | 34 ++ .../PgDataSourceTests.cs | 68 +++ .../Sa.Data.PostgreSqlTests.csproj | 14 + src/Tests/Sa.MediaTests/Data/m1.wav | Bin 0 -> 1455404 bytes src/Tests/Sa.MediaTests/Sa.MediaTests.csproj | 21 + src/Tests/Sa.MediaTests/WavFileTests.cs | 34 ++ .../Delivery/DeliveryLongProcessorTests.cs | 68 +++ .../Delivery/DeliveryPermanentErrorTests.cs | 82 ++++ .../Delivery/DeliveryProcessorTests.cs | 65 +++ .../Delivery/DeliveryRetryErrorTests.cs | 101 +++++ .../OutboxParallelMessagingTests.cs | 178 ++++++++ .../OutboxPostgreSqlFixture.cs | 15 + .../Sa.Outbox.PostgreSqlTests/OutboxTests.cs | 105 +++++ .../Publisher/OutboxPublisherTests.cs | 34 ++ .../Sa.Outbox.PostgreSqlTests.csproj | 16 + .../OutboxMessageSerializerTests.cs | 93 ++++ .../Sa.Outbox.PostgreSqlTests/TestMessage.cs | 12 + .../Cache/PartCacheTests.cs | 169 ++++++++ .../Cleaning/PartCleanupServiceTests.cs | 71 +++ .../Configuration/ConfigurationPartTests.cs | 67 +++ .../Configuration/SqlBuilderTests.cs | 196 +++++++++ .../PartitionAsJobTests.cs | 62 +++ .../PartitionIndexTests.cs | 61 +++ .../PartitionManagerTests.cs | 78 ++++ .../PgPartByTests.cs | 170 ++++++++ .../Repositories/PgRepositoryTests.cs | 103 +++++ .../Sa.Partitional.PostgreSqlTests.csproj | 15 + .../Sa.ScheduleTests/Sa.ScheduleTests.csproj | 14 + .../SchedulePostSetupTests.cs | 73 ++++ .../Sa.ScheduleTests/ScheduleSetupTests.cs | 56 +++ src/Tests/SaTests/Classes/KeepLockerTests.cs | 90 ++++ src/Tests/SaTests/Classes/RetryTests.cs | 146 +++++++ src/Tests/SaTests/Classes/StrOrNumTests.cs | 32 ++ src/Tests/SaTests/Classes/WorkQueueTests.cs | 158 +++++++ src/Tests/SaTests/SaTests.csproj | 13 + 303 files changed, 14219 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 .github/workflows/dotnet.yml create mode 100644 src/.gitignore create mode 100644 src/Common.Properties.xml create mode 100644 src/Sa.Data.Cache/Sa.Data.Cache.csproj create mode 100644 src/Sa.Data.Cache/Setup.cs create mode 100644 src/Sa.Data.PostgreSql.Migration/ITodo.cs create mode 100644 src/Sa.Data.PostgreSql.Migration/Sa.Data.PostgreSql.Migration.csproj create mode 100644 src/Sa.Data.PostgreSql/Configuration/IPgDataSourceSettingsBuilder.cs create mode 100644 src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettings.cs create mode 100644 src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettingsBuilder.cs create mode 100644 src/Sa.Data.PostgreSql/GlobalSuppressions.cs create mode 100644 src/Sa.Data.PostgreSql/IPgDataSource.cs create mode 100644 src/Sa.Data.PostgreSql/IPgDistributedLock.cs create mode 100644 src/Sa.Data.PostgreSql/PgDataSource.cs create mode 100644 src/Sa.Data.PostgreSql/PgDistributedLock.cs create mode 100644 src/Sa.Data.PostgreSql/Readme.md create mode 100644 src/Sa.Data.PostgreSql/Sa.Data.PostgreSql.csproj create mode 100644 src/Sa.Data.PostgreSql/Setup.cs create mode 100644 src/Sa.Media/Sa.Media.csproj create mode 100644 src/Sa.Media/Wav/WavFile.cs create mode 100644 src/Sa.Outbox.Attributes/IOutboxPayloadMessage.cs create mode 100644 src/Sa.Outbox.Attributes/OutboxMessageAttribute.cs create mode 100644 src/Sa.Outbox.Attributes/PingMessage.cs create mode 100644 src/Sa.Outbox.Attributes/Sa.Outbox.Support.csproj create mode 100644 src/Sa.Outbox.PostgreSql/Commands/ErrorDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/ExtendDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/FinishDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/IErrorDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/IExtendDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/IFinishDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/IOutboxBulkCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/IStartDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/OutboxBulkCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/SqlCacheSplitter.cs create mode 100644 src/Sa.Outbox.PostgreSql/Commands/StartDeliveryCommand.cs create mode 100644 src/Sa.Outbox.PostgreSql/Configuration/IPgOutboxConfiguration.cs create mode 100644 src/Sa.Outbox.PostgreSql/Configuration/PgOutboxConfiguration.cs create mode 100644 src/Sa.Outbox.PostgreSql/Configuration/PgOutboxSettings.cs create mode 100644 src/Sa.Outbox.PostgreSql/Configuration/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/GlobalSuppressions.cs create mode 100644 src/Sa.Outbox.PostgreSql/IdGen/IIdGenerator.cs create mode 100644 src/Sa.Outbox.PostgreSql/IdGen/IdGenerator.cs create mode 100644 src/Sa.Outbox.PostgreSql/IdGen/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Interceptors/DeliveryJobInterceptor.cs create mode 100644 src/Sa.Outbox.PostgreSql/Interceptors/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Partitional/OutboxMigrationSupport.cs create mode 100644 src/Sa.Outbox.PostgreSql/Partitional/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Readme.md create mode 100644 src/Sa.Outbox.PostgreSql/Repository/DeliveryRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/IMsgTypeRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/IOutboxPartRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/MsgTypeRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/OutboxPartRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/OutboxRepository.cs create mode 100644 src/Sa.Outbox.PostgreSql/Repository/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Sa.Outbox.PostgreSql.csproj create mode 100644 src/Sa.Outbox.PostgreSql/Serialization/IOutboxMessageSerializer.cs create mode 100644 src/Sa.Outbox.PostgreSql/Serialization/OutboxMessageSerializer.cs create mode 100644 src/Sa.Outbox.PostgreSql/Serialization/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/Setup.cs create mode 100644 src/Sa.Outbox.PostgreSql/SqlOutboxTemplate.cs create mode 100644 src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeCache.cs create mode 100644 src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeHashResolver.cs create mode 100644 src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeCache.cs create mode 100644 src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeHashResolver.cs create mode 100644 src/Sa.Outbox.PostgreSql/TypeHashResolve/Setup.cs create mode 100644 src/Sa.Outbox/Configuration/DeliveryBuilder.cs create mode 100644 src/Sa.Outbox/Configuration/IDeliveryBuilder.cs create mode 100644 src/Sa.Outbox/Configuration/IOutboxBuilder.cs create mode 100644 src/Sa.Outbox/Configuration/OutboxBuilder.cs create mode 100644 src/Sa.Outbox/Configuration/OutboxSettings.cs create mode 100644 src/Sa.Outbox/Delivery/DeliveryCourier.cs create mode 100644 src/Sa.Outbox/Delivery/DeliveryProcessor.cs create mode 100644 src/Sa.Outbox/Delivery/DeliveryRelay.cs create mode 100644 src/Sa.Outbox/Delivery/IDeliveryCourier.cs create mode 100644 src/Sa.Outbox/Delivery/IDeliveryProcessor.cs create mode 100644 src/Sa.Outbox/Delivery/IDeliveryRelay.cs create mode 100644 src/Sa.Outbox/Delivery/Setup.cs create mode 100644 src/Sa.Outbox/DeliveryStatusCode.cs create mode 100644 src/Sa.Outbox/Exceptions/DeliveryException.cs create mode 100644 src/Sa.Outbox/Exceptions/DeliveryPermanentException.cs create mode 100644 src/Sa.Outbox/Exceptions/OutboxMessageException.cs create mode 100644 src/Sa.Outbox/GlobalSuppressions.cs create mode 100644 src/Sa.Outbox/IConsumer.cs create mode 100644 src/Sa.Outbox/IOutboxMessagePluginPublisher.cs create mode 100644 src/Sa.Outbox/Job/DeliveryJob.cs create mode 100644 src/Sa.Outbox/Job/IOutboxJobInterceptor.cs create mode 100644 src/Sa.Outbox/Job/OutboxJobInterceptor.cs create mode 100644 src/Sa.Outbox/Job/Setup.cs create mode 100644 src/Sa.Outbox/Partitional/IOutboxPartitionalSupport.cs create mode 100644 src/Sa.Outbox/Partitional/IPartitionalSupportCache.cs create mode 100644 src/Sa.Outbox/Partitional/OutboxPartitionalSupport.cs create mode 100644 src/Sa.Outbox/Partitional/PartitionalSettings.cs create mode 100644 src/Sa.Outbox/Partitional/PartitionalSupportCache.cs create mode 100644 src/Sa.Outbox/Partitional/Setup.cs create mode 100644 src/Sa.Outbox/Publication/OutboxMessagePublisher.cs create mode 100644 src/Sa.Outbox/Publication/OutboxMessageTypeHelper.cs create mode 100644 src/Sa.Outbox/Publication/Setup.cs create mode 100644 src/Sa.Outbox/Readme.md create mode 100644 src/Sa.Outbox/Repositories/IDeliveryRepository.cs create mode 100644 src/Sa.Outbox/Repositories/IOutboxContext.cs create mode 100644 src/Sa.Outbox/Repositories/IOutboxRepository.cs create mode 100644 src/Sa.Outbox/Repositories/OutboxContext.cs create mode 100644 src/Sa.Outbox/Repositories/OutboxMessage.cs create mode 100644 src/Sa.Outbox/Repositories/OutboxMessageFilter.cs create mode 100644 src/Sa.Outbox/Sa.Outbox.csproj create mode 100644 src/Sa.Outbox/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cache/IPartCache.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cache/PartCache.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cache/PartCacheSettings.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cache/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cleaning/IPartCleanupService.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupJob.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupScheduleSettings.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupService.cs create mode 100644 src/Sa.Partitional.PostgreSql/Cleaning/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/ISchemaBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/ISettingsBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/ITableBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/SchemaBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/SettingsBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/Builder/TableBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/IPartConfiguration.cs create mode 100644 src/Sa.Partitional.PostgreSql/Configuration/PartConfiguration.cs create mode 100644 src/Sa.Partitional.PostgreSql/GlobalSuppressions.cs create mode 100644 src/Sa.Partitional.PostgreSql/IPartitionManager.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/IPartMigrationService.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/MigrationJobConstance.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/PartMigrationJob.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/PartMigrationScheduleSettings.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/PartMigrationService.cs create mode 100644 src/Sa.Partitional.PostgreSql/Migration/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Part.cs create mode 100644 src/Sa.Partitional.PostgreSql/PartByRange.cs create mode 100644 src/Sa.Partitional.PostgreSql/PartitionManager.cs create mode 100644 src/Sa.Partitional.PostgreSql/PgPartBy.cs create mode 100644 src/Sa.Partitional.PostgreSql/Readme.md create mode 100644 src/Sa.Partitional.PostgreSql/Repositories/IPartRepository.cs create mode 100644 src/Sa.Partitional.PostgreSql/Repositories/PartRepository.cs create mode 100644 src/Sa.Partitional.PostgreSql/Repositories/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/Sa.Partitional.PostgreSql.csproj create mode 100644 src/Sa.Partitional.PostgreSql/Settings/IPartTableMigrationSupport.cs create mode 100644 src/Sa.Partitional.PostgreSql/Settings/ITableSettings.cs create mode 100644 src/Sa.Partitional.PostgreSql/Settings/ITableSettingsStorage.cs create mode 100644 src/Sa.Partitional.PostgreSql/Settings/TableSettings.cs create mode 100644 src/Sa.Partitional.PostgreSql/Settings/TableSettingsStorage.cs create mode 100644 src/Sa.Partitional.PostgreSql/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilderFactory.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlTableBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/Setup.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilderFactory.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartListBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartRangeBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlRootBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTableBuilder.cs create mode 100644 src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTemplate.cs create mode 100644 src/Sa.Partitional.Support/Part.cs create mode 100644 src/Sa.Partitional.Support/PartByRange.cs create mode 100644 src/Sa.Partitional.Support/Sa.Partitional.Support.csproj create mode 100644 src/Sa.Schedule/Engine/JobContext.cs create mode 100644 src/Sa.Schedule/Engine/JobController.cs create mode 100644 src/Sa.Schedule/Engine/JobErrorHandler.cs create mode 100644 src/Sa.Schedule/Engine/JobFactory.cs create mode 100644 src/Sa.Schedule/Engine/JobPipeline.cs create mode 100644 src/Sa.Schedule/Engine/JobRunner.cs create mode 100644 src/Sa.Schedule/Engine/JobScheduler.cs create mode 100644 src/Sa.Schedule/Engine/JobTiming.cs create mode 100644 src/Sa.Schedule/Engine/ScheduleHost.cs create mode 100644 src/Sa.Schedule/Engine/Scheduler.cs create mode 100644 src/Sa.Schedule/ErrorHandlingAction.cs create mode 100644 src/Sa.Schedule/IJob.cs create mode 100644 src/Sa.Schedule/IJobBuilder.cs create mode 100644 src/Sa.Schedule/IJobContext.cs create mode 100644 src/Sa.Schedule/IJobController.cs create mode 100644 src/Sa.Schedule/IJobErrorHandler.cs create mode 100644 src/Sa.Schedule/IJobErrorHandling.cs create mode 100644 src/Sa.Schedule/IJobErrorHandlingBuilder.cs create mode 100644 src/Sa.Schedule/IJobFactory.cs create mode 100644 src/Sa.Schedule/IJobInterceptor.cs create mode 100644 src/Sa.Schedule/IJobProperties.cs create mode 100644 src/Sa.Schedule/IJobRunner.cs create mode 100644 src/Sa.Schedule/IJobScheduler.cs create mode 100644 src/Sa.Schedule/IJobSettings.cs create mode 100644 src/Sa.Schedule/IJobTiming.cs create mode 100644 src/Sa.Schedule/IScheduleBuilder.cs create mode 100644 src/Sa.Schedule/IScheduleSettings.cs create mode 100644 src/Sa.Schedule/IScheduler.cs create mode 100644 src/Sa.Schedule/JobException.cs create mode 100644 src/Sa.Schedule/JobInterceptorSettings.cs create mode 100644 src/Sa.Schedule/JobStatus.cs create mode 100644 src/Sa.Schedule/Readme.md create mode 100644 src/Sa.Schedule/Sa.Schedule.csproj create mode 100644 src/Sa.Schedule/Settings/IInterceptorSettings.cs create mode 100644 src/Sa.Schedule/Settings/InterceptorSettings.cs create mode 100644 src/Sa.Schedule/Settings/Job.cs create mode 100644 src/Sa.Schedule/Settings/JobBuilder.cs create mode 100644 src/Sa.Schedule/Settings/JobErrorHandling.cs create mode 100644 src/Sa.Schedule/Settings/JobProperies.cs create mode 100644 src/Sa.Schedule/Settings/JobSettings.cs create mode 100644 src/Sa.Schedule/Settings/NullJobServices.cs create mode 100644 src/Sa.Schedule/Settings/ScheduleBuilder.cs create mode 100644 src/Sa.Schedule/Settings/ScheduleSettings.cs create mode 100644 src/Sa.Schedule/Setup.cs create mode 100644 src/Sa.StateMachine/ISettingsBuilder.cs create mode 100644 src/Sa.StateMachine/ISmContext.cs create mode 100644 src/Sa.StateMachine/ISmProcessor.cs create mode 100644 src/Sa.StateMachine/ISmSettings.cs create mode 100644 src/Sa.StateMachine/ITransition.cs create mode 100644 src/Sa.StateMachine/ITransitionGraph.cs create mode 100644 src/Sa.StateMachine/Internal/SettingsBulder.cs create mode 100644 src/Sa.StateMachine/Internal/SmSettings.cs create mode 100644 src/Sa.StateMachine/Internal/TransitionGraph.cs create mode 100644 src/Sa.StateMachine/Sa.StateMachine.csproj create mode 100644 src/Sa.StateMachine/SmEnumerable.cs create mode 100644 src/Sa.StateMachine/SmLongProcess.cs create mode 100644 src/Sa.StateMachine/SmState.cs create mode 100644 src/Sa.StateMachine/SmStateId.cs create mode 100644 src/Sa.StateMachine/StateKind.cs create mode 100644 src/Sa.sln create mode 100644 src/Sa/Classes/ArrayPooler.cs create mode 100644 src/Sa/Classes/Enumeration.cs create mode 100644 src/Sa/Classes/KeepLocker.cs create mode 100644 src/Sa/Classes/MurmurHash3.cs create mode 100644 src/Sa/Classes/Quartz.cs create mode 100644 src/Sa/Classes/ResetLazy.cs create mode 100644 src/Sa/Classes/Retry.cs create mode 100644 src/Sa/Classes/Section.cs create mode 100644 src/Sa/Classes/StrOrNum.cs create mode 100644 src/Sa/Classes/WorkQueue.cs create mode 100644 src/Sa/Extensions/DateTimeExtensions.cs create mode 100644 src/Sa/Extensions/EnumerableExtensions.cs create mode 100644 src/Sa/Extensions/ExceptionExtensions.cs create mode 100644 src/Sa/Extensions/JsonExtensions.cs create mode 100644 src/Sa/Extensions/NumericExtensions.cs create mode 100644 src/Sa/Extensions/SpanExtensions.cs create mode 100644 src/Sa/Extensions/StrToExtensions.cs create mode 100644 src/Sa/Extensions/StringExtensions.cs create mode 100644 src/Sa/GlobalSuppressions.cs create mode 100644 src/Sa/Host/InstanceIdProvider.cs create mode 100644 src/Sa/Host/MessageTypeResolver/AssemblyQualifiedNameMessageTypeResolver.cs create mode 100644 src/Sa/Host/MessageTypeResolver/IMessageTypeResolver.cs create mode 100644 src/Sa/Infrastructure/IHasId.cs create mode 100644 src/Sa/Sa.csproj create mode 100644 src/Sa/Serialization/Converter/ObjectToInferredTypesConverter.cs create mode 100644 src/Sa/Setup.cs create mode 100644 src/Sa/Timing/Providers/CurrentTimeProvider.cs create mode 100644 src/Sa/Timing/Providers/ICurrentTimeProvider.cs create mode 100644 src/Samples/Schedule.Console/GlobalSuppressions.cs create mode 100644 src/Samples/Schedule.Console/Program.cs create mode 100644 src/Samples/Schedule.Console/Properties/launchSettings.json create mode 100644 src/Samples/Schedule.Console/Schedule.Console.csproj create mode 100644 src/Samples/Schedule.Console/appsettings.json create mode 100644 src/Samples/StateMachine.Console/LongProcess.cs create mode 100644 src/Samples/StateMachine.Console/Program.cs create mode 100644 src/Samples/StateMachine.Console/StateMachine.Console.csproj create mode 100644 src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceCollection.cs create mode 100644 src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceFixture.cs create mode 100644 src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixture.cs create mode 100644 src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixtureSettings.cs create mode 100644 src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/Sa.Data.PostgreSql.Fixture.csproj create mode 100644 src/Tests/Fixtures/Sa.Fixture/Sa.Fixture.csproj create mode 100644 src/Tests/Fixtures/Sa.Fixture/SaFixture.cs create mode 100644 src/Tests/Host.Test.Properties.xml create mode 100644 src/Tests/Sa.Data.PostgreSqlTests/PgDataSourceTests.cs create mode 100644 src/Tests/Sa.Data.PostgreSqlTests/Sa.Data.PostgreSqlTests.csproj create mode 100644 src/Tests/Sa.MediaTests/Data/m1.wav create mode 100644 src/Tests/Sa.MediaTests/Sa.MediaTests.csproj create mode 100644 src/Tests/Sa.MediaTests/WavFileTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryLongProcessorTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryPermanentErrorTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryProcessorTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryRetryErrorTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/OutboxParallelMessagingTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/OutboxPostgreSqlFixture.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/OutboxTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Publisher/OutboxPublisherTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Sa.Outbox.PostgreSqlTests.csproj create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/Serialization/OutboxMessageSerializerTests.cs create mode 100644 src/Tests/Sa.Outbox.PostgreSqlTests/TestMessage.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Cache/PartCacheTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Cleaning/PartCleanupServiceTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/ConfigurationPartTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/SqlBuilderTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/PartitionAsJobTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/PartitionIndexTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/PartitionManagerTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/PgPartByTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Repositories/PgRepositoryTests.cs create mode 100644 src/Tests/Sa.Partitional.PostgreSqlTests/Sa.Partitional.PostgreSqlTests.csproj create mode 100644 src/Tests/Sa.ScheduleTests/Sa.ScheduleTests.csproj create mode 100644 src/Tests/Sa.ScheduleTests/SchedulePostSetupTests.cs create mode 100644 src/Tests/Sa.ScheduleTests/ScheduleSetupTests.cs create mode 100644 src/Tests/SaTests/Classes/KeepLockerTests.cs create mode 100644 src/Tests/SaTests/Classes/RetryTests.cs create mode 100644 src/Tests/SaTests/Classes/StrOrNumTests.cs create mode 100644 src/Tests/SaTests/Classes/WorkQueueTests.cs create mode 100644 src/Tests/SaTests/SaTests.csproj diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fe1152b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml new file mode 100644 index 0000000..dcddade --- /dev/null +++ b/.github/workflows/dotnet.yml @@ -0,0 +1,31 @@ +# This workflow will build a .NET project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net + +name: .NET + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - name: Restore dependencies + run: dotnet restore + working-directory: ./src + - name: Build + run: dotnet build --no-restore + working-directory: ./src + - name: Test + run: dotnet test --no-build --verbosity normal + working-directory: ./src diff --git a/.gitignore b/.gitignore index a4fe18b..44ce8a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,402 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. +dist/ +.vscode/## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml ## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..a4fe18b --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,400 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +# but not Directory.Build.rsp, as it configures directory-level build defaults +!Directory.Build.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml diff --git a/src/Common.Properties.xml b/src/Common.Properties.xml new file mode 100644 index 0000000..e382396 --- /dev/null +++ b/src/Common.Properties.xml @@ -0,0 +1,22 @@ + + + + net8.0 + enable + Sa + abt + dundich + Copyright © 2024 + See https://github.com/dundich/Sa/releases + https://github.com/dundich/Sa + https://github.com/dundich/Sa + Apache-2.0 + true + true + enable + + + + + + \ No newline at end of file diff --git a/src/Sa.Data.Cache/Sa.Data.Cache.csproj b/src/Sa.Data.Cache/Sa.Data.Cache.csproj new file mode 100644 index 0000000..90fa666 --- /dev/null +++ b/src/Sa.Data.Cache/Sa.Data.Cache.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.Data.Cache/Setup.cs b/src/Sa.Data.Cache/Setup.cs new file mode 100644 index 0000000..f740dd6 --- /dev/null +++ b/src/Sa.Data.Cache/Setup.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.DependencyInjection; +using ZiggyCreatures.Caching.Fusion; + +namespace Sa.Data.Cache; + + +public static class Setup +{ + public static IServiceCollection AddFusionCacheEx(this IServiceCollection services, string cacheName, Action? configure = null) + { + services.AddFusionCacheSystemTextJsonSerializer(); + + // https://github.com/ZiggyCreatures/FusionCache + services + .AddFusionCache(cacheName) + .WithPostSetup((sp, c) => + { + FusionCacheEntryOptions ops = c.DefaultEntryOptions; + + ops.Duration = TimeSpan.FromMinutes(2); + ops.FactorySoftTimeout = TimeSpan.FromMilliseconds(100); + ops.FailSafeMaxDuration = TimeSpan.FromHours(2); + ops.FailSafeThrottleDuration = TimeSpan.FromSeconds(30); + ops.Priority = CacheItemPriority.Low; + configure?.Invoke(sp, ops); + }) + .WithoutLogger(); + + return services; + } +} \ No newline at end of file diff --git a/src/Sa.Data.PostgreSql.Migration/ITodo.cs b/src/Sa.Data.PostgreSql.Migration/ITodo.cs new file mode 100644 index 0000000..2064e3c --- /dev/null +++ b/src/Sa.Data.PostgreSql.Migration/ITodo.cs @@ -0,0 +1,7 @@ +namespace Sa.Data.PostgreSql.Migration +{ + public interface ITodo + { + // todos + } +} diff --git a/src/Sa.Data.PostgreSql.Migration/Sa.Data.PostgreSql.Migration.csproj b/src/Sa.Data.PostgreSql.Migration/Sa.Data.PostgreSql.Migration.csproj new file mode 100644 index 0000000..660d21e --- /dev/null +++ b/src/Sa.Data.PostgreSql.Migration/Sa.Data.PostgreSql.Migration.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.Data.PostgreSql/Configuration/IPgDataSourceSettingsBuilder.cs b/src/Sa.Data.PostgreSql/Configuration/IPgDataSourceSettingsBuilder.cs new file mode 100644 index 0000000..1c8c3ff --- /dev/null +++ b/src/Sa.Data.PostgreSql/Configuration/IPgDataSourceSettingsBuilder.cs @@ -0,0 +1,10 @@ + +namespace Sa.Data.PostgreSql; + +public interface IPgDataSourceSettingsBuilder +{ + void WithConnectionString(string connectionString); + void WithConnectionString(Func implementationFactory); + void WithSettings(PgDataSourceSettings settings); + void WithSettings(Func implementationFactory); +} \ No newline at end of file diff --git a/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettings.cs b/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettings.cs new file mode 100644 index 0000000..29c4800 --- /dev/null +++ b/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettings.cs @@ -0,0 +1,6 @@ +namespace Sa.Data.PostgreSql; + +public class PgDataSourceSettings(string connectionString) +{ + public string ConnectionString { get; } = connectionString; +} diff --git a/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettingsBuilder.cs b/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettingsBuilder.cs new file mode 100644 index 0000000..1e40a96 --- /dev/null +++ b/src/Sa.Data.PostgreSql/Configuration/PgDataSourceSettingsBuilder.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Data.PostgreSql.Configuration; + +internal class PgDataSourceSettingsBuilder(IServiceCollection services) : IPgDataSourceSettingsBuilder +{ + + public void WithConnectionString(string connectionString) + { + services.TryAddSingleton(new PgDataSourceSettings(connectionString)); + } + + public void WithConnectionString(Func implementationFactory) + { + services.TryAddSingleton(sp => new PgDataSourceSettings(implementationFactory(sp))); + } + + public void WithSettings(Func implementationFactory) + { + services.TryAddSingleton(implementationFactory); + } + + public void WithSettings(PgDataSourceSettings settings) + { + services.TryAddSingleton(settings); + } +} diff --git a/src/Sa.Data.PostgreSql/GlobalSuppressions.cs b/src/Sa.Data.PostgreSql/GlobalSuppressions.cs new file mode 100644 index 0000000..9f39147 --- /dev/null +++ b/src/Sa.Data.PostgreSql/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0130:Namespace does not match folder structure", Justification = "", Scope = "namespace", Target = "~N:Sa.Data.PostgreSql")] diff --git a/src/Sa.Data.PostgreSql/IPgDataSource.cs b/src/Sa.Data.PostgreSql/IPgDataSource.cs new file mode 100644 index 0000000..0f504f7 --- /dev/null +++ b/src/Sa.Data.PostgreSql/IPgDataSource.cs @@ -0,0 +1,83 @@ +using Npgsql; + +namespace Sa.Data.PostgreSql; + +public interface IPgDataSource +{ + public static IPgDataSource Create(string connectionString) => new PgDataSource(new PgDataSourceSettings(connectionString)); + + + // ExecuteNonQuery + + Task ExecuteNonQuery(string sql, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default); + + async Task ExecuteNonQuery(string sql, CancellationToken cancellationToken = default) + => await ExecuteNonQuery(sql, [], cancellationToken); + + + // ExecuteReader + + Task ExecuteReader(string sql, Action read, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default); + + async Task ExecuteReader(string sql, Action read, CancellationToken cancellationToken = default) + => await ExecuteReader(sql, read, [], cancellationToken); + + + // ExecuteReaderList + + + async Task> ExecuteReaderList(string sql, Func read, CancellationToken cancellationToken = default) + { + List list = []; + await ExecuteReader(sql, (reader, _) => list.Add(read(reader)), cancellationToken); + return list; + } + + async Task> ExecuteReaderList(string sql, Func read, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default) + { + List list = []; + await ExecuteReader(sql, (reader, _) => list.Add(read(reader)), parameters, cancellationToken); + return list; + } + + + // ExecuteReaderFirst + + + Task ExecuteReaderFirst(string sql, CancellationToken cancellationToken = default) + { + return ExecuteReaderFirst(sql, [], cancellationToken); + } + + async Task ExecuteReaderFirst(string sql, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default) + { + T value = default!; + + await ExecuteReader(sql, (reader, _) => + { + value = Type.GetTypeCode(typeof(T)) switch + { + TypeCode.Char => (T)(object)reader.GetChar(0), + TypeCode.Int64 => (T)(object)reader.GetInt64(0), + TypeCode.Int32 => (T)(object)reader.GetInt32(0), + TypeCode.String => (T)(object)reader.GetString(0), + TypeCode.Boolean => (T)(object)reader.GetBoolean(0), + TypeCode.Double => (T)(object)reader.GetDouble(0), + TypeCode.DateTime => (T)(object)reader.GetDateTime(0), + TypeCode.Decimal => (T)(object)reader.GetDecimal(0), + TypeCode.DBNull => value, + _ => throw new InvalidOperationException($"Unsupported type: {typeof(T)}"), + }; + } + , parameters + , cancellationToken); + + return value; + } + + + // BeginBinaryImport + + + ValueTask BeginBinaryImport(string sql, Func> write, CancellationToken cancellationToken = default); +} diff --git a/src/Sa.Data.PostgreSql/IPgDistributedLock.cs b/src/Sa.Data.PostgreSql/IPgDistributedLock.cs new file mode 100644 index 0000000..5ebf898 --- /dev/null +++ b/src/Sa.Data.PostgreSql/IPgDistributedLock.cs @@ -0,0 +1,6 @@ +namespace Sa.Data.PostgreSql; + +public interface IPgDistributedLock +{ + Task TryExecuteInDistributedLock(long lockId, Func exclusiveLockTask, CancellationToken cancellationToken); +} diff --git a/src/Sa.Data.PostgreSql/PgDataSource.cs b/src/Sa.Data.PostgreSql/PgDataSource.cs new file mode 100644 index 0000000..d175bf5 --- /dev/null +++ b/src/Sa.Data.PostgreSql/PgDataSource.cs @@ -0,0 +1,71 @@ +using Npgsql; + +namespace Sa.Data.PostgreSql; + +/// +/// NpgsqlDataSource lite +/// +/// connection string +internal sealed class PgDataSource(PgDataSourceSettings settings) : IPgDataSource, IDisposable, IAsyncDisposable +{ + private readonly Lazy _dataSource = new(() => NpgsqlDataSource.Create(settings.ConnectionString)); + + public ValueTask OpenDbConnection(CancellationToken cancellationToken) => _dataSource.Value.OpenConnectionAsync(cancellationToken); + + public void Dispose() + { + if (_dataSource.IsValueCreated) + { + _dataSource.Value.Dispose(); + } + } + + public async ValueTask DisposeAsync() + { + if (_dataSource.IsValueCreated) + { + await _dataSource.Value.DisposeAsync(); + } + } + + public async ValueTask BeginBinaryImport(string sql, Func> write, CancellationToken cancellationToken = default) + { + using NpgsqlConnection db = await OpenDbConnection(cancellationToken); + using NpgsqlBinaryImporter writer = await db.BeginBinaryImportAsync(sql, cancellationToken); + ulong result = await write(writer, cancellationToken); + return result; + } + + public async Task ExecuteNonQuery(string sql, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default) + { + using NpgsqlConnection connection = await OpenDbConnection(cancellationToken); + using NpgsqlCommand cmd = new(sql, connection); + AddParameters(cmd, parameters); + return await cmd.ExecuteNonQueryAsync(cancellationToken); + } + + public async Task ExecuteReader(string sql, Action read, NpgsqlParameter[] parameters, CancellationToken cancellationToken = default) + { + int rowCount = 0; + + using NpgsqlConnection connection = await OpenDbConnection(cancellationToken); + using NpgsqlCommand cmd = new(sql, connection); + AddParameters(cmd, parameters); + using NpgsqlDataReader reader = await cmd.ExecuteReaderAsync(cancellationToken); + while (await reader.ReadAsync(cancellationToken) && !cancellationToken.IsCancellationRequested) + { + read(reader, rowCount); + rowCount++; + } + return rowCount; + } + + + static void AddParameters(NpgsqlCommand cmd, NpgsqlParameter[] parameters) + { + if (parameters != null && parameters.Length > 0) + { + cmd.Parameters.AddRange(parameters); + } + } +} diff --git a/src/Sa.Data.PostgreSql/PgDistributedLock.cs b/src/Sa.Data.PostgreSql/PgDistributedLock.cs new file mode 100644 index 0000000..f22b1b5 --- /dev/null +++ b/src/Sa.Data.PostgreSql/PgDistributedLock.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.Logging; +using Npgsql; + +namespace Sa.Data.PostgreSql; + +/// +/// +/// +/// +internal sealed class PgDistributedLock(PgDataSourceSettings settings, ILogger? logger = null) : IPgDistributedLock +{ + private readonly NpgsqlConnectionStringBuilder builder = new(settings.ConnectionString); + + public async Task TryExecuteInDistributedLock(long lockId, Func exclusiveLockTask, CancellationToken cancellationToken) + { + logger?.LogInformation("Trying to acquire session lock for Lock Id {@LockId}", lockId); + + using var connection = new NpgsqlConnection(builder.ToString()); + await connection.OpenAsync(cancellationToken); + + bool hasLockedAcquired = await TryAcquireLockAsync(lockId, connection, cancellationToken); + + if (!hasLockedAcquired) + { + logger?.LogInformation("Lock {@LockId} rejected", lockId); + return false; + } + + logger?.LogInformation("Lock {@LockId} acquired", lockId); + try + { + if (await TryAcquireLockAsync(lockId, connection, cancellationToken)) + { + await exclusiveLockTask(cancellationToken); + } + } + finally + { + logger?.LogInformation("Releasing session lock for {@LockId}", lockId); + await ReleaseLock(lockId, connection, cancellationToken); + } + return true; + } + + private static async Task TryAcquireLockAsync(long lockId, NpgsqlConnection connection, CancellationToken cancellationToken) + { + string sessionLockCommand = $"SELECT pg_try_advisory_lock({lockId})"; + using var commandQuery = new NpgsqlCommand(sessionLockCommand, connection); + object? result = await commandQuery.ExecuteScalarAsync(cancellationToken); + if (result != null && bool.TryParse(result.ToString(), out var lockAcquired) && lockAcquired) + { + return true; + } + return false; + } + + private static async Task ReleaseLock(long lockId, NpgsqlConnection connection, CancellationToken cancellationToke) + { + string transactionLockCommand = $"SELECT pg_advisory_unlock({lockId})"; + using var commandQuery = new NpgsqlCommand(transactionLockCommand, connection); + await commandQuery.ExecuteScalarAsync(cancellationToke); + } +} \ No newline at end of file diff --git a/src/Sa.Data.PostgreSql/Readme.md b/src/Sa.Data.PostgreSql/Readme.md new file mode 100644 index 0000000..5846932 --- /dev/null +++ b/src/Sa.Data.PostgreSql/Readme.md @@ -0,0 +1,87 @@ +# IPgDataSource + +Предоставляет облегченный (минимальный) вариант абстракции для работы с базой данных PostgreSQL в .NET-приложениях. + +## ExecuteNonQuery + +Выполняет SQL-запрос, который не возвращает данные (например, INSERT, UPDATE, DELETE), и возвращает количество затронутых строк. + +```csharp +var dataSource = new PgDataSource(new PgDataSourceSettings("YourConnectionString")); +int affectedRows = await dataSource.ExecuteNonQuery("SELECT 2"); +Console.WriteLine($"Affected Rows: {affectedRows}"); + +var parameters = new[] +{ + new NpgsqlParameter("p1", "Tom"), + new NpgsqlParameter("p2", 18) +}; + +int affectedRows = await dataSource.ExecuteNonQuery(""" + CREATE TABLE IF NOT EXISTS users ( + name text, + age int + ); + + INSERT INTO users (name, age) VALUES (@p1, @p2); + """, parameters); + +Console.WriteLine($"Affected Rows: {affectedRows}"); +``` + +## ExecuteReader + +Чтение данных + +```csharp +int actual = 0; +await dataSource.ExecuteReader("SELECT 1", (reader, i) => actual = reader.GetInt32(0)); +Console.WriteLine($"Value from Database: {actual}"); + +// get first value +int errCount = await fixture.DataSource.ExecuteReaderFirst("select count(error_id) from outbox__$error"); + +``` + +## BeginBinaryImport + +Бинарный импорт + +```csharp +public async ValueTask BulkWrite(ReadOnlyMemory> messages CancellationToken cancellationToken){ + // Начинаем бинарный импорт + ulong result = await dataSource.BeginBinaryImport(sqlTemplate, async (writer, t) => + { + // Записываем строки в импорт + WriteRows(writer, typeCode, messages); + return await writer.CompleteAsync(t); + }, cancellationToken); + + return result; +} + +private void WriteRows(NpgsqlBinaryImporter writer, ReadOnlyMemory> messages) +{ + foreach (OutboxMessage message in messages.Span) + { + // Генерируем уникальный идентификатор для сообщения + string id = idGenerator.GenId(message.PartInfo.CreatedAt); + + // Начинаем новую строку для записи + writer.StartRow(); + + // Записываем данные в строку + writer.Write(id, NpgsqlDbType.Char); // id + writer.Write(message.PartInfo.TenantId, NpgsqlDbType.Integer); // tenant + writer.Write(message.PartInfo.Part, NpgsqlDbType.Text); // part + + // Сериализуем и записываем полезную нагрузку + using RecyclableMemoryStream stream = streamManager.GetStream(); + serializer.Serialize(stream, message.Payload); + stream.Position = 0; + writer.Write(stream, NpgsqlDbType.Bytea); // payload + writer.Write(stream.Length, NpgsqlDbType.Integer); // payload_size + writer.Write(message.PartInfo.CreatedAt.ToUnixTimeSeconds(), NpgsqlDbType.Bigint); // created_at + } +} +``` \ No newline at end of file diff --git a/src/Sa.Data.PostgreSql/Sa.Data.PostgreSql.csproj b/src/Sa.Data.PostgreSql/Sa.Data.PostgreSql.csproj new file mode 100644 index 0000000..f43529b --- /dev/null +++ b/src/Sa.Data.PostgreSql/Sa.Data.PostgreSql.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.Data.PostgreSql/Setup.cs b/src/Sa.Data.PostgreSql/Setup.cs new file mode 100644 index 0000000..9a122a0 --- /dev/null +++ b/src/Sa.Data.PostgreSql/Setup.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Data.PostgreSql.Configuration; + +namespace Sa.Data.PostgreSql; + +public static class Setup +{ + public static IServiceCollection AddPgDataSource(this IServiceCollection services, Action? configure = null) + { + PgDataSourceSettingsBuilder builder = new(services); + configure?.Invoke(builder); + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Media/Sa.Media.csproj b/src/Sa.Media/Sa.Media.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/src/Sa.Media/Sa.Media.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/Sa.Media/Wav/WavFile.cs b/src/Sa.Media/Wav/WavFile.cs new file mode 100644 index 0000000..a333d13 --- /dev/null +++ b/src/Sa.Media/Wav/WavFile.cs @@ -0,0 +1,404 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace Sa.Media.Wav; + +/// +/// Структура, описывающая заголовок WAV файла. +/// +/// +/// +/// + +public sealed class WavFile : IDisposable +{ + static class Env + { + public const UInt32 ChunkId = 0x46464952; + public const UInt32 WaveFormat = 0x45564157; + public const UInt16 WaveFormatPcm = 0x0001; + public const UInt32 Subchunk1IdJunk = 0x4B4E554A; + } + + private BinaryReader? _reader; + + + /// + /// Содержит символы "RIFF" в ASCII кодировке + /// + public UInt32 ChunkId { get; private set; } + + /// + /// Это оставшийся размер цепочки, начиная с этой позиции. + /// Иначе говоря, это размер файла - 8, то есть, исключены поля chunkId и chunkSize. + /// + public UInt32 ChunkSize { get; private set; } + + /// + /// Содержит символы "WAVE" + /// + public UInt32 Format { get; private set; } + + /// + /// Содержит символы "fmt " + /// + public UInt32 Subchunk1Id { get; private set; } + + /// + /// 16 для формата PCM. (or 18) + /// Это оставшийся размер подцепочки, начиная с этой позиции. + /// + public UInt32 Subchunk1Size { get; private set; } + + /// + /// Аудио формат + /// Для PCM = 1 (то есть, Линейное квантование). + /// Значения, отличающиеся от 1, обозначают некоторый формат сжатия. + /// + /// + public UInt16 AudioFormat { get; private set; } + + /// + /// Количество каналов. Моно = 1, Стерео = 2 и т.д. + /// + public UInt16 NumChannels { get; private set; } + + /// + /// Частота дискретизации. 8000 Гц, 44100 Гц и т.д. + /// + public UInt32 SampleRate { get; private set; } + + /// + /// sampleRate * numChannels * bitsPerSample/8 + /// + public UInt32 ByteRate { get; private set; } + + /// + /// numChannels * bitsPerSample/8 + /// Количество байт для одного сэмпла, включая все каналы. + /// + public UInt16 BlockAlign { get; private set; } + + /// + /// Так называемая "глубиная" или точность звучания. 8 бит, 16 бит и т.д. + /// + public UInt16 BitsPerSample { get; private set; } + + // Подцепочка "data" содержит аудио-данные и их размер. + + /// + /// Содержит символы "data" + /// + public UInt32 Subchunk2Id { get; private set; } + + /// + /// numSamples * numChannels * bitsPerSample/8 + /// Количество байт в области данных. + /// + public int Subchunk2Size { get; private set; } + + /// + /// Смещение к области данных + /// + public long DataOffset { get; private set; } + + /// + /// the number of samples per channel + /// + public int SamplesPerChannel { get; private set; } + + /// + /// Из файла + /// + public string? FileName { get; private set; } + + + public bool IsWave => IsLoaded() && ChunkId == Env.ChunkId + && Format == Env.WaveFormat; + + public bool IsPcmWave => IsWave + && (Subchunk1Size == 16 || Subchunk2Size == 18) + && AudioFormat == Env.WaveFormatPcm; + + public bool IsLoaded() => DataOffset > 0; + + + public WavFile ReadHeader(bool suppressErrors = true) + { + if (IsLoaded()) return this; + + BinaryReader reader = OpenReader(); + + // chunk 0 + ChunkId = reader.ReadUInt32(); + ChunkSize = reader.ReadUInt32(); + Format = reader.ReadUInt32(); + + // chunk 1 + Subchunk1Id = reader.ReadUInt32(); + + // chunk 1 + // Содержит символы "fmt " + // (0x666d7420 в big-endian представлении) + while (Subchunk1Id == Env.Subchunk1IdJunk) //JUNK + { + //skip JUNK chunks: https://www.daubnet.com/en/file-format-riff + UInt32 JunkSubchunk1Size = reader.ReadUInt32(); // bytes for this chunk + if (JunkSubchunk1Size % 2 == 1) + { + ++JunkSubchunk1Size; //When writing RIFFs, JUNK chunks should not have odd number as Size. + } + reader.ReadBytes((int)JunkSubchunk1Size); + Subchunk1Id = reader.ReadUInt32(); //read next subchunk + } + + + Subchunk1Size = reader.ReadUInt32(); // bytes for this chunk (expect 16 or 18) + + // 16 bytes coming... + AudioFormat = reader.ReadUInt16(); + NumChannels = reader.ReadUInt16(); + SampleRate = reader.ReadUInt32(); + ByteRate = reader.ReadUInt32(); + BlockAlign = reader.ReadUInt16(); + BitsPerSample = reader.ReadUInt16(); + + + if (Subchunk1Size == 18) + { + // Read any extra values + int fmtExtraSize = reader.ReadInt16(); + reader.ReadBytes(fmtExtraSize); + } + + // chunk 2 + + + while (true) + { + Subchunk2Id = reader.ReadUInt32(); + Subchunk2Size = reader.ReadInt32(); + + if (Subchunk2Id == 0x5453494c) + { + //just skip LIST subchunk + reader.ReadBytes(Subchunk2Size); + continue; + } + if (Subchunk2Id == 0x524c4c46) + { + //just skip FLLR subchunk https://stackoverflow.com/questions/6284651/avaudiorecorder-doesnt-write-out-proper-wav-file-header + reader.ReadBytes(Subchunk2Size); + continue; + } + + if (Subchunk2Id != 0x61746164) + { + if (suppressErrors) return this; + throw new NotImplementedException($"Bad Subchunk2Id: 0x{Subchunk2Id:x8}"); + } + break; + } + + if (Subchunk2Size == 0x7FFFFFFF) + { + //size does not set!! + //hack to support custom file length calculation + //this does not check if there are otehr subchunks after "data" in thefile + long sizeInBytesLong = (reader.BaseStream.Length - reader.BaseStream.Position); + if (sizeInBytesLong > Int32.MaxValue) + { + if (suppressErrors) return this; + throw new ArgumentNullException("Too long wave! " + sizeInBytesLong); + } + + Subchunk2Size = (int)sizeInBytesLong; + } + + // Calculate the number of samples per channel + SamplesPerChannel = Subchunk2Size / (BlockAlign * NumChannels); + + // save start data offset + DataOffset = reader.BaseStream.Position; + + return this; + } + + + public WavFile WithFileName(string filename) + { + if (filename != FileName) + { + Close(); + FileName = filename; + } + + return this; + } + + + public IEnumerable<(int channelId, byte[] sample)> ReadWave(float? cutFromSeconds = null, float? cutToSeconds = null) + { + ReadHeader(); + + BinaryReader reader = OpenReader(); + + // Calculate the byte offset for the start of the data + long dataOffset = DataOffset; + + // Calculate the byte offset for the end of the data + long dataEndOffset = dataOffset + Subchunk2Size; + + // Calculate the byte offset for the start of the cut + long cutFromOffset = dataOffset; + if (cutFromSeconds != null) + { + cutFromOffset += (long)(cutFromSeconds.Value * SampleRate * BlockAlign); + } + + // Calculate the byte offset for the end of the cut + long cutToOffset = dataEndOffset; + if (cutToSeconds != null) + { + cutToOffset = dataOffset + (long)(cutToSeconds.Value * SampleRate * BlockAlign); + } + + if (reader.BaseStream.CanSeek) + { + reader.BaseStream.Position = cutFromOffset; + } + + // Read samples from the current channel + for (long i = cutFromOffset; i < cutToOffset; i += BlockAlign) + { + for (int channelId = 0; channelId < NumChannels; channelId++) + { + // Read the sample from the stream + byte[] sample = reader.ReadBytes(BlockAlign / NumChannels); + yield return (channelId, sample); + } + } + } + + /// + /// Convert and return audio data in double format + /// + /// + /// + /// + public IEnumerable<(int channelId, double[] sample)> ReadDoubleWave(float? cutFromSeconds = null, float? cutToSeconds = null) + => ReadWave(cutFromSeconds, cutToSeconds) + .Select(c => (c.channelId, ConvertToDouble(BitsPerSample, c.sample))); + + + + /// + /// для распознавалок + /// + public IEnumerable<(int channelId, byte[] sample)> ReadDoubleWaveAsByte(float? cutFromSeconds = null, float? cutToSeconds = null) + => ReadDoubleWave(cutFromSeconds, cutToSeconds) + .Select(c => (c.channelId, ConvertToByte(c.sample))); + + public double GetLengthSeconds() + => IsLoaded() && SampleRate != 0 + ? SamplesPerChannel / SampleRate + : 0; + + public TimeSpan GetLength() => TimeSpan.FromSeconds(GetLengthSeconds()); + + public long WriteChannel([NotNull] string fileName, [Range(0, 10)] int indexChannel) + { + using FileStream fs = File.Open(fileName ?? throw new ArgumentNullException(nameof(fileName)), FileMode.OpenOrCreate); + return WriteChannel(fs, indexChannel); + } + + public long WriteChannel(FileStream fs, [Range(0, 10)] int indexChannel) + { + ReadHeader(); + + if (!IsLoaded()) throw new NotSupportedException(); + + if (indexChannel >= NumChannels || indexChannel < 0) throw new ArgumentOutOfRangeException(nameof(indexChannel)); + + using var writer = new BinaryWriter(fs); + writer.Write(ChunkId); + writer.Write(ChunkSize); + writer.Write(Format); + writer.Write(Subchunk1Id); + writer.Write(Subchunk1Size); + writer.Write(AudioFormat); + writer.Write((UInt16)1); //NumChannels + writer.Write(SampleRate); + writer.Write(ByteRate); + writer.Write((UInt16)(BlockAlign / NumChannels)); + writer.Write(BitsPerSample); + writer.Write(Subchunk2Id); + writer.Write(Subchunk2Size / NumChannels); + + + foreach (var (_, sample) in ReadWave().Where(c => c.channelId == indexChannel)) + { + writer.Write(sample); + } + + writer.Flush(); + return fs.Length; + } + + public void Close() + { + _reader?.Dispose(); + _reader = null; + DataOffset = 0; + } + + public void Dispose() => Close(); + + private BinaryReader OpenReader() + { + if (_reader == null) + { + FileStream fs = File.Open(FileName ?? throw new ArgumentException(nameof(FileName)), FileMode.Open); + _reader = new BinaryReader(fs); + } + else + { + _reader.BaseStream.Position = 0; + } + return _reader; + } + + private static byte[] ConvertToByte(double[] data) + { + short[] array = Array.ConvertAll(data, (double e) => (short)(e * 32767.0)); + byte[] array2 = new byte[array.Length * 2]; + Buffer.BlockCopy(array, 0, array2, 0, array2.Length); + return array2; + } + + private static double[] ConvertToDouble(ushort bitsPerSample, byte[] data) + { + int len = data.Length; + double[] sample; + switch (bitsPerSample) + { + case 64: + sample = new double[len / sizeof(double)]; + Buffer.BlockCopy(data, 0, sample, 0, len); + break; + case 32: + float[] asFloat = new float[len / sizeof(float)]; + Buffer.BlockCopy(data, 0, asFloat, 0, len); + sample = Array.ConvertAll(asFloat, e => (double)e); + break; + case 16: + Int16[] asInt16 = new Int16[len / sizeof(Int16)]; + Buffer.BlockCopy(data, 0, asInt16, 0, len); + sample = Array.ConvertAll(asInt16, e => e / -(double)Int16.MinValue); + break; + default: throw new ArgumentException("Bad BitsPerSample: " + bitsPerSample); + } + + return sample; + } +} diff --git a/src/Sa.Outbox.Attributes/IOutboxPayloadMessage.cs b/src/Sa.Outbox.Attributes/IOutboxPayloadMessage.cs new file mode 100644 index 0000000..7305f3f --- /dev/null +++ b/src/Sa.Outbox.Attributes/IOutboxPayloadMessage.cs @@ -0,0 +1,18 @@ +namespace Sa.Outbox.Support; + +/// +/// Represents a message payload in the Outbox system. +/// This interface defines the properties that any Outbox payload message must implement. +/// +public interface IOutboxPayloadMessage +{ + /// + /// Gets the unique identifier for the payload. + /// + string PayloadId { get; } + + /// + /// Gets the identifier for the tenant associated with the payload. + /// + public int TenantId { get; } +} diff --git a/src/Sa.Outbox.Attributes/OutboxMessageAttribute.cs b/src/Sa.Outbox.Attributes/OutboxMessageAttribute.cs new file mode 100644 index 0000000..dcc6af8 --- /dev/null +++ b/src/Sa.Outbox.Attributes/OutboxMessageAttribute.cs @@ -0,0 +1,21 @@ +namespace Sa.Outbox.Support; + + +// +/// An attribute used to mark classes or structs as Outbox messages. +/// This attribute can be used to specify the part associated with the Outbox message. +/// +/// The part identifier for the Outbox message. Default is "root". +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] +public class OutboxMessageAttribute(string part = "root") : Attribute +{ + /// + /// Gets the part identifier associated with the Outbox message. + /// + public string Part => part; + + /// + /// A default instance of the with the default part value. + /// + public readonly static OutboxMessageAttribute Default = new(); +} \ No newline at end of file diff --git a/src/Sa.Outbox.Attributes/PingMessage.cs b/src/Sa.Outbox.Attributes/PingMessage.cs new file mode 100644 index 0000000..1f60aa2 --- /dev/null +++ b/src/Sa.Outbox.Attributes/PingMessage.cs @@ -0,0 +1,10 @@ +namespace Sa.Outbox.Support; + + +[OutboxMessage] +public record PingMessage(long Payload) : IOutboxPayloadMessage +{ + public string PayloadId => String.Empty; + + public int TenantId => 0; +} diff --git a/src/Sa.Outbox.Attributes/Sa.Outbox.Support.csproj b/src/Sa.Outbox.Attributes/Sa.Outbox.Support.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/src/Sa.Outbox.Attributes/Sa.Outbox.Support.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/Sa.Outbox.PostgreSql/Commands/ErrorDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/ErrorDeliveryCommand.cs new file mode 100644 index 0000000..aeb5067 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/ErrorDeliveryCommand.cs @@ -0,0 +1,58 @@ +using Npgsql; +using Sa.Data.PostgreSql; +using Sa.Extensions; + +namespace Sa.Outbox.PostgreSql.Commands; + +internal class ErrorDeliveryCommand( + IPgDataSource dataSource + , SqlOutboxTemplate sqlTemplate +) : IErrorDeliveryCommand +{ + + private readonly SqlCacheSplitter sqlCache = new(len => sqlTemplate.SqlError(len)); + + public async Task> Execute(IOutboxContext[] outboxMessages, CancellationToken cancellationToken) + { + Dictionary errors = outboxMessages + .Where(m => m.Exception != null) + .GroupBy(m => m.Exception!) + .Select(m => (err: m.Key, createdAt: m.First().DeliveryResult.CreatedAt.StartOfDay())) + .ToDictionary(e => e.err, e => new ErrorInfo(e.err.ToString().GetMurmurHash3(), e.err.GetType().Name, e.createdAt)); + + int len = errors.Count; + + if (len == 0) return errors; + + KeyValuePair[] arrErrors = [.. errors]; + + int startIndex = 0; + + foreach ((string sql, int cnt) in sqlCache.GetSql(len)) + { + + var sliceErrors = new ArraySegment>(arrErrors, startIndex, cnt); + + startIndex += cnt; + + List parameters = []; + + int i = 0; + // (@id_{i},@type_{i},@message_{i},@created_at_{i} + foreach ((Exception Key, ErrorInfo Value) in sliceErrors) + { + (long ErrorId, string TypeName, DateTimeOffset CreatedAt) = Value; + + parameters.Add(new($"@id_{i}", ErrorId)); + parameters.Add(new($"@type_{i}", TypeName)); + parameters.Add(new($"@message_{i}", Key.ToString())); + parameters.Add(new($"@created_at_{i}", CreatedAt.ToUnixTimeSeconds())); + i++; + } + + await dataSource.ExecuteNonQuery(sql, [.. parameters], cancellationToken); + } + + return errors; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/ExtendDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/ExtendDeliveryCommand.cs new file mode 100644 index 0000000..63b3395 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/ExtendDeliveryCommand.cs @@ -0,0 +1,32 @@ +using Sa.Data.PostgreSql; +using Sa.Outbox.PostgreSql.TypeHashResolve; + +namespace Sa.Outbox.PostgreSql.Commands; + +internal class ExtendDeliveryCommand( + IPgDataSource dataSource + , IMsgTypeHashResolver hashResolver + , SqlOutboxTemplate sqlTemplate +) : IExtendDeliveryCommand +{ + public async Task Execute(TimeSpan lockExpiration, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + + long typeCode = await hashResolver.GetCode(filter.PayloadType, cancellationToken); + long now = filter.NowDate.ToUnixTimeSeconds(); + long lockExpiresOn = (filter.NowDate + lockExpiration).ToUnixTimeSeconds(); + long fromDate = filter.FromDate.ToUnixTimeSeconds(); + + return await dataSource.ExecuteNonQuery(sqlTemplate.SqlExtendDelivery, + [ + new("tenant", filter.TenantId) + , new("part", filter.Part) + , new("from_date", fromDate) + , new("transact_id", filter.TransactId) + , new("payload_type", typeCode) + , new("lock_expires_on", lockExpiresOn) + , new("now", now) + ] + , cancellationToken); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/FinishDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/FinishDeliveryCommand.cs new file mode 100644 index 0000000..c8b09ee --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/FinishDeliveryCommand.cs @@ -0,0 +1,86 @@ +using Npgsql; +using Sa.Data.PostgreSql; +using Sa.Outbox.PostgreSql.IdGen; + +namespace Sa.Outbox.PostgreSql.Commands; + +internal class FinishDeliveryCommand( + IPgDataSource dataSource + , SqlOutboxTemplate sqlTemplate + , IIdGenerator idGenerator +) : IFinishDeliveryCommand +{ + const int IndexParamsCount = 7; + const int ConstParamsCount = 4; + + + private readonly SqlCacheSplitter sqlCache = new(len => sqlTemplate.SqlFinishDelivery(len)); + + public async Task Execute( + IOutboxContext[] outboxMessages, + IReadOnlyDictionary errors, + OutboxMessageFilter filter, + CancellationToken cancellationToken) + { + if (outboxMessages.Length == 0) return 0; + + int total = 0; + + int startIndex = 0; + foreach ((string sql, int len) in sqlCache.GetSql(outboxMessages.Length)) + { + var segment = new ArraySegment>(outboxMessages, startIndex, len); + startIndex += len; + + NpgsqlParameter[] parameters = GetSqlParams(segment, errors, filter); + total += await dataSource.ExecuteNonQuery(sql, parameters, cancellationToken); + } + + return total; + } + + private NpgsqlParameter[] GetSqlParams( + ArraySegment> sliceContext, + IReadOnlyDictionary errors, + OutboxMessageFilter filter) + { + NpgsqlParameter[] parameters = new NpgsqlParameter[sliceContext.Count * IndexParamsCount + ConstParamsCount]; + + int j = 0; + foreach (IOutboxContext context in sliceContext) + { + DateTimeOffset createdAt = context.DeliveryResult.CreatedAt; + string id = idGenerator.GenId(createdAt); + string msg = context.DeliveryResult.Message; + long lockExpiresOn = (createdAt + context.PostponeAt).ToUnixTimeSeconds(); + + string errorId = String.Empty; + Exception? error = context.Exception; + if (error != null) + { + errorId = errors[error].ErrorId.ToString(); + if (string.IsNullOrEmpty(msg)) + { + msg = error.Message; + } + } + // (@id_{i},@outbox_id_{i},@error_id_{i},@status_code_{i},@status_message_{i},@lock_expires_on_{i},@created_at_{i} + parameters[j] = new($"@p{j}", id); j++; + parameters[j] = new($"@p{j}", context.OutboxId); j++; + parameters[j] = new($"@p{j}", errorId); j++; + parameters[j] = new($"@p{j}", context.DeliveryResult.Code); j++; + parameters[j] = new($"@p{j}", msg); j++; + parameters[j] = new($"@p{j}", lockExpiresOn); j++; + parameters[j] = new($"@p{j}", createdAt.ToUnixTimeSeconds()); j++; + } + + //@tenant AND @part AND @from_date AND @transact_id AND @created_at + + parameters[j++] = new("tnt", filter.TenantId); + parameters[j++] = new("prt", filter.Part); + parameters[j++] = new("from_date", filter.FromDate.ToUnixTimeSeconds()); + parameters[j] = new("tid", filter.TransactId); + + return parameters; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/IErrorDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/IErrorDeliveryCommand.cs new file mode 100644 index 0000000..bf862be --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/IErrorDeliveryCommand.cs @@ -0,0 +1,11 @@ + +namespace Sa.Outbox.PostgreSql.Commands; + + +public record struct ErrorInfo(long ErrorId, string TypeName, DateTimeOffset CreatedAt); + + +internal interface IErrorDeliveryCommand +{ + Task> Execute(IOutboxContext[] outboxMessages, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/IExtendDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/IExtendDeliveryCommand.cs new file mode 100644 index 0000000..ccbcc67 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/IExtendDeliveryCommand.cs @@ -0,0 +1,7 @@ + +namespace Sa.Outbox.PostgreSql.Commands; + +internal interface IExtendDeliveryCommand +{ + Task Execute(TimeSpan lockExpiration, OutboxMessageFilter filter, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/IFinishDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/IFinishDeliveryCommand.cs new file mode 100644 index 0000000..19571ac --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/IFinishDeliveryCommand.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.PostgreSql.Commands; + +internal interface IFinishDeliveryCommand +{ + Task Execute(IOutboxContext[] outboxMessages, IReadOnlyDictionary errors, OutboxMessageFilter filter, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/IOutboxBulkCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/IOutboxBulkCommand.cs new file mode 100644 index 0000000..55adfb2 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/IOutboxBulkCommand.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.PostgreSql.Commands; + +internal interface IOutboxBulkCommand +{ + ValueTask BulkWrite(string payloadType, ReadOnlyMemory> messages, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/IStartDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/IStartDeliveryCommand.cs new file mode 100644 index 0000000..09ffefd --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/IStartDeliveryCommand.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.PostgreSql.Commands; + +internal interface IStartDeliveryCommand +{ + Task Execute(Memory> writeBuffer, int batchSize, TimeSpan lockDuration, OutboxMessageFilter filter, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Outbox.PostgreSql/Commands/OutboxBulkCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/OutboxBulkCommand.cs new file mode 100644 index 0000000..1681d70 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/OutboxBulkCommand.cs @@ -0,0 +1,70 @@ +using Microsoft.IO; +using Npgsql; +using NpgsqlTypes; +using Sa.Data.PostgreSql; +using Sa.Outbox.PostgreSql.IdGen; +using Sa.Outbox.PostgreSql.Serialization; +using Sa.Outbox.PostgreSql.TypeHashResolve; + +namespace Sa.Outbox.PostgreSql.Commands; + + +internal class OutboxBulkCommand( + IPgDataSource dataSource + , SqlOutboxTemplate sqlTemplate + , RecyclableMemoryStreamManager streamManager + , IOutboxMessageSerializer serializer + , IIdGenerator idGenerator + , IMsgTypeHashResolver hashResolver +) : IOutboxBulkCommand +{ + public async ValueTask BulkWrite(string payloadType, ReadOnlyMemory> messages, CancellationToken cancellationToken) + { + long typeCode = await hashResolver.GetCode(payloadType, cancellationToken); + + ulong result = await dataSource.BeginBinaryImport(sqlTemplate.SqlBulkOutboxCopy, async (writer, t) => + { + WriteRows(writer, typeCode, messages); + + return await writer.CompleteAsync(t); + + }, cancellationToken); + + return result; + } + + private void WriteRows(NpgsqlBinaryImporter writer, long payloadTypeCode, ReadOnlyMemory> messages) + { + foreach (OutboxMessage row in messages.Span) + { + string id = idGenerator.GenId(row.PartInfo.CreatedAt); + + writer.StartRow(); + + + // id + writer.Write(id, NpgsqlDbType.Char); + // tenant + writer.Write(row.PartInfo.TenantId, NpgsqlDbType.Integer); + // part + writer.Write(row.PartInfo.Part, NpgsqlDbType.Text); + + + // payload_id + writer.Write(row.PayloadId, NpgsqlDbType.Text); + // payload_type + writer.Write(payloadTypeCode, NpgsqlDbType.Bigint); + // payload + using RecyclableMemoryStream stream = streamManager.GetStream(); + serializer.Serialize(stream, row.Payload); + stream.Position = 0; + writer.Write(stream, NpgsqlDbType.Bytea); + // payload_size + writer.Write(stream.Length, NpgsqlDbType.Integer); + + + // created_at + writer.Write(row.PartInfo.CreatedAt.ToUnixTimeSeconds(), NpgsqlDbType.Bigint); + } + } +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/Setup.cs b/src/Sa.Outbox.PostgreSql/Commands/Setup.cs new file mode 100644 index 0000000..f43fa4c --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/Setup.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Outbox.PostgreSql.Commands; + +internal static class Setup +{ + public static IServiceCollection AddOutboxCommands(this IServiceCollection services) + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Commands/SqlCacheSplitter.cs b/src/Sa.Outbox.PostgreSql/Commands/SqlCacheSplitter.cs new file mode 100644 index 0000000..b82ff5b --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/SqlCacheSplitter.cs @@ -0,0 +1,49 @@ +namespace Sa.Outbox.PostgreSql.Commands; + +internal class SqlCacheSplitter(Func genSql) +{ + private readonly Dictionary _sqlCache = []; + + public IEnumerable<(string sql, int len)> GetSql(int len, int maxLen = 4096) + { + if (len <= 0) + { + yield break; + } + + int multipleOf16 = len / 16 * 16; + + if (multipleOf16 > maxLen) + { + int multipleOfMax = multipleOf16 / maxLen; + + for (int i = 0; i < multipleOfMax; i++) + { + yield return GetOrAdd(maxLen); + } + } + else if (multipleOf16 > 0) + { + yield return GetOrAdd(multipleOf16); + } + + int diff = len - multipleOf16; + + if (diff > 0) + { + yield return GetOrAdd(diff); + } + } + + private (string, int) GetOrAdd(int len) + { + if (!_sqlCache.TryGetValue(len, out string? sql)) + { + sql = genSql(len); + _sqlCache[len] = sql; + } + + return (sql, len); + } +} + diff --git a/src/Sa.Outbox.PostgreSql/Commands/StartDeliveryCommand.cs b/src/Sa.Outbox.PostgreSql/Commands/StartDeliveryCommand.cs new file mode 100644 index 0000000..4c64871 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Commands/StartDeliveryCommand.cs @@ -0,0 +1,94 @@ +using Npgsql; +using Sa.Data.PostgreSql; +using Sa.Extensions; +using Sa.Outbox.PostgreSql.Serialization; +using Sa.Outbox.PostgreSql.TypeHashResolve; +using System.Data; + +namespace Sa.Outbox.PostgreSql.Commands; + +internal class StartDeliveryCommand( + IPgDataSource dataSource + , SqlOutboxTemplate sqlTemplate + , IOutboxMessageSerializer serializer + , IMsgTypeHashResolver hashResolver +) : IStartDeliveryCommand +{ + public async Task Execute(Memory> writeBuffer, int batchSize, TimeSpan lockDuration, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + + long typeCode = await hashResolver.GetCode(filter.PayloadType, cancellationToken); + + + return await dataSource.ExecuteReader(sqlTemplate.SqlLockAndSelect, (reader, i) => + { + OutboxDeliveryMessage deliveryMessage = DeliveryReader.Read(reader, serializer); + + writeBuffer.Span[i] = deliveryMessage; + }, + [ + new("tenant", filter.TenantId) + , new("part", filter.Part) + , new("from_date", filter.FromDate.ToUnixTimeSeconds()) + , new("payload_type", typeCode) + , new("transact_id", filter.TransactId) + , new("limit", batchSize) + , new("lock_expires_on", (filter.NowDate + lockDuration).ToUnixTimeSeconds()) + , new("now", filter.NowDate.ToUnixTimeSeconds()) + ] + , cancellationToken); + } + + + internal static class DeliveryReader + { + public static OutboxDeliveryMessage Read(NpgsqlDataReader reader, IOutboxMessageSerializer serializer) + { + string outboxId = reader.GetString("outbox_id"); + string payloadId = reader.GetString("outbox_payload_id"); + + TMessage payload = ReadPayload(reader, serializer); + OutboxPartInfo outboxPart = ReadOutboxPart(reader); + OutboxDeliveryInfo deliveryInfo = ReadDeliveryInfo(reader); + + return new OutboxDeliveryMessage(outboxId, payloadId, payload, outboxPart, deliveryInfo); + } + + + private static OutboxPartInfo ReadOutboxPart(NpgsqlDataReader reader) + { + return new OutboxPartInfo( + reader.GetInt32("outbox_tenant") + , reader.GetString("outbox_part") + , reader.GetInt64("outbox_created_at").ToDateTimeOffsetFromUnixTimestamp() + ); + } + + private static OutboxDeliveryInfo ReadDeliveryInfo(NpgsqlDataReader reader) + { + return new OutboxDeliveryInfo( + reader.GetString("outbox_delivery_id") + , reader.GetInt32("outbox_delivery_attempt") + , reader.GetString("outbox_delivery_error_id") + , ReadStatus(reader) + , reader.GetInt64("outbox_delivery_created_at").ToDateTimeOffsetFromUnixTimestamp() + ); + } + + private static TMessage ReadPayload(NpgsqlDataReader reader, IOutboxMessageSerializer serializer) + { + using Stream stream = reader.GetStream("outbox_payload"); + TMessage payload = serializer.Deserialize(stream)!; + return payload; + } + + + private static DeliveryStatus ReadStatus(NpgsqlDataReader reader) + { + int code = reader.GetInt32("outbox_delivery_status_code"); + string message = reader.GetString("outbox_delivery_status_message"); + DateTimeOffset createAt = reader.GetInt64("outbox_delivery_created_at").ToDateTimeOffsetFromUnixTimestamp(); + return new DeliveryStatus(code, message, createAt); + } + } +} diff --git a/src/Sa.Outbox.PostgreSql/Configuration/IPgOutboxConfiguration.cs b/src/Sa.Outbox.PostgreSql/Configuration/IPgOutboxConfiguration.cs new file mode 100644 index 0000000..359e99e --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Configuration/IPgOutboxConfiguration.cs @@ -0,0 +1,9 @@ +using Sa.Data.PostgreSql; + +namespace Sa.Outbox.PostgreSql; + +public interface IPgOutboxConfiguration +{ + IPgOutboxConfiguration WithPgOutboxSettings(Action? configure = null); + IPgOutboxConfiguration AddDataSource(Action? configure = null); +} diff --git a/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxConfiguration.cs b/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxConfiguration.cs new file mode 100644 index 0000000..8e51402 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxConfiguration.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Data.PostgreSql; +using System.Collections.Concurrent; + +namespace Sa.Outbox.PostgreSql.Configuration; + +internal class PgOutboxConfiguration(IServiceCollection services) : IPgOutboxConfiguration +{ + private static readonly ConcurrentDictionary>> s_invokers = []; + + public IPgOutboxConfiguration WithPgOutboxSettings(Action? configure = null) + { + if (configure != null) + { + if (s_invokers.TryGetValue(services, out var invokers)) + { + invokers.Add(configure); + } + else + { + s_invokers[services] = [configure]; + } + } + + + services.TryAddSingleton(sp => + { + PgOutboxSettings settings = new(); + + if (s_invokers.TryGetValue(services, out var invokers)) + { + foreach (Action build in invokers) + build.Invoke(sp, settings); + + s_invokers.Remove(services, out _); + } + + return settings; + }); + + AddSettings(); + return this; + } + + public IPgOutboxConfiguration AddDataSource(Action? configure = null) + { + services.AddPgDataSource(configure); + return this; + } + + + private void AddSettings() + { + services.TryAddSingleton(sp => sp.GetRequiredService().SerializationSettings); + + services.TryAddSingleton(sp => sp.GetRequiredService().TableSettings); + services.TryAddSingleton(sp => sp.GetRequiredService().CacheSettings); + services.TryAddSingleton(sp => sp.GetRequiredService().MigrationSettings); + services.TryAddSingleton(sp => sp.GetRequiredService().CleanupSettings); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxSettings.cs b/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxSettings.cs new file mode 100644 index 0000000..b9a840c --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Configuration/PgOutboxSettings.cs @@ -0,0 +1,171 @@ +using System.Text.Json; + +namespace Sa.Outbox.PostgreSql; + +/// +/// Represents the settings for the PostgreSQL Outbox configuration. +/// This class contains various settings related to table configuration, serialization, caching, migration, and cleanup. +/// +public class PgOutboxSettings +{ + /// + /// Gets the settings related to the Outbox table configuration. + /// + public PgOutboxTableSettings TableSettings { get; } = new(); + + /// + /// Gets the settings related to serialization of messages. + /// + public PgOutboxSerializeSettings SerializationSettings { get; } = new(); + + /// + /// Gets the settings related to caching of message types. + /// + public PgOutboxCacheSettings CacheSettings { get; } = new(); + + /// + /// Gets the settings related to migration of the Outbox schema. + /// + public PgOutboxMigrationSettings MigrationSettings { get; } = new(); + + /// + /// Gets the settings related to cleanup of old Outbox messages and parts. + /// + public PgOutboxCleanupSettings CleanupSettings { get; } = new(); +} + + +/// +/// Represents the settings for configuring the Outbox tables in PostgreSQL. +/// +public class PgOutboxTableSettings +{ + /// + /// Gets or sets the name of the database schema. + /// Default is set to "public". + /// + public string DatabaseSchemaName { get; set; } = "public"; + + /// + /// Gets or sets the name of the Outbox table. + /// Default is set to "outbox". + /// + public string DatabaseOutboxTableName { get; set; } = "outbox"; + + /// + /// Gets or sets the name of the delivery table. + /// Default is set to "outbox__$delivery". + /// + public string DatabaseDeliveryTableName { get; set; } = "outbox__$delivery"; + + /// + /// Gets or sets the name of the type table. + /// Default is set to "outbox__$type". + /// + public string DatabaseTypeTableName { get; set; } = "outbox__$type"; + + /// + /// Gets or sets the name of the error table. + /// Default is set to "outbox__$error". + /// + public string DatabaseErrorTableName { get; set; } = "outbox__$error"; + + /// + /// Gets the fully qualified name of the Outbox table, including the schema. + /// + /// The qualified name of the Outbox table. + public string GetQualifiedOutboxTableName() => $@"{DatabaseSchemaName}.""{DatabaseOutboxTableName}"""; + + /// + /// Gets the fully qualified name of the delivery table, including the schema. + /// + /// The qualified name of the delivery table. + public string GetQualifiedDeliveryTableName() => $@"{DatabaseSchemaName}.""{DatabaseDeliveryTableName}"""; + + /// + /// Gets the fully qualified name of the type table, including the schema. + /// + /// The qualified name of the type table. + public string GetQualifiedTypeTableName() => $@"{DatabaseSchemaName}.""{DatabaseTypeTableName}"""; + + /// + /// Gets the fully qualified name of the error table, including the schema. + /// + /// The qualified name of the error table. + public string GetQualifiedErrorTableName() => $@"{DatabaseSchemaName}.""{DatabaseErrorTableName}"""; +} + +/// +/// Represents the settings for serialization of messages in the Outbox. +/// +public class PgOutboxSerializeSettings +{ + public JsonSerializerOptions? JsonSerializerOptions { get; set; } +} + + +/// +/// Represents the settings for caching message types in the Outbox. +/// +public class PgOutboxCacheSettings +{ + /// + /// Gets or sets the duration for which message types are cached. + /// Default is set to 1 day. + /// + public TimeSpan CacheTypeDuration { get; set; } = TimeSpan.FromDays(1); +} + +/// +/// Represents the settings for migrating the Outbox schema in PostgreSQL. +/// +public class PgOutboxMigrationSettings +{ + /// + /// Gets or sets a value indicating whether the migration should be executed as a background job. + /// Default is set to true, meaning the migration will run as a job. + /// + public bool AsJob { get; set; } = true; + + /// + /// Gets or sets the number of days to move forward during the migration process. + /// Default is set to 2 days. + /// + public int ForwardDays { get; set; } = 2; + + /// + /// Gets or sets the interval at which the migration job will be executed. + /// Default is set to every 4 hours, with a random additional delay of up to 59 minutes. + /// + public TimeSpan ExecutionInterval { get; set; } = TimeSpan + .FromHours(4) + .Add(TimeSpan.FromMinutes(Random.Shared.Next(1, 59))); +} + + +/// +/// Represents the settings for cleaning up old Outbox messages and parts in PostgreSQL. +/// This class contains configuration options for how and when the cleanup should occur. +/// +public class PgOutboxCleanupSettings +{ + /// + /// Gets or sets a value indicating whether the cleanup should be executed as a background job. + /// Default is set to false, meaning the cleanup will not run as a job. + /// + public bool AsJob { get; set; } = false; + + /// + /// Gets or sets the duration after which old parts will be dropped. + /// Default is set to 30 days. + /// + public TimeSpan DropPartsAfterRetention { get; set; } = TimeSpan.FromDays(30); + + /// + /// Gets or sets the interval at which the cleanup job will be executed. + /// Default is set to every 4 hours, with a random additional delay of up to 59 minutes. + /// + public TimeSpan ExecutionInterval { get; set; } = TimeSpan + .FromHours(4) + .Add(TimeSpan.FromMinutes(Random.Shared.Next(1, 59))); +} diff --git a/src/Sa.Outbox.PostgreSql/Configuration/Setup.cs b/src/Sa.Outbox.PostgreSql/Configuration/Setup.cs new file mode 100644 index 0000000..a6f28f3 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Configuration/Setup.cs @@ -0,0 +1,19 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Sa.Outbox.PostgreSql.Configuration; + +internal static class Setup +{ + public static IServiceCollection AddPgOutboxSettings(this IServiceCollection services, Action? configure = null) + { + var cfg = new PgOutboxConfiguration(services); + configure?.Invoke(cfg); + + cfg + .WithPgOutboxSettings() + .AddDataSource() + ; + + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/GlobalSuppressions.cs b/src/Sa.Outbox.PostgreSql/GlobalSuppressions.cs new file mode 100644 index 0000000..0157fed --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0130:Namespace does not match folder structure")] diff --git a/src/Sa.Outbox.PostgreSql/IdGen/IIdGenerator.cs b/src/Sa.Outbox.PostgreSql/IdGen/IIdGenerator.cs new file mode 100644 index 0000000..a89cc5b --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/IdGen/IIdGenerator.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.PostgreSql.IdGen; + +public interface IIdGenerator +{ + string GenId(DateTimeOffset date); +} diff --git a/src/Sa.Outbox.PostgreSql/IdGen/IdGenerator.cs b/src/Sa.Outbox.PostgreSql/IdGen/IdGenerator.cs new file mode 100644 index 0000000..095fd9f --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/IdGen/IdGenerator.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.PostgreSql.IdGen; + +internal class IdGenerator : IIdGenerator +{ + public string GenId(DateTimeOffset date) => Ulid.NewUlid(date).ToString(); +} diff --git a/src/Sa.Outbox.PostgreSql/IdGen/Setup.cs b/src/Sa.Outbox.PostgreSql/IdGen/Setup.cs new file mode 100644 index 0000000..d78d13a --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/IdGen/Setup.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Outbox.PostgreSql.IdGen; + +internal static class Setup +{ + public static IServiceCollection AddIdGen(this IServiceCollection services) + { + services.TryAddSingleton(); + + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Interceptors/DeliveryJobInterceptor.cs b/src/Sa.Outbox.PostgreSql/Interceptors/DeliveryJobInterceptor.cs new file mode 100644 index 0000000..48344b6 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Interceptors/DeliveryJobInterceptor.cs @@ -0,0 +1,18 @@ +using Sa.Outbox.Job; +using Sa.Partitional.PostgreSql; +using Sa.Schedule; + +namespace Sa.Outbox.PostgreSql.Interceptors; + +internal class DeliveryJobInterceptor(IPartMigrationService migrationService) : IOutboxJobInterceptor +{ + public async Task OnHandle(IJobContext context, Func next, object? key, CancellationToken cancellationToken) + { + if (!migrationService.OutboxMigrated.IsCancellationRequested && context.Settings.JobType.Name.StartsWith("DeliveryJob")) + { + return; + } + + await next(); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Interceptors/Setup.cs b/src/Sa.Outbox.PostgreSql/Interceptors/Setup.cs new file mode 100644 index 0000000..f51c5f3 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Interceptors/Setup.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Outbox.Job; + +namespace Sa.Outbox.PostgreSql.Interceptors; + +internal static class Setup +{ + public static IServiceCollection AddOutboxJobInterceptors(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Partitional/OutboxMigrationSupport.cs b/src/Sa.Outbox.PostgreSql/Partitional/OutboxMigrationSupport.cs new file mode 100644 index 0000000..ef2c514 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Partitional/OutboxMigrationSupport.cs @@ -0,0 +1,19 @@ +using Sa.Classes; +using Sa.Outbox.Partitional; +using Sa.Partitional.PostgreSql; + +namespace Sa.Outbox.PostgreSql.Partitional; + +internal class OutboxMigrationSupport(IOutboxPartitionalSupport? partitionalSupport = null) : IPartTableMigrationSupport +{ + public async Task GetPartValues(CancellationToken cancellationToken) + { + if (partitionalSupport == null) return []; + + IReadOnlyCollection parts = await partitionalSupport.GetPartValues(cancellationToken); + + return parts + .Select(c => new StrOrNum[] { c.TenantId, c.Part }) + .ToArray(); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Partitional/Setup.cs b/src/Sa.Outbox.PostgreSql/Partitional/Setup.cs new file mode 100644 index 0000000..58935c8 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Partitional/Setup.cs @@ -0,0 +1,66 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Partitional.PostgreSql; + +namespace Sa.Outbox.PostgreSql.Partitional; + +internal static class Setup +{ + public static IServiceCollection AddOutboxPartitional(this IServiceCollection services) + { + services.TryAddSingleton(); + + services.AddPartitional((sp, builder) => + { + SqlOutboxTemplate sql = sp.GetRequiredService(); + IPartTableMigrationSupport? migrationSupport = sp.GetService(); + + builder.AddSchema(sql.DatabaseSchemaName, schema => + { + ITableBuilder outboxTableBuilder = schema + .AddTable(sql.DatabaseOutboxTableName, SqlOutboxTemplate.OutboxFields) + .PartByList("outbox_tenant", "outbox_part") + .TimestampAs("outbox_created_at") + .AddPostSql(() => sql.SqlCreateTypeTable) + ; + + ITableBuilder deliveryTableBuilder = schema + .AddTable(sql.DatabaseDeliveryTableName, SqlOutboxTemplate.DeliveryFields) + .PartByList("delivery_tenant", "delivery_part") + .TimestampAs("delivery_created_at") + ; + + ITableBuilder errorTableBuilder = schema + .AddTable(sql.DatabaseErrorTableName, SqlOutboxTemplate.ErrorFields) + .TimestampAs("error_created_at") + ; + + if (migrationSupport != null) + { + outboxTableBuilder.AddMigration(migrationSupport); + deliveryTableBuilder.AddMigration(migrationSupport); + } + + errorTableBuilder.AddMigration(); + }) + ; + }) + .AddPartMigrationSchedule((sp, opts) => + { + PgOutboxMigrationSettings settings = sp.GetRequiredService(); + opts.AsJob = settings.AsJob; + opts.ExecutionInterval = settings.ExecutionInterval; + opts.ForwardDays = settings.ForwardDays; + }) + .AddPartCleanupSchedule((sp, opts) => + { + PgOutboxCleanupSettings settings = sp.GetRequiredService(); + opts.AsJob = settings.AsJob; + opts.ExecutionInterval = settings.ExecutionInterval; + opts.DropPartsAfterRetention = settings.DropPartsAfterRetention; + }) + ; + + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Readme.md b/src/Sa.Outbox.PostgreSql/Readme.md new file mode 100644 index 0000000..8ec6622 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Readme.md @@ -0,0 +1,118 @@ +# Sa.Outbox.PostgreSql + +Предназначен для реализации паттерна Outbox с использованием PostgreSQL, который используется для обеспечения надежной доставки сообщений в распределенных системах. Он помогает избежать потери сообщений и гарантирует, что сообщения будут обработаны даже в случае сбоев. + +## Основные функции +- **Надежная доставка сообщений**: Обеспечивает сохранение сообщений в базе данных до их успешной обработки. +- **Поддержка транзакций**: Позволяет отправлять сообщения в рамках одной транзакции с изменениями в базе данных. +- **Гибкость**: Поддерживает различные типы сообщений и их обработчиков. +- **Параллельная обработка**: Позволяет обрабатывать сообщения параллельно, что увеличивает производительность системы. + + + +## Примеры + +### Пример конфигурирования + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox; +using Sa.Outbox.PostgreSql; + +public class Startup +{ + public void ConfigureServices(IServiceCollection services) + { + // Конфигурация Outbox + services.AddOutbox(builder => + { + builder.WithDeliveries(deliveryBuilder => + { + deliveryBuilder.AddDelivery(); + }); + + builder.WithPartitioningSupport((serviceProvider, partSettings) => + { + // Пример настройки для обработки сообщений для каждого арендатора + partSettings.ForEachTenant = true; + partSettings.GetTenantIds = async cancellationToken => + { + // Логика получения идентификаторов арендаторов + return await Task.FromResult(new int[] { 1, 2 }); + }; + }); + }); + + // Подключение Outbox с использованием PostgreSQL + services.AddOutboxUsingPostgreSql(cfg => + { + cfg.AddDataSource(c => c.WithConnectionString("Host=my_host;Database=my_db;Username=my_user;Password=my_password")); + cfg.WithPgOutboxSettings((_, settings) => + { + // Установка схемы базы данных + settings.TableSettings.DatabaseSchemaName = "public"; + // Настройка очистки + settings.CleanupSettings.DropPartsAfterRetention = TimeSpan.FromDays(30); + }); + }); + } +} +``` + +### Пример потребителя сообщений + +```csharp +using Sa.Outbox; + +namespace MyNamespace +{ + // Пример сообщения, которое будет отправляться через Outbox + [OutboxMessage] + public record MyMessage(string PayloadId, string Content) : IOutboxPayloadMessage + { + public int TenantId { get; init; } // Идентификатор арендатора + } + + // Пример потребителя, который будет обрабатывать сообщения MyMessage + public class MyMessageConsumer : IConsumer + { + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + foreach (var messageContext in outboxMessages) + { + // Логика обработки сообщения + Console.WriteLine($"Processing message with ID: {messageContext.Payload.PayloadId} and Content: {messageContext.Payload.Content}"); + + // Успешная обработка сообщения + messageContext.Ok("Message processed successfully."); + } + } + } +} +``` + +### Пример отправки сообщения + +```csharp + +public class MessageSender(IOutboxMessagePublisher publisher) +{ + public async Task SendMessagesAsync(CancellationToken cancellationToken) + { + // Создание списка сообщений для отправки + var messages = new List + { + new MyMessage { PayloadId = Guid.NewGuid().ToString(), Content = "Hello, World!", TenantId = 1 }, + new MyMessage { PayloadId = Guid.NewGuid().ToString(), Content = "Another message", TenantId = 2 } + }; + + // Отправка сообщений через Outbox + ulong result = await publisher.Publish(messages, cancellationToken); + + Console.WriteLine($"Sent {result} messages."); + } +} + +``` + + diff --git a/src/Sa.Outbox.PostgreSql/Repository/DeliveryRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/DeliveryRepository.cs new file mode 100644 index 0000000..9101978 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/DeliveryRepository.cs @@ -0,0 +1,47 @@ +using Sa.Outbox.PostgreSql.Commands; + +namespace Sa.Outbox.PostgreSql.Repository; + +internal class DeliveryRepository( + IStartDeliveryCommand startCmd + , IErrorDeliveryCommand errorCmd + , IFinishDeliveryCommand finishCmd + , IExtendDeliveryCommand extendCmd + , IOutboxPartRepository partRepository +) : IDeliveryRepository +{ + public Task StartDelivery(Memory> writeBuffer, int batchSize, TimeSpan lockDuration, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) return Task.FromResult(0); + return startCmd.Execute(writeBuffer, batchSize, lockDuration, filter, cancellationToken); + } + + public async Task FinishDelivery(IOutboxContext[] outboxMessages, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + IReadOnlyDictionary errors = await GetErrors(outboxMessages, cancellationToken); + + IEnumerable parts = outboxMessages + .Select(c => new OutboxPartInfo(c.PartInfo.TenantId, c.PartInfo.Part, c.DeliveryResult.CreatedAt)); + + await partRepository.EnsureDeliveryParts(parts, cancellationToken); + + return await finishCmd.Execute(outboxMessages, errors, filter, cancellationToken); + } + + private async Task> GetErrors(IOutboxContext[] outboxMessages, CancellationToken cancellationToken) + { + IEnumerable errOnDates = outboxMessages + .Where(m => m.Exception != null) + .Select(m => m.DeliveryResult.CreatedAt); + + await partRepository.EnsureErrorParts(errOnDates, cancellationToken); + + IReadOnlyDictionary errors = await errorCmd.Execute(outboxMessages, cancellationToken); + return errors; + } + + public async Task ExtendDelivery(TimeSpan lockExpiration, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + return await extendCmd.Execute(lockExpiration, filter, cancellationToken); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/IMsgTypeRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/IMsgTypeRepository.cs new file mode 100644 index 0000000..d972142 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/IMsgTypeRepository.cs @@ -0,0 +1,7 @@ +namespace Sa.Outbox.PostgreSql.Repository; + +internal interface IMsgTypeRepository +{ + Task Insert(long id, string typeName, CancellationToken cancellationToken); + Task> SelectAll(CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/IOutboxPartRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/IOutboxPartRepository.cs new file mode 100644 index 0000000..914a0f7 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/IOutboxPartRepository.cs @@ -0,0 +1,11 @@ + +namespace Sa.Outbox.PostgreSql.Repository; + +internal interface IOutboxPartRepository +{ + Task EnsureDeliveryParts(IEnumerable outboxParts, CancellationToken cancellationToken); + Task EnsureOutboxParts(IEnumerable outboxParts, CancellationToken cancellationToken); + Task EnsureErrorParts(IEnumerable dates, CancellationToken cancellationToken); + + Task Migrate(); +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/MsgTypeRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/MsgTypeRepository.cs new file mode 100644 index 0000000..f82e558 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/MsgTypeRepository.cs @@ -0,0 +1,24 @@ +using Sa.Data.PostgreSql; +using System.Data; + +namespace Sa.Outbox.PostgreSql.Repository; + + +internal class MsgTypeRepository(IPgDataSource dataSource, SqlOutboxTemplate template) : IMsgTypeRepository +{ + public Task Insert(long id, string typeName, CancellationToken cancellationToken) + { + return dataSource.ExecuteNonQuery(template.SqlInsertType, [ + new ("type_id", id) + , new ("type_name", typeName) + ], cancellationToken); + } + + public Task> SelectAll(CancellationToken cancellationToken) + { + return dataSource.ExecuteReaderList(template.SqlSelectType, + reader => + (id: reader.GetInt64("type_id"), typeName: reader.GetString("type_name")) + , cancellationToken); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/OutboxPartRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/OutboxPartRepository.cs new file mode 100644 index 0000000..4181a49 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/OutboxPartRepository.cs @@ -0,0 +1,42 @@ +using Sa.Extensions; +using Sa.Partitional.PostgreSql; + +namespace Sa.Outbox.PostgreSql.Repository; + +internal class OutboxPartRepository(IPartitionManager partManager, PgOutboxTableSettings tableSettings) + : IOutboxPartRepository +{ + + public Task EnsureDeliveryParts(IEnumerable outboxParts, CancellationToken cancellationToken) + => EnsureParts(tableSettings.DatabaseDeliveryTableName, outboxParts, cancellationToken); + + public Task EnsureOutboxParts(IEnumerable outboxParts, CancellationToken cancellationToken) + => EnsureParts(tableSettings.DatabaseOutboxTableName, outboxParts, cancellationToken); + + public async Task EnsureErrorParts(IEnumerable dates, CancellationToken cancellationToken) + { + int i = 0; + foreach (DateTimeOffset date in dates.Select(c => c.StartOfDay()).Distinct()) + { + i++; + await partManager.EnsureParts(tableSettings.DatabaseErrorTableName, date, [], cancellationToken); + } + + return i; + } + + public Task Migrate() => partManager.Migrate(CancellationToken.None); + + + private async Task EnsureParts(string databaseTableName, IEnumerable outboxParts, CancellationToken cancellationToken) + { + int i = 0; + foreach (OutboxPartInfo part in outboxParts.Distinct()) + { + i++; + await partManager.EnsureParts(databaseTableName, part.CreatedAt, [part.TenantId, part.Part], cancellationToken); + } + + return i; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/OutboxRepository.cs b/src/Sa.Outbox.PostgreSql/Repository/OutboxRepository.cs new file mode 100644 index 0000000..b96bd55 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/OutboxRepository.cs @@ -0,0 +1,18 @@ +using Sa.Extensions; +using Sa.Outbox.PostgreSql.Commands; + +namespace Sa.Outbox.PostgreSql.Repository; + +internal class OutboxRepository(IOutboxBulkCommand bulkCmd, IOutboxPartRepository partRepository) + : IOutboxRepository +{ + public async ValueTask Save(string payloadType, ReadOnlyMemory> messages, CancellationToken cancellationToken = default) + { + if (messages.Length == 0) return 0; + + OutboxPartInfo[] parts = messages.Span.SelectWhere(c => c.PartInfo); + await partRepository.EnsureOutboxParts(parts, cancellationToken); + + return await bulkCmd.BulkWrite(payloadType, messages, cancellationToken); + } +} diff --git a/src/Sa.Outbox.PostgreSql/Repository/Setup.cs b/src/Sa.Outbox.PostgreSql/Repository/Setup.cs new file mode 100644 index 0000000..388d634 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Repository/Setup.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Outbox.PostgreSql.Repository; + +internal static class Setup +{ + public static IServiceCollection AddOutboxMessageRepository(this IServiceCollection services) + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Sa.Outbox.PostgreSql.csproj b/src/Sa.Outbox.PostgreSql/Sa.Outbox.PostgreSql.csproj new file mode 100644 index 0000000..5763403 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Sa.Outbox.PostgreSql.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Sa.Outbox.PostgreSql/Serialization/IOutboxMessageSerializer.cs b/src/Sa.Outbox.PostgreSql/Serialization/IOutboxMessageSerializer.cs new file mode 100644 index 0000000..beb9428 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Serialization/IOutboxMessageSerializer.cs @@ -0,0 +1,12 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Sa.Outbox.PostgreSql.Serialization; + +public interface IOutboxMessageSerializer +{ + T? Deserialize(Stream stream); + Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default); + + void Serialize(Stream stream, [NotNull] T value); + Task SerializeAsync(Stream stream, [NotNull] T value, CancellationToken cancellationToken = default); +} diff --git a/src/Sa.Outbox.PostgreSql/Serialization/OutboxMessageSerializer.cs b/src/Sa.Outbox.PostgreSql/Serialization/OutboxMessageSerializer.cs new file mode 100644 index 0000000..f8e9896 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Serialization/OutboxMessageSerializer.cs @@ -0,0 +1,56 @@ +using Sa.Serialization.Converter; +using System.Diagnostics.CodeAnalysis; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Unicode; + +namespace Sa.Outbox.PostgreSql.Serialization; + +/// +/// Implementation of using . +/// +internal class OutboxMessageSerializer : IOutboxMessageSerializer +{ + + private readonly static JavaScriptEncoder encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic); + + + /// + /// options for the JSON serializer. By default adds converter. + /// + public JsonSerializerOptions Options { get; private set; } = CreateDefaultOptions(); + + public OutboxMessageSerializer WithOptions(JsonSerializerOptions? options) + { + if (options != null) + { + Options = options; + } + return this; + } + + public static JsonSerializerOptions CreateDefaultOptions() + { + JsonSerializerOptions options = new(JsonSerializerDefaults.Web) + { + WriteIndented = false, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + AllowTrailingCommas = true, + Encoder = encoder, + }; + options.Converters.Add(new ObjectToInferredTypesConverter()); + return options; + } + + public Task DeserializeAsync(Stream stream, CancellationToken cancellationToken = default) + => JsonSerializer.DeserializeAsync(stream, Options, cancellationToken).AsTask(); + + public T? Deserialize(Stream stream) => JsonSerializer.Deserialize(stream, Options); + + + public Task SerializeAsync(Stream stream, [NotNull] T value, CancellationToken cancellationToken = default) + => JsonSerializer.SerializeAsync(stream, value ?? throw new ArgumentNullException(nameof(value)), Options, cancellationToken); + + public void Serialize(Stream stream, [NotNull] T value) => JsonSerializer.Serialize(stream, value ?? throw new ArgumentNullException(nameof(value)), Options); +} diff --git a/src/Sa.Outbox.PostgreSql/Serialization/Setup.cs b/src/Sa.Outbox.PostgreSql/Serialization/Setup.cs new file mode 100644 index 0000000..2cabf7a --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Serialization/Setup.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Outbox.PostgreSql.Serialization; + +public static class Setup +{ + public static IServiceCollection AddOutboxMessageSerializer(this IServiceCollection services, PgOutboxSerializeSettings? settings = null) + { + services.TryAddSingleton(sp + => new OutboxMessageSerializer().WithOptions((settings ?? sp.GetRequiredService()).JsonSerializerOptions)); + return services; + } +} diff --git a/src/Sa.Outbox.PostgreSql/Setup.cs b/src/Sa.Outbox.PostgreSql/Setup.cs new file mode 100644 index 0000000..a2f0e0c --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/Setup.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Outbox.PostgreSql.Commands; +using Sa.Outbox.PostgreSql.Configuration; +using Sa.Outbox.PostgreSql.IdGen; +using Sa.Outbox.PostgreSql.Interceptors; +using Sa.Outbox.PostgreSql.Partitional; +using Sa.Outbox.PostgreSql.Repository; +using Sa.Outbox.PostgreSql.Serialization; +using Sa.Outbox.PostgreSql.TypeHashResolve; + +namespace Sa.Outbox.PostgreSql; + +public static class Setup +{ + public static IServiceCollection AddOutboxUsingPostgreSql(this IServiceCollection services, Action? configure = null) + { + services + .AddSaInfrastructure(); + + services.TryAddSingleton(); + + services + .AddPgOutboxSettings(configure); + + services + .AddOutboxMessageRepository() + .AddOutboxMessageSerializer() + .AddOutboxPartitional() + .AddIdGen() + .AddOutboxCommands() + .AddMsgTypeHashResolver() + .AddOutboxJobInterceptors() + ; + + services.AddOutbox(); + + return services; + } +} \ No newline at end of file diff --git a/src/Sa.Outbox.PostgreSql/SqlOutboxTemplate.cs b/src/Sa.Outbox.PostgreSql/SqlOutboxTemplate.cs new file mode 100644 index 0000000..4e63e65 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/SqlOutboxTemplate.cs @@ -0,0 +1,260 @@ +namespace Sa.Outbox.PostgreSql; + +internal class SqlOutboxTemplate(PgOutboxTableSettings settings) +{ + public string DatabaseSchemaName => settings.DatabaseSchemaName; + public string DatabaseOutboxTableName => settings.DatabaseOutboxTableName; + public string DatabaseDeliveryTableName => settings.DatabaseDeliveryTableName; + public string DatabaseErrorTableName => settings.DatabaseErrorTableName; + + + public readonly static string[] OutboxFields = + [ + // ulid + "outbox_id CHAR(26) NOT NULL", + + // -- parts + outbox_created_at + "outbox_tenant INT NOT NULL DEFAULT 0", + "outbox_part TEXT NOT NULL", + + "outbox_payload_id TEXT NOT NULL", + "outbox_payload_type BIGINT NOT NULL", + "outbox_payload BYTEA NOT NULL", + "outbox_payload_size INT NOT NULL", + + // -- rw + "outbox_transact_id TEXT NOT NULL DEFAULT ''", + "outbox_lock_expires_on BIGINT NOT NULL DEFAULT 0", + + // -- delivery + "outbox_delivery_attempt int NOT NULL DEFAULT 0", + // --- copy last + "outbox_delivery_id CHAR(26) NOT NULL DEFAULT ''", + "outbox_delivery_error_id TEXT NOT NULL DEFAULT ''", + "outbox_delivery_status_code INT NOT NULL DEFAULT 0", + "outbox_delivery_status_message TEXT NOT NULL DEFAULT ''", + "outbox_delivery_created_at BIGINT NOT NULL DEFAULT 0" + ]; + + + public readonly static string[] DeliveryFields = + [ + "delivery_id CHAR(26) NOT NULL", + "delivery_outbox_id CHAR(26) NOT NULL", + "delivery_error_id TEXT NOT NULL DEFAULT ''", + "delivery_status_code INT NOT NULL DEFAULT 0", + "delivery_status_message TEXT NOT NULL DEFAULT ''", + "delivery_transact_id TEXT NOT NULL DEFAULT ''", + "delivery_lock_expires_on BIGINT NOT NULL DEFAULT 0", + // - parts + "delivery_tenant INT NOT NULL DEFAULT 0", + "delivery_part TEXT NOT NULL", + ]; + + // Delivery errors + public readonly static string[] ErrorFields = + [ + "error_id BIGINT NOT NULL", + "error_type TEXT NOT NULL", + "error_message TEXT NOT NULL", + ]; + + + //CREATE INDEX IF NOT EXISTS ix_{DatabaseTableName}__payload_id + // ON {GetQualifiedTableName()} (payload_id) + // WHERE payload_id <> '' AND (outbox_delivery_status_code BETWEEN {DeliveryStatusCode.Ok} AND 299 OR outbox_delivery_status_code >= 500) + + //CREATE INDEX IF NOT EXISTS ix_{DatabaseTableName}__payload_type + // ON {GetQualifiedTableName()} (payload_type); + // WHERE (outbox_delivery_status_code < {DeliveryStatusCode.Ok} OR outbox_delivery_status_code BETWEEN 300 AND 499) + //"""; + + + public string SqlBulkOutboxCopy = +$""" +COPY {settings.GetQualifiedOutboxTableName()} ( + outbox_id + ,outbox_tenant + ,outbox_part + ,outbox_payload_id + ,outbox_payload_type + ,outbox_payload + ,outbox_payload_size + ,outbox_created_at +) +FROM STDIN (FORMAT BINARY) +; +"""; + + + static readonly string s_InProcessing = $"(outbox_delivery_status_code < {DeliveryStatusCode.Ok} OR outbox_delivery_status_code BETWEEN {DeliveryStatusCode.Status300} AND {DeliveryStatusCode.Status499})"; + + + public string SqlLockAndSelect = +$""" +WITH next_task AS ( + SELECT outbox_id FROM {settings.GetQualifiedOutboxTableName()} + WHERE + outbox_tenant = @tenant AND outbox_part = @part AND outbox_created_at >= @from_date + AND outbox_payload_type = @payload_type + AND {s_InProcessing} + AND outbox_lock_expires_on < @now + LIMIT @limit + FOR UPDATE SKIP LOCKED +) +UPDATE {settings.GetQualifiedOutboxTableName()} +SET + outbox_delivery_status_code = CASE + WHEN outbox_delivery_status_code = 0 THEN {DeliveryStatusCode.Processing} + ELSE outbox_delivery_status_code + END + ,outbox_transact_id = @transact_id + ,outbox_lock_expires_on = @lock_expires_on +FROM + next_task +WHERE + {settings.GetQualifiedOutboxTableName()}.outbox_id = next_task.outbox_id +RETURNING + {settings.GetQualifiedOutboxTableName()}.outbox_id + ,outbox_tenant + ,outbox_part + ,outbox_payload + ,outbox_payload_id + ,outbox_delivery_id + ,outbox_delivery_attempt + ,outbox_delivery_error_id + ,outbox_delivery_status_code + ,outbox_delivery_status_message + ,outbox_delivery_created_at + ,outbox_created_at +; +"""; + + + private static string SqlFinishDelivery(PgOutboxTableSettings settings, int count) + { + return +$""" +WITH inserted_delivery AS ( + INSERT INTO {settings.GetQualifiedDeliveryTableName()} ( + delivery_id + , delivery_outbox_id + , delivery_error_id + , delivery_status_code + , delivery_status_message + , delivery_lock_expires_on + , delivery_transact_id + , delivery_tenant + , delivery_part + , delivery_created_at + ) + VALUES +{BuildDeliveryInsertValues(count)} + ON CONFLICT DO NOTHING + RETURNING * +) +UPDATE {settings.GetQualifiedOutboxTableName()} +SET + outbox_delivery_id = inserted_delivery.delivery_id + , outbox_delivery_attempt = outbox_delivery_attempt + CASE + WHEN inserted_delivery.delivery_status_code <> {DeliveryStatusCode.Postpone} THEN 1 + ELSE 0 + END + , outbox_delivery_error_id = inserted_delivery.delivery_error_id + , outbox_delivery_status_code = inserted_delivery.delivery_status_code + , outbox_delivery_status_message = inserted_delivery.delivery_status_message + , outbox_lock_expires_on = inserted_delivery.delivery_lock_expires_on + , outbox_delivery_created_at = inserted_delivery.delivery_created_at +FROM + inserted_delivery +WHERE + outbox_tenant = @tnt + AND outbox_part = @prt + AND outbox_created_at >= @from_date + AND outbox_transact_id = @tid + AND outbox_id = inserted_delivery.delivery_outbox_id +; + +"""; + } + + private static string BuildDeliveryInsertValues(int count) + { + List values = []; + int j = 0; + for (int i = 0; i < count; i++) + { + // @id_{i},@outbox_id_{i},@error_id_{i},@status_code_{i},@status_message_{i},@lock_expires_on_{i},@created_at_{i} + values.Add($" (@p{j++},@p{j++},@p{j++},@p{j++},@p{j++},@p{j++},@tid,@tnt,@prt,@p{j++})"); + } + return string.Join(",\r\n", values); + } + + + public string SqlExtendDelivery = +$""" +UPDATE {settings.GetQualifiedOutboxTableName()} +SET + outbox_lock_expires_on = @lock_expires_on +WHERE + outbox_tenant = @tenant AND outbox_part = @part AND outbox_created_at >= @from_date + AND outbox_payload_type = @payload_type + AND {s_InProcessing} + AND outbox_transact_id = @transact_id + AND outbox_lock_expires_on > @now +FOR UPDATE SKIP LOCKED +; +"""; + + + public string SqlFinishDelivery(int count) => SqlFinishDelivery(settings, count); + + + public string SqlCreateTypeTable + = +$""" +CREATE TABLE IF NOT EXISTS {settings.GetQualifiedTypeTableName()} +( + type_id BIGINT NOT NULL, + type_name TEXT NOT NULL, + CONSTRAINT "pk_{settings.DatabaseTypeTableName}" PRIMARY KEY (type_id) +) +; +"""; + + + public string SqlSelectType = $"SELECT * FROM {settings.GetQualifiedTypeTableName()}"; + + public string SqlInsertType = +$""" +INSERT INTO {settings.GetQualifiedTypeTableName()} + (type_id, type_name) +VALUES + (@type_id,@type_name) +ON CONFLICT DO NOTHING +; +"""; + + + private static string BuildErrorInsertValues(int count) + { + List values = []; + for (int i = 0; i < count; i++) + { + values.Add($" (@id_{i},@type_{i},@message_{i},@created_at_{i})"); + } + return string.Join(",\r\n", values); + } + + private static string SqlError(PgOutboxTableSettings settings, int count) => +$""" +INSERT INTO {settings.GetQualifiedErrorTableName()} + (error_id,error_type,error_message,error_created_at) +VALUES +{BuildErrorInsertValues(count)} +ON CONFLICT DO NOTHING +; +"""; + + public string SqlError(int count) => SqlError(settings, count); +} diff --git a/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeCache.cs b/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeCache.cs new file mode 100644 index 0000000..4c231c1 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeCache.cs @@ -0,0 +1,9 @@ + +namespace Sa.Outbox.PostgreSql.TypeHashResolve; + +internal interface IMsgTypeCache +{ + ValueTask GetCode(string typeName, CancellationToken cancellationToken); + ValueTask GetTypeName(long code, CancellationToken cancellationToken); + ValueTask Reset(CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeHashResolver.cs b/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeHashResolver.cs new file mode 100644 index 0000000..a2d4954 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/TypeHashResolve/IMsgTypeHashResolver.cs @@ -0,0 +1,7 @@ +namespace Sa.Outbox.PostgreSql.TypeHashResolve; + +internal interface IMsgTypeHashResolver +{ + ValueTask GetCode(string typeName, CancellationToken cancellationToken); + ValueTask GetTypeName(long typeCode, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeCache.cs b/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeCache.cs new file mode 100644 index 0000000..32da900 --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeCache.cs @@ -0,0 +1,77 @@ +using Sa.Outbox.PostgreSql.Repository; +using ZiggyCreatures.Caching.Fusion; + +namespace Sa.Outbox.PostgreSql.TypeHashResolve; + +internal sealed class MsgTypeCache( + IFusionCacheProvider cacheProvider + , IMsgTypeRepository repository + , PgOutboxCacheSettings cacheSettings) + : IDisposable, IMsgTypeCache +{ + internal static class Env + { + public const string CacheName = "sa-msgtype"; + } + + private readonly IFusionCache _cache = cacheProvider.GetCache(Env.CacheName); + + internal class Storage + { + private readonly Dictionary _hashType = []; + private readonly Dictionary _typeHash = []; + + internal Storage(List<(long id, string typeName)> hashCodes) + { + foreach (var (id, typeName) in hashCodes) + { + _hashType[id] = typeName; + _typeHash[typeName] = id; + } + } + + public long GetCode(string typeName) + { + if (_typeHash.TryGetValue(typeName, out var code)) return code; + return 0; + } + + public string? GetType(long code) + { + if (_hashType.TryGetValue(code, out var name)) return name; + return default; + } + } + + public async ValueTask GetCode(string typeName, CancellationToken cancellationToken) + { + var storage = await GetStorage(cancellationToken); + return storage.GetCode(typeName); + } + + public async ValueTask GetTypeName(long code, CancellationToken cancellationToken) + { + var storage = await GetStorage(cancellationToken); + return storage.GetType(code); + } + + public ValueTask Reset(CancellationToken cancellationToken) => _cache.RemoveAsync(Env.CacheName, token: cancellationToken); + + private ValueTask GetStorage(CancellationToken cancellationToken) + { + return _cache.GetOrSetAsync( + Env.CacheName + , async (context, t) => await Load(context, t) + , options: null + , token: cancellationToken); + } + + private async Task Load(FusionCacheFactoryExecutionContext context, CancellationToken cancellationToken) + { + List<(long id, string typeName)> hashCodes = await repository.SelectAll(cancellationToken); + context.Options.Duration = hashCodes.Count > 0 ? cacheSettings.CacheTypeDuration : TimeSpan.Zero; + return new Storage(hashCodes); + } + + public void Dispose() => _cache.Dispose(); +} diff --git a/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeHashResolver.cs b/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeHashResolver.cs new file mode 100644 index 0000000..2524f0a --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/TypeHashResolve/MsgTypeHashResolver.cs @@ -0,0 +1,44 @@ +using Sa.Extensions; +using Sa.Outbox.PostgreSql.Repository; + +namespace Sa.Outbox.PostgreSql.TypeHashResolve; + + +internal class MsgTypeHashResolver(IMsgTypeCache cache, IMsgTypeRepository repository) : IMsgTypeHashResolver +{ + private int _triggered = 0; + + public async ValueTask GetCode(string typeName, CancellationToken cancellationToken) + { + + long code = await cache.GetCode(typeName, cancellationToken); + + if (code != 0) return code; + + code = typeName.GetMurmurHash3(); + + if (Interlocked.CompareExchange(ref _triggered, 1, 0) == 1) return code; + + try + { + await repository.Insert(code, typeName, cancellationToken); + await cache.Reset(cancellationToken); + } + finally + { + Interlocked.CompareExchange(ref _triggered, 0, 1); + } + + return code; + } + + public async ValueTask GetTypeName(long typeCode, CancellationToken cancellationToken) + { + string? typeName = await cache.GetTypeName(typeCode, cancellationToken); + if (typeName != null) return typeName; + + await cache.Reset(cancellationToken); + + return await cache.GetTypeName(typeCode, cancellationToken) ?? typeCode.ToString(); + } +} diff --git a/src/Sa.Outbox.PostgreSql/TypeHashResolve/Setup.cs b/src/Sa.Outbox.PostgreSql/TypeHashResolve/Setup.cs new file mode 100644 index 0000000..9609aec --- /dev/null +++ b/src/Sa.Outbox.PostgreSql/TypeHashResolve/Setup.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Data.Cache; + +namespace Sa.Outbox.PostgreSql.TypeHashResolve; + +internal static class Setup +{ + public static IServiceCollection AddMsgTypeHashResolver(this IServiceCollection services) + { + services.AddFusionCacheEx(MsgTypeCache.Env.CacheName, (sp, opts) => + { + PgOutboxCacheSettings cacheSettings = sp.GetRequiredService(); + opts.Duration = cacheSettings.CacheTypeDuration; + }); + + + services.TryAddSingleton(); + services.TryAddSingleton(); + + return services; + } +} \ No newline at end of file diff --git a/src/Sa.Outbox/Configuration/DeliveryBuilder.cs b/src/Sa.Outbox/Configuration/DeliveryBuilder.cs new file mode 100644 index 0000000..ca47401 --- /dev/null +++ b/src/Sa.Outbox/Configuration/DeliveryBuilder.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Job; + +namespace Sa.Outbox.Configuration; + +internal class DeliveryBuilder(IServiceCollection services) : IDeliveryBuilder +{ + public IDeliveryBuilder AddDelivery(Action? configure = null, int instanceCount = 1) + where TConsumer : class, IConsumer + { + services.AddDeliveryJob(configure, instanceCount); + return this; + } +} diff --git a/src/Sa.Outbox/Configuration/IDeliveryBuilder.cs b/src/Sa.Outbox/Configuration/IDeliveryBuilder.cs new file mode 100644 index 0000000..a8a19a0 --- /dev/null +++ b/src/Sa.Outbox/Configuration/IDeliveryBuilder.cs @@ -0,0 +1,19 @@ +namespace Sa.Outbox; + + +/// +/// Represents a builder for creating outbox deliveries. +/// +public interface IDeliveryBuilder +{ + /// + /// Adds a delivery for the specified consumer and message type. + /// + /// The type of consumer. + /// The type of message. + /// An optional action to configure the delivery settings. + /// The number of instances to create for the delivery. + /// The delivery builder instance. + IDeliveryBuilder AddDelivery(Action? configure = null, int instanceCount = 1) + where TConsumer : class, IConsumer; +} \ No newline at end of file diff --git a/src/Sa.Outbox/Configuration/IOutboxBuilder.cs b/src/Sa.Outbox/Configuration/IOutboxBuilder.cs new file mode 100644 index 0000000..7db49d8 --- /dev/null +++ b/src/Sa.Outbox/Configuration/IOutboxBuilder.cs @@ -0,0 +1,19 @@ +namespace Sa.Outbox; + +public interface IOutboxBuilder +{ + OutboxPublishSettings PublishSettings { get; } + /// + /// Configures the delivery settings for the outbox. + /// + /// An action to configure the delivery settings. + /// The current instance of the IOutboxSettingsBuilder. + IOutboxBuilder WithDeliveries(Action build); + + /// + /// Enables partitioning support for the outbox. + /// + /// An action to configure the partitioning settings. + /// The current instance of the IOutboxSettingsBuilder. + IOutboxBuilder WithPartitioningSupport(Action configure); +} \ No newline at end of file diff --git a/src/Sa.Outbox/Configuration/OutboxBuilder.cs b/src/Sa.Outbox/Configuration/OutboxBuilder.cs new file mode 100644 index 0000000..dfc1bda --- /dev/null +++ b/src/Sa.Outbox/Configuration/OutboxBuilder.cs @@ -0,0 +1,34 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Outbox.Delivery; +using Sa.Outbox.Partitional; +using Sa.Outbox.Publication; + +namespace Sa.Outbox.Configuration; + +internal class OutboxBuilder : IOutboxBuilder +{ + private readonly IServiceCollection services; + + public OutboxBuilder(IServiceCollection services) + { + this.services = services; + services.AddSaInfrastructure(); + services.AddMessagePublisher(); + services.TryAddSingleton(this.PublishSettings); + } + + public OutboxPublishSettings PublishSettings { get; } = new(); + + public IOutboxBuilder WithDeliveries(Action build) + { + services.AddOutboxDelivery(build); + return this; + } + + public IOutboxBuilder WithPartitioningSupport(Action configure) + { + services.AddPartitioningSupport(configure); + return this; + } +} diff --git a/src/Sa.Outbox/Configuration/OutboxSettings.cs b/src/Sa.Outbox/Configuration/OutboxSettings.cs new file mode 100644 index 0000000..e83632f --- /dev/null +++ b/src/Sa.Outbox/Configuration/OutboxSettings.cs @@ -0,0 +1,109 @@ +namespace Sa.Outbox; + + +/// +/// Settings for publishing messages from the Outbox. +/// +public class OutboxPublishSettings +{ + /// + /// The maximum batch size of messages to be sent at once. + /// Default value: 16. + /// for array pool size: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 + /// + public int MaxBatchSize { get; set; } = 64; +} + + +/// +/// Indicates that this is a configuration for message delivery in the Outbox. +/// +public class OutboxDeliverySettings(Guid jobId, int instanceIndex = 0) +{ + /// + /// Gets the unique identifier for the delivery job + /// + public Guid JobId => jobId; + /// + /// Indicates the index of the worker instance. + /// + public int WorkerInstanceIndex => instanceIndex; + /// + /// Gets the scheduling settings for the delivery job. + /// + public ScheduleSettings ScheduleSettings { get; } = new(); + /// + /// Gets the extraction settings for retrieving messages from the Outbox. + /// + public ExtractSettings ExtractSettings { get; } = new(); + /// + /// Gets the consumption settings for processing messages. + /// + public ConsumeSettings ConsumeSettings { get; } = new(); +} + +/// +/// Represents the scheduling settings for the delivery job. +/// +public class ScheduleSettings +{ + public string? Name { get; set; } + public TimeSpan ExecutionInterval { get; set; } = TimeSpan.FromMinutes(1); + + /// + /// job schedule delay before start + /// + public TimeSpan InitialDelay { get; set; } = TimeSpan.FromSeconds(10); + + public int RetryCountOnError { get; set; } = 2; +} + +/// +/// Represents the extraction settings for retrieving messages from the Outbox. +/// +public class ExtractSettings +{ + /// + /// Gets or sets the maximum size of the Outbox message batch for each database poll. + /// for array pool size: 16, 32, 64, 128, 256, 512, 1024 ... + /// + public int MaxBatchSize { get; set; } = 16; + /// + /// Message lock expiration time. + /// When a batch of messages for a bus instance is acquired, the messages will be locked (reserved) for that amount of time. + /// + public TimeSpan LockDuration { get; set; } = TimeSpan.FromSeconds(10); + + /// + /// How long before to request a lock renewal. + /// This should be much shorter than . + /// + public TimeSpan LockRenewal { get; set; } = TimeSpan.FromSeconds(3); + + /// + /// Repeat extract for each tenant + /// + /// + public bool ForEachTenant { get; set; } + + /// + /// select outbox messages for processing for the period + /// + public TimeSpan LookbackInterval { get; set; } = TimeSpan.FromDays(7); +} + +/// +/// Represents the consumption settings for processing messages from the Outbox. +/// +public class ConsumeSettings +{ + /// + /// The maximum number of delivery attempts before delivery will not be attempted again. + /// + public int MaxDeliveryAttempts { get; set; } = 3; + /// + /// The maximum number of messages that can take in part + /// default value + /// + public int? ConsumeBatchSize { get; set; } +} diff --git a/src/Sa.Outbox/Delivery/DeliveryCourier.cs b/src/Sa.Outbox/Delivery/DeliveryCourier.cs new file mode 100644 index 0000000..815e720 --- /dev/null +++ b/src/Sa.Outbox/Delivery/DeliveryCourier.cs @@ -0,0 +1,70 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Extensions; +using Sa.Outbox.Exceptions; + +namespace Sa.Outbox.Delivery; + +internal class DeliveryCourier(IServiceProvider serviceProvider) : IDeliveryCourier +{ + + public async ValueTask Deliver(IReadOnlyCollection> outboxMessages, int maxDeliveryAttempts, CancellationToken cancellationToken) + { + try + { + using IServiceScope scope = serviceProvider.CreateScope(); + IConsumer consumer = scope.ServiceProvider.GetRequiredService>(); + await consumer.Consume(outboxMessages, cancellationToken); + } + catch (Exception ex) when (!ex.IsCritical()) + { + HandleError(ex, outboxMessages); + } + + return PostHandle(outboxMessages, maxDeliveryAttempts); + } + + private static void HandleError(Exception error, IReadOnlyCollection> outboxMessages) + { + foreach (IOutboxContext item in outboxMessages) + { + // если не было обработанных ошибок до - то... + if (item.DeliveryResult.Code == 0) + { + // "Unknown delivery error." + // раскидываем ошибки в отложенную обработку от 10 до 45 мин + item.Error(error ?? new DeliveryException("Unknown delivery error."), postpone: GenTimeSpan.Next()); + } + } + } + + private static int PostHandle(IReadOnlyCollection> messages, int maxDeliveryAttempts) + { + int iOk = 0; + foreach (IOutboxContext message in messages) + { + if (message.DeliveryResult.Code >= 400 && message.DeliveryResult.Code < 500 && message.DeliveryInfo.Attempt + 1 > maxDeliveryAttempts) + { + Exception exception = message.Exception ?? new DeliveryPermanentException("Maximum delivery attempts exceeded", statusCode: 501); + + // Устанавливаем постоянную ошибку + message.PermanentError(exception, statusCode: 501); + } + else if (message.DeliveryResult.Code == 0) + { + message.Ok(); + iOk++; + } + } + + return iOk; + } + + + static class GenTimeSpan + { + public static TimeSpan Next() + { + return TimeSpan.FromSeconds(Random.Shared.Next(60 * 10, 60 * 45)); + } + } +} \ No newline at end of file diff --git a/src/Sa.Outbox/Delivery/DeliveryProcessor.cs b/src/Sa.Outbox/Delivery/DeliveryProcessor.cs new file mode 100644 index 0000000..5f107af --- /dev/null +++ b/src/Sa.Outbox/Delivery/DeliveryProcessor.cs @@ -0,0 +1,19 @@ +namespace Sa.Outbox.Delivery; + +internal class DeliveryProcessor(IDeliveryRelay relayService) : IDeliveryProcessor +{ + public async Task ProcessMessages(OutboxDeliverySettings settings, CancellationToken cancellationToken) + { + long count = 0; + bool runAgain; + do + { + int sentCount = await relayService.StartDelivery(settings, cancellationToken); + runAgain = sentCount > 0; + count += sentCount; + } + while (runAgain && !cancellationToken.IsCancellationRequested); + + return count; + } +} diff --git a/src/Sa.Outbox/Delivery/DeliveryRelay.cs b/src/Sa.Outbox/Delivery/DeliveryRelay.cs new file mode 100644 index 0000000..c3d4590 --- /dev/null +++ b/src/Sa.Outbox/Delivery/DeliveryRelay.cs @@ -0,0 +1,135 @@ +using Sa.Classes; +using Sa.Extensions; +using Sa.Host.MessageTypeResolver; +using Sa.Outbox.Partitional; +using Sa.Outbox.Publication; +using Sa.Outbox.Repository; +using Sa.Timing.Providers; + +namespace Sa.Outbox.Delivery; + +internal sealed class DeliveryRelay( + IDeliveryRepository repository + , IMessageTypeResolver typeResolver + , IArrayPoolFactory arrayPoolFactory + , IPartitionalSupportCache partCache + , ICurrentTimeProvider timeProvider + , IDeliveryCourier deliveryCourier + , PartitionalSettings? partitionalSettings = null + ) : IDeliveryRelay +{ + + private readonly bool _globalForEachTenant = partitionalSettings?.ForEachTenant ?? false; + + public async Task StartDelivery(OutboxDeliverySettings settings, CancellationToken cancellationToken) + { + IArrayPooler> arrayPooler = arrayPoolFactory.Create>(); + + int batchSize = settings.ExtractSettings.MaxBatchSize; + + if (batchSize == 0) return 0; + + OutboxDeliveryMessage[] buffer = arrayPooler.Rent(batchSize); + Memory> slice = buffer.AsMemory(0, batchSize); + try + { + if (_globalForEachTenant || settings.ExtractSettings.ForEachTenant) + { + int count = 0; + int[] tenantIds = await partCache.GetTenantIds(cancellationToken); + foreach (int tenantId in tenantIds) + { + count += await FillBuffer(slice, settings, tenantId, cancellationToken); + } + return count; + } + else + { + return await FillBuffer(slice, settings, 0, cancellationToken); + } + } + finally + { + arrayPooler.Return(buffer); + } + } + + private async Task FillBuffer(Memory> buffer, OutboxDeliverySettings settings, int tenantId, CancellationToken cancellationToken) + { + OutboxMessageFilter filter = CreateFilter(settings, tenantId); + + int locked = await repository.StartDelivery(buffer, settings.ExtractSettings.MaxBatchSize, settings.ExtractSettings.LockDuration, filter, cancellationToken); + if (locked == 0) return locked; + + buffer = buffer[..locked]; + + using IDisposable locker = KeepLocker.KeepLocked( + settings.ExtractSettings.LockRenewal + , async t => + { + filter = ExtendFilter(filter); + await repository.ExtendDelivery(settings.ExtractSettings.LockDuration, filter, t); + } + , cancellationToken: cancellationToken + ); + + // send msgs to consumer + return await DeliverBatches(buffer, settings, filter, cancellationToken); + } + + private OutboxMessageFilter CreateFilter(OutboxDeliverySettings settings, int tenantId) + { + OutboxMessageTypeInfo ti = OutboxMessageTypeHelper.GetOutboxMessageTypeInfo(); + DateTimeOffset fromDate = timeProvider.GetUtcNow().StartOfDay() - settings.ExtractSettings.LookbackInterval; + + return new OutboxMessageFilter( + GenTransactId() + , typeResolver.ToName() + , tenantId + , ti.PartName + , fromDate + , timeProvider.GetUtcNow() + ); + } + + private OutboxMessageFilter ExtendFilter(OutboxMessageFilter filter) + { + return new OutboxMessageFilter( + filter.TransactId + , filter.PayloadType + , filter.TenantId + , filter.Part + , filter.FromDate + , timeProvider.GetUtcNow() + ); + } + + private static string GenTransactId() => $"{Environment.MachineName}-{Guid.NewGuid():N}"; + + private async Task DeliverBatches(Memory> deliveryMessages, OutboxDeliverySettings settings, OutboxMessageFilter filter, CancellationToken cancellationToken) + { + int iOk = 0; + + foreach (IOutboxContext[] outboxMessages in deliveryMessages + .GetChunks(settings.ConsumeSettings.ConsumeBatchSize ?? settings.ExtractSettings.MaxBatchSize) + .Select(chunk + => chunk.Span.SelectWhere(dm + => new OutboxContext(dm, timeProvider)))) + { + if (cancellationToken.IsCancellationRequested) break; + + iOk += await DeliveryCourier(settings, filter, outboxMessages, cancellationToken); + } + + return iOk; + } + + private async Task DeliveryCourier(OutboxDeliverySettings settings, OutboxMessageFilter filter, IOutboxContext[] outboxMessages, CancellationToken cancellationToken) + { + int iOk = await deliveryCourier.Deliver(outboxMessages, settings.ConsumeSettings.MaxDeliveryAttempts, cancellationToken); + + await repository.FinishDelivery(outboxMessages, filter, cancellationToken); + + return iOk; + } +} diff --git a/src/Sa.Outbox/Delivery/IDeliveryCourier.cs b/src/Sa.Outbox/Delivery/IDeliveryCourier.cs new file mode 100644 index 0000000..f1e5f26 --- /dev/null +++ b/src/Sa.Outbox/Delivery/IDeliveryCourier.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.Delivery; + +public interface IDeliveryCourier +{ + ValueTask Deliver(IReadOnlyCollection> outboxMessages, int maxDeliveryAttempts, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Delivery/IDeliveryProcessor.cs b/src/Sa.Outbox/Delivery/IDeliveryProcessor.cs new file mode 100644 index 0000000..2a628d6 --- /dev/null +++ b/src/Sa.Outbox/Delivery/IDeliveryProcessor.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.Delivery; + +public interface IDeliveryProcessor +{ + Task ProcessMessages(OutboxDeliverySettings settings, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Delivery/IDeliveryRelay.cs b/src/Sa.Outbox/Delivery/IDeliveryRelay.cs new file mode 100644 index 0000000..ff4507f --- /dev/null +++ b/src/Sa.Outbox/Delivery/IDeliveryRelay.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.Delivery; + +public interface IDeliveryRelay +{ + Task StartDelivery(OutboxDeliverySettings settings, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Delivery/Setup.cs b/src/Sa.Outbox/Delivery/Setup.cs new file mode 100644 index 0000000..20f358c --- /dev/null +++ b/src/Sa.Outbox/Delivery/Setup.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Outbox.Configuration; +using Sa.Outbox.Partitional; + +namespace Sa.Outbox.Delivery; + +internal static class Setup +{ + public static IServiceCollection AddOutboxDelivery(this IServiceCollection services, Action configure) + { + // looper - job processor + services.TryAddSingleton(); + // iteration - extract from repository & batch & send to courier + services.TryAddSingleton(); + // sender - sending to scope consumer + services.TryAddSingleton(); + // support - messaging to each tenant + services.TryAddSingleton(); + + configure.Invoke(new DeliveryBuilder(services)); + + return services; + } +} diff --git a/src/Sa.Outbox/DeliveryStatusCode.cs b/src/Sa.Outbox/DeliveryStatusCode.cs new file mode 100644 index 0000000..9886ece --- /dev/null +++ b/src/Sa.Outbox/DeliveryStatusCode.cs @@ -0,0 +1,61 @@ +namespace Sa.Outbox; + + + +public static class DeliveryStatusCode +{ + /// + /// Indicates that the message is pending and has not yet been processed. + /// + public const int Pending = 0; + + /// + /// Indicates that the message is currently being processed. + /// + public const int Processing = 100; + + /// + /// Indicates that the processing of the message has been postponed. + /// This may occur due to temporary conditions that prevent immediate processing. + /// + public const int Postpone = 103; + + /// + /// Indicates that the message has been processed successfully. + /// + public const int Ok = 200; + + /// + /// Indicates that the processing of the message has been aborted. + /// This may happen due to user intervention. + /// + public const int Aborted = 299; + + /// + /// Reserved for future use or specific status codes that may be defined later. + /// + public const int Status300 = 300; + + /// + /// Indicates that an error occurred during the processing of the message. + /// This may include various types of recoverable errors. + /// + public const int Error = 400; + + /// + /// Reserved for client-side errors that do not fall into other categories. + /// + public const int Status499 = 499; + + /// + /// Indicates that a permanent error has occurred, and the message cannot be processed. + /// + public const int PermanentError = 500; + + /// + /// Indicates a permanent error has occurred + /// - that the maximum number of processing attempts has been reached, + /// and the message will not be retried further. + /// + public const int MaximumAttemptsError = 501; +} diff --git a/src/Sa.Outbox/Exceptions/DeliveryException.cs b/src/Sa.Outbox/Exceptions/DeliveryException.cs new file mode 100644 index 0000000..ea99b3a --- /dev/null +++ b/src/Sa.Outbox/Exceptions/DeliveryException.cs @@ -0,0 +1,8 @@ +namespace Sa.Outbox.Exceptions; + +public class DeliveryException(string message, Exception? innerException = null, int statusCode = 400, TimeSpan? postponeAt = null) + : OutboxMessageException(message, innerException) +{ + public int StatusCode => statusCode; + public TimeSpan? PostponeAt => postponeAt; +} diff --git a/src/Sa.Outbox/Exceptions/DeliveryPermanentException.cs b/src/Sa.Outbox/Exceptions/DeliveryPermanentException.cs new file mode 100644 index 0000000..231da5d --- /dev/null +++ b/src/Sa.Outbox/Exceptions/DeliveryPermanentException.cs @@ -0,0 +1,6 @@ +namespace Sa.Outbox.Exceptions; + +public class DeliveryPermanentException(string message, Exception? innerException = null, int statusCode = 500) + : DeliveryException(message, innerException, statusCode) +{ +} diff --git a/src/Sa.Outbox/Exceptions/OutboxMessageException.cs b/src/Sa.Outbox/Exceptions/OutboxMessageException.cs new file mode 100644 index 0000000..27a5e86 --- /dev/null +++ b/src/Sa.Outbox/Exceptions/OutboxMessageException.cs @@ -0,0 +1,16 @@ +namespace Sa.Outbox.Exceptions; + +public class OutboxMessageException : Exception +{ + public OutboxMessageException() + { + } + + public OutboxMessageException(string message) : base(message) + { + } + + public OutboxMessageException(string message, Exception? innerException) : base(message, innerException) + { + } +} diff --git a/src/Sa.Outbox/GlobalSuppressions.cs b/src/Sa.Outbox/GlobalSuppressions.cs new file mode 100644 index 0000000..5935e67 --- /dev/null +++ b/src/Sa.Outbox/GlobalSuppressions.cs @@ -0,0 +1,9 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0130:Namespace does not match folder structure")] +[assembly: SuppressMessage("Minor Code Smell", "S3267:Loops should be simplified with \"LINQ\" expressions", Justification = "")] diff --git a/src/Sa.Outbox/IConsumer.cs b/src/Sa.Outbox/IConsumer.cs new file mode 100644 index 0000000..29c0f36 --- /dev/null +++ b/src/Sa.Outbox/IConsumer.cs @@ -0,0 +1,25 @@ +namespace Sa.Outbox; + +/// +/// Represents a consumer interface for processing Outbox messages of a specific type. +/// +/// The type of the message being consumed. +public interface IConsumer : IConsumer +{ + /// + /// Consumes a collection of Outbox messages. + /// This method processes the provided messages asynchronously. + /// + /// A read-only collection of Outbox contexts containing messages to be consumed. + /// A cancellation token to signal the operation's cancellation. + /// A task representing the asynchronous operation. + ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken); +} + +/// +/// Represents a base consumer interface for processing Outbox messages. +/// This interface can be extended by specific consumer implementations. +/// +public interface IConsumer +{ +} \ No newline at end of file diff --git a/src/Sa.Outbox/IOutboxMessagePluginPublisher.cs b/src/Sa.Outbox/IOutboxMessagePluginPublisher.cs new file mode 100644 index 0000000..8043e19 --- /dev/null +++ b/src/Sa.Outbox/IOutboxMessagePluginPublisher.cs @@ -0,0 +1,31 @@ +using Sa.Outbox.Support; + +namespace Sa.Outbox; + +/// +/// Defines a contract for publishing outbox messages. +/// +public interface IOutboxMessagePublisher +{ + /// + /// Publishes a collection of messages. + /// + /// The type of the messages to be published, which must implement . + /// A collection of messages to be published. + /// A token to monitor for cancellation requests. + /// A representing the asynchronous operation, + /// with the number of successfully published messages as the result. + ValueTask Publish(IReadOnlyCollection messages, CancellationToken cancellationToken = default) + where TMessage : IOutboxPayloadMessage; + + /// + /// Publishes a single message. + /// + /// The type of the message to be published, which must implement . + /// The message to be published. + /// A token to monitor for cancellation requests. + /// A representing the asynchronous operation, + /// with the number of successfully published messages as the result. + ValueTask Publish(TMessage messages, CancellationToken cancellationToken = default) + where TMessage : IOutboxPayloadMessage => Publish([messages], cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Outbox/Job/DeliveryJob.cs b/src/Sa.Outbox/Job/DeliveryJob.cs new file mode 100644 index 0000000..505fa6a --- /dev/null +++ b/src/Sa.Outbox/Job/DeliveryJob.cs @@ -0,0 +1,19 @@ +using Sa.Outbox.Delivery; +using Sa.Schedule; + +namespace Sa.Outbox.Job; + + +public interface IDeliveryJob: IJob; + + +internal class DeliveryJob(IDeliveryProcessor processor) : IDeliveryJob +{ + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + OutboxDeliverySettings settings = context.Settings.Properties.Tag as OutboxDeliverySettings + ?? throw new NotImplementedException("tag"); + + await processor.ProcessMessages(settings, cancellationToken); + } +} diff --git a/src/Sa.Outbox/Job/IOutboxJobInterceptor.cs b/src/Sa.Outbox/Job/IOutboxJobInterceptor.cs new file mode 100644 index 0000000..b073968 --- /dev/null +++ b/src/Sa.Outbox/Job/IOutboxJobInterceptor.cs @@ -0,0 +1,7 @@ +using Sa.Schedule; + +namespace Sa.Outbox.Job; + +public interface IOutboxJobInterceptor : IJobInterceptor +{ +} \ No newline at end of file diff --git a/src/Sa.Outbox/Job/OutboxJobInterceptor.cs b/src/Sa.Outbox/Job/OutboxJobInterceptor.cs new file mode 100644 index 0000000..1c12f46 --- /dev/null +++ b/src/Sa.Outbox/Job/OutboxJobInterceptor.cs @@ -0,0 +1,21 @@ +using Sa.Schedule; + +namespace Sa.Outbox.Job; + +internal class OutboxJobInterceptor(IEnumerable interceptors) : IJobInterceptor +{ + public async Task OnHandle(IJobContext context, Func next, object? key, CancellationToken cancellationToken) + { + bool hasInterceptors = false; + foreach (IOutboxJobInterceptor item in interceptors) + { + hasInterceptors = true; + await item.OnHandle(context, next, key, cancellationToken); + } + + if (!hasInterceptors) + { + await next(); + } + } +} diff --git a/src/Sa.Outbox/Job/Setup.cs b/src/Sa.Outbox/Job/Setup.cs new file mode 100644 index 0000000..59f9e44 --- /dev/null +++ b/src/Sa.Outbox/Job/Setup.cs @@ -0,0 +1,56 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Schedule; + +namespace Sa.Outbox.Job; + +internal static class Setup +{ + public static IServiceCollection AddDeliveryJob(this IServiceCollection services, Action? сonfigure, int intstanceCount) + where TConsumer : class, IConsumer + { + services.TryAddScoped, TConsumer>(); + + if (intstanceCount > 0) + { + AddSchedule(services, сonfigure, intstanceCount); + } + + return services; + } + + private static void AddSchedule(IServiceCollection services, Action? сonfigure, int intstanceCount) + where TConsumer : class, IConsumer + { + services.AddSchedule(builder => + { + builder.UseHostedService(); + + for (int i = 0; i < intstanceCount; i++) + { + Guid jobId = Guid.NewGuid(); + + builder.AddJob>((sp, jobBuilder) => + { + var settings = new OutboxDeliverySettings(jobId, i); + сonfigure?.Invoke(sp, settings); + + ScheduleSettings scheduleSettings = settings.ScheduleSettings; + + jobBuilder + .EveryTime(scheduleSettings.ExecutionInterval) + .WithInitialDelay(scheduleSettings.InitialDelay) + .WithTag(settings) + .WithName(scheduleSettings.Name ?? typeof(TConsumer).Name) + .ConfigureErrorHandling(c => c + .IfErrorRetry(scheduleSettings.RetryCountOnError) + .ThenCloseApplication()) + ; + + }, jobId); + } + + builder.AddInterceptor(); + }); + } +} diff --git a/src/Sa.Outbox/Partitional/IOutboxPartitionalSupport.cs b/src/Sa.Outbox/Partitional/IOutboxPartitionalSupport.cs new file mode 100644 index 0000000..ca97d4c --- /dev/null +++ b/src/Sa.Outbox/Partitional/IOutboxPartitionalSupport.cs @@ -0,0 +1,25 @@ + +namespace Sa.Outbox.Partitional; + +/// +/// Represents a pair of tenant identifier and part information in the Outbox system. +/// This record is used to associate a tenant with a specific part of the Outbox message. +/// +/// The unique identifier for the tenant. +/// The part identifier associated with the tenant. +public record struct OutboxTenantPartPair(int TenantId, string Part); + +/// +/// Represents an interface for supporting partitioning in the Outbox processing system. +/// This interface defines a method for retrieving tenant-part pairs. +/// +public interface IOutboxPartitionalSupport +{ + /// + /// Asynchronously retrieves a collection of tenant-part pairs. + /// This method can be used to get the current mapping of tenants to their respective parts. + /// + /// A cancellation token to signal the operation's cancellation. + /// A task representing the asynchronous operation, containing a read-only collection of . + Task> GetPartValues(CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Partitional/IPartitionalSupportCache.cs b/src/Sa.Outbox/Partitional/IPartitionalSupportCache.cs new file mode 100644 index 0000000..0567f38 --- /dev/null +++ b/src/Sa.Outbox/Partitional/IPartitionalSupportCache.cs @@ -0,0 +1,15 @@ + +namespace Sa.Outbox.Partitional; + +/// +/// Represents a cache that provides partitional support. +/// +public interface IPartitionalSupportCache +{ + /// + /// Retrieves an array of tenant IDs from the cache. + /// + /// A token to cancel the operation. + /// A task that represents the asynchronous operation, containing an array of tenant IDs. + ValueTask GetTenantIds(CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Partitional/OutboxPartitionalSupport.cs b/src/Sa.Outbox/Partitional/OutboxPartitionalSupport.cs new file mode 100644 index 0000000..f44b405 --- /dev/null +++ b/src/Sa.Outbox/Partitional/OutboxPartitionalSupport.cs @@ -0,0 +1,64 @@ +using Sa.Outbox.Job; +using Sa.Outbox.Publication; +using Sa.Schedule; + +namespace Sa.Outbox.Partitional; + +internal class OutboxPartitionalSupport(IScheduleSettings scheduleSettings, PartitionalSettings partSettings) : IOutboxPartitionalSupport +{ + private readonly Lazy s_lazyParts = new(() => + { + Type baseType = typeof(DeliveryJob<>); + + IEnumerable jobSettings = scheduleSettings.GetJobSettings(); + + string[] parts = jobSettings + .Select(c => GetMessageTypeIfInheritsFromDeliveryJob(c.JobType, baseType)) + .Where(mt => mt != null) + .Cast() + .Select(mt => OutboxMessageTypeHelper.GetOutboxMessageTypeInfo(mt).PartName) + .Distinct() + .ToArray(); + + return parts; + }); + + public async Task> GetPartValues(CancellationToken cancellationToken) + { + string[] parts = s_lazyParts.Value; + + if (parts.Length == 0) return []; + + if (partSettings?.GetTenantIds == null) return []; + + + int[] tenantIds = await partSettings.GetTenantIds(cancellationToken); + if (tenantIds.Length == 0) return []; + + List result = []; + + foreach (int tenantId in tenantIds) + { + foreach (string part in parts) + { + result.Add(new OutboxTenantPartPair(tenantId, part)); + } + } + + return result; + } + + + private static Type? GetMessageTypeIfInheritsFromDeliveryJob(Type type, Type baseType) + { + if (!baseType.IsGenericTypeDefinition) return null; + + if (type.IsGenericType && type.GetGenericTypeDefinition() == baseType) + return type.GenericTypeArguments[0]; + + if (type.BaseType != null) + return GetMessageTypeIfInheritsFromDeliveryJob(type.BaseType, baseType); + + return null; + } +} diff --git a/src/Sa.Outbox/Partitional/PartitionalSettings.cs b/src/Sa.Outbox/Partitional/PartitionalSettings.cs new file mode 100644 index 0000000..bcb3b03 --- /dev/null +++ b/src/Sa.Outbox/Partitional/PartitionalSettings.cs @@ -0,0 +1,26 @@ +namespace Sa.Outbox; + +/// +/// Represents the settings for partitioning in the Outbox processing system. +/// This class contains configuration options related to tenant handling and caching. +/// +public class PartitionalSettings +{ + /// + /// Gets or sets a value indicating whether to process messages for each tenant individually. + /// Default is set to true, meaning messages will be processed for each tenant. + /// + public bool ForEachTenant { get; set; } = true; + + /// + /// Gets or sets the duration for which tenant IDs are cached. + /// Default is set to 2 minutes. + /// + public TimeSpan CacheTenantIdsDuration { get; set; } = TimeSpan.FromMinutes(2); + + /// + /// Gets or sets a function that retrieves tenant IDs asynchronously. + /// This function takes a as a parameter and returns an array of tenant IDs. + /// + public Func>? GetTenantIds { get; set; } +} \ No newline at end of file diff --git a/src/Sa.Outbox/Partitional/PartitionalSupportCache.cs b/src/Sa.Outbox/Partitional/PartitionalSupportCache.cs new file mode 100644 index 0000000..09420a6 --- /dev/null +++ b/src/Sa.Outbox/Partitional/PartitionalSupportCache.cs @@ -0,0 +1,34 @@ +using ZiggyCreatures.Caching.Fusion; + +namespace Sa.Outbox.Partitional; + +internal class PartitionalSupportCache(IFusionCacheProvider cacheProvider, PartitionalSettings? settings = null) : IPartitionalSupportCache +{ + internal static class Env + { + public const string CacheName = "sa-outbox"; + public const string KeyGetTenantIds = "sa-tenant-ids"; + } + + private readonly IFusionCache _cache = cacheProvider.GetCache(Env.CacheName); + + + public async ValueTask GetTenantIds(CancellationToken cancellationToken) + { + if (settings == null) return []; + + return await _cache.GetOrSetAsync( + Env.KeyGetTenantIds + , ExtractTenantIds + , options: null + , token: cancellationToken); + } + + private async Task ExtractTenantIds(FusionCacheFactoryExecutionContext context, CancellationToken cancellationToken) + { + if (settings?.GetTenantIds == null) return []; + int[] ids = await settings.GetTenantIds(cancellationToken); + context.Options.Duration = settings.CacheTenantIdsDuration; + return ids; + } +} diff --git a/src/Sa.Outbox/Partitional/Setup.cs b/src/Sa.Outbox/Partitional/Setup.cs new file mode 100644 index 0000000..c0fd787 --- /dev/null +++ b/src/Sa.Outbox/Partitional/Setup.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +using Sa.Data.Cache; + +namespace Sa.Outbox.Partitional; + +internal static class Setup +{ + public static IServiceCollection AddPartitioningSupport(this IServiceCollection services, Action configure) + { + services.TryAddSingleton(); + + services.TryAddSingleton(sp => + { + PartitionalSettings settings = new(); + configure.Invoke(sp, settings); + return settings; + }); + + services.AddFusionCacheEx(PartitionalSupportCache.Env.CacheName); + + services.TryAddSingleton(); + + return services; + } +} diff --git a/src/Sa.Outbox/Publication/OutboxMessagePublisher.cs b/src/Sa.Outbox/Publication/OutboxMessagePublisher.cs new file mode 100644 index 0000000..866b15d --- /dev/null +++ b/src/Sa.Outbox/Publication/OutboxMessagePublisher.cs @@ -0,0 +1,71 @@ +using Sa.Classes; +using Sa.Host.MessageTypeResolver; +using Sa.Outbox.Support; +using Sa.Timing.Providers; + +namespace Sa.Outbox.Publication; + +internal class OutboxMessagePublisher( + ICurrentTimeProvider timeProvider, + IMessageTypeResolver typeResolver, + IArrayPoolFactory poolFactory, + IOutboxRepository outboxRepository, + OutboxPublishSettings publishSettings +) : IOutboxMessagePublisher +{ + public async ValueTask Publish(IReadOnlyCollection messages, CancellationToken cancellationToken = default) + where TMessage : IOutboxPayloadMessage + { + if (messages.Count == 0) return 0; + return await Send(messages, cancellationToken); + } + + private async ValueTask Send(IReadOnlyCollection messages, CancellationToken cancellationToken) + where TMessage : IOutboxPayloadMessage + { + OutboxMessageTypeInfo typeInfo = OutboxMessageTypeHelper.GetOutboxMessageTypeInfo(); + DateTimeOffset now = timeProvider.GetUtcNow(); + string payloadType = typeResolver.ToName(); + int maxBatchSize = publishSettings.MaxBatchSize; + IArrayPooler> pooler = poolFactory.Create>(); + IEnumerator enumerator = messages.GetEnumerator(); + + ulong sent = 0; + int start = 0; + do + { + int len = (start + maxBatchSize < messages.Count) + ? maxBatchSize + : messages.Count - start; + + OutboxMessage[] payloads = pooler.Rent(len); + try + { + int i = 0; + while (i < len && enumerator.MoveNext()) + { + TMessage message = enumerator.Current; + + payloads[i] = new OutboxMessage( + PayloadId: message.PayloadId ?? string.Empty, + Payload: message, + PartInfo: new OutboxPartInfo(TenantId: message.TenantId, typeInfo.PartName, now)); + + i++; + } + + sent += await outboxRepository.Save(payloadType, payloads.AsMemory()[..len], cancellationToken); + } + finally + { + pooler.Return(payloads); + } + + start += len; + } + while (start < messages.Count); + + return sent; + + } +} diff --git a/src/Sa.Outbox/Publication/OutboxMessageTypeHelper.cs b/src/Sa.Outbox/Publication/OutboxMessageTypeHelper.cs new file mode 100644 index 0000000..779dcb7 --- /dev/null +++ b/src/Sa.Outbox/Publication/OutboxMessageTypeHelper.cs @@ -0,0 +1,29 @@ +using Sa.Outbox.Support; +using System.Collections.Concurrent; +using System.Reflection; + +namespace Sa.Outbox.Publication; + +internal record OutboxMessageTypeInfo(string PartName); + +internal static class OutboxMessageTypeHelper +{ + private static readonly ConcurrentDictionary s_cache = new(); + + public static OutboxMessageTypeInfo GetOutboxMessageTypeInfo(Type type) + => s_cache.GetOrAdd(type, GetTypeInfo); + + public static OutboxMessageTypeInfo GetOutboxMessageTypeInfo() + => s_cache.GetOrAdd(typeof(T), GetTypeInfo); + + private static OutboxMessageTypeInfo GetTypeInfo(Type typeToCheck) + { + return new OutboxMessageTypeInfo(PartName: GetPartValue(typeToCheck)); + } + + private static string GetPartValue(Type type) + { + OutboxMessageAttribute? attribute = type.GetCustomAttribute(); + return attribute?.Part ?? OutboxMessageAttribute.Default.Part; + } +} diff --git a/src/Sa.Outbox/Publication/Setup.cs b/src/Sa.Outbox/Publication/Setup.cs new file mode 100644 index 0000000..df1ea50 --- /dev/null +++ b/src/Sa.Outbox/Publication/Setup.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Outbox.Publication; + +internal static class Setup +{ + public static IServiceCollection AddMessagePublisher(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Outbox/Readme.md b/src/Sa.Outbox/Readme.md new file mode 100644 index 0000000..d952527 --- /dev/null +++ b/src/Sa.Outbox/Readme.md @@ -0,0 +1,255 @@ +# Outbox + +Базовая локика + абстракции предназначеные для реализации паттерна Outbox, с поддержкой партиционирования. + +## Базовый интерфейс для определения Outbox сообщения + +```csharp +/// +/// Represents a message payload in the Outbox system. +/// +public interface IOutboxPayloadMessage +{ + /// + /// Gets the unique identifier for the payload. + /// + string PayloadId { get; } + + /// + /// Gets the identifier for the tenant associated with the payload. + /// + public int TenantId { get; } +} + + +// example message + +[OutboxMessage(part:"some_part")] // задаем партицию +public record SomeMessage(long Payload) : IOutboxPayloadMessage +{ + public string PayloadId => String.Empty; + public int TenantId => 0; +} +``` + + + +## Основные интерфейсы по работе с сообщениями + +### Публикация сообщения + +```csharp +/// +/// Defines a contract for publishing outbox messages. +/// +public interface IOutboxMessagePublisher +{ + /// + /// Publishes a collection of messages. + /// + ValueTask Publish(IReadOnlyCollection messages, CancellationToken cancellationToken = default) + where TMessage : IOutboxPayloadMessage; + + /// + /// Publishes a single message. + /// + ValueTask Publish(TMessage messages, CancellationToken cancellationToken = default) + where TMessage : IOutboxPayloadMessage => Publish(new[] { messages }, cancellationToken); +} +``` + +### Сохранение в хранилище + +```csharp +public interface IOutboxRepository +{ + ValueTask Save(string payloadType, ReadOnlyMemory> messages, CancellationToken cancellationToken = default); +} +``` + + +### Доставка до потребителя + +```csharp +public interface IDeliveryRepository +{ + /// + /// Exclusively take for processing for the client + /// + Task StartDelivery(Memory> writeBuffer, int batchSize, TimeSpan lockDuration, OutboxMessageFilter filter, CancellationToken cancellationToken); + + /// + /// Complete the delivery + /// + Task FinishDelivery(IOutboxContext[] outboxMessages, OutboxMessageFilter filter, CancellationToken cancellationToken); + + /// + /// Extend the delivery (retain the lock for the client) + /// + Task ExtendDelivery(TimeSpan lockExpiration, OutboxMessageFilter filter, CancellationToken cancellationToken); +} +``` + + +### Поддержка партиций +```csharp +/// +/// Represents a pair of tenant identifier and part information in the Outbox system. +/// This record is used to associate a tenant with a specific part of the Outbox message. +/// +/// The unique identifier for the tenant. +/// The part identifier associated with the tenant. +public record struct OutboxTenantPartPair(int TenantId, string Part); + +/// +/// Represents an interface for supporting partitioning in the Outbox processing system. +/// This interface defines a method for retrieving tenant-part pairs. +/// +public interface IOutboxPartitionalSupport +{ + /// + /// Asynchronously retrieves a collection of tenant-part pairs. + /// This method can be used to get the current mapping of tenants to their respective parts. + /// + Task> GetPartValues(CancellationToken cancellationToken); +} +``` + +### Потребитель сообщений +```csharp +/// +/// Represents a consumer interface for processing Outbox messages of a specific type. +/// +public interface IConsumer : IConsumer +{ + /// + /// Consumes a collection of Outbox messages. + /// + ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken); +} + +/// +/// Represents a base consumer interface for processing Outbox messages. +/// This interface can be extended by specific consumer implementations. +/// +public interface IConsumer +{ +} +``` + + + +## Примеры Outbox с использованием PostgreSQL + +### Пример конфигурирования + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox; +using Sa.Outbox.PostgreSql; + +public class Startup +{ + public void ConfigureServices(IServiceCollection services) + { + // Конфигурация Outbox + services.AddOutbox(builder => + { + // Настройка доставки + builder.WithDeliveries(deliveryBuilder => + { + // Добавить доставку (подкл. потребителя сообщений с типом - MyMessage) + deliveryBuilder.AddDelivery(); + }); + + // Настройка поддержки для работы с партициями + builder.WithPartitioningSupport((serviceProvider, partSettings) => + { + // Пример настройки для обработки сообщений для каждого арендатора + partSettings.ForEachTenant = true; + + // Возвращаем список тенантов для app + partSettings.GetTenantIds = async cancellationToken => + { + // Логика получения идентификаторов арендаторов + return await Task.FromResult(new int[] { 1, 2 }); + }; + }); + }); + + // Подключение Outbox с использованием PostgreSQL + services.AddOutboxUsingPostgreSql(cfg => + { + // коннекшен к БД + cfg.AddDataSource(c => c.WithConnectionString("Host=my_host;Database=my_db;Username=my_user;Password=my_password")); + + // настройки для работы Pg + cfg.WithPgOutboxSettings((_, settings) => + { + // Установка схемы базы данных + settings.TableSettings.DatabaseSchemaName = "public"; + + // Настройка очистки + settings.CleanupSettings.DropPartsAfterRetention = TimeSpan.FromDays(30); + }); + }); + } +} +``` + +### Пример отправки сообщения + +```csharp + +public class MessageSender(IOutboxMessagePublisher publisher) +{ + public async Task SendMessagesAsync(CancellationToken cancellationToken) + { + // Создание списка сообщений для отправки + var messages = new List + { + new MyMessage { PayloadId = Guid.NewGuid().ToString(), Content = "Hello, World!", TenantId = 1 }, + new MyMessage { PayloadId = Guid.NewGuid().ToString(), Content = "Another message", TenantId = 2 } + }; + + // Отправка сообщений через Outbox + ulong result = await publisher.Publish(messages, cancellationToken); + + Console.WriteLine($"Sent {result} messages."); + } +} +``` + + +### Пример потребления сообщений + +```csharp +using Sa.Outbox; + +namespace MyNamespace +{ + // Пример сообщения, которое будет отправляться через Outbox + [OutboxMessage] + public record MyMessage(string PayloadId, string Content) : IOutboxPayloadMessage + { + public int TenantId { get; init; } // Идентификатор арендатора + } + + // Пример потребителя, который будет обрабатывать сообщения MyMessage + public class MyMessageConsumer : IConsumer + { + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + foreach (var messageContext in outboxMessages) + { + // Логика обработки сообщения + Console.WriteLine($"Processing message with ID: {messageContext.Payload.PayloadId} and Content: {messageContext.Payload.Content}"); + + // Успешная обработка сообщения + messageContext.Ok("Message processed successfully."); + } + } + } +} +``` + diff --git a/src/Sa.Outbox/Repositories/IDeliveryRepository.cs b/src/Sa.Outbox/Repositories/IDeliveryRepository.cs new file mode 100644 index 0000000..da83125 --- /dev/null +++ b/src/Sa.Outbox/Repositories/IDeliveryRepository.cs @@ -0,0 +1,22 @@ +namespace Sa.Outbox; + + +/// +/// needed External implementation +/// +public interface IDeliveryRepository +{ + /// + /// Exclusively take for processing for the client + /// + Task StartDelivery(Memory> writeBuffer, int batchSize, TimeSpan lockDuration, OutboxMessageFilter filter, CancellationToken cancellationToken); + /// + /// Complete the delivery + /// + Task FinishDelivery(IOutboxContext[] outboxMessages, OutboxMessageFilter filter, CancellationToken cancellationToken); + + /// + /// Extend the delivery (retain the lock for the client) + /// + Task ExtendDelivery(TimeSpan lockExpiration, OutboxMessageFilter filter, CancellationToken cancellationToken); +} diff --git a/src/Sa.Outbox/Repositories/IOutboxContext.cs b/src/Sa.Outbox/Repositories/IOutboxContext.cs new file mode 100644 index 0000000..9568d74 --- /dev/null +++ b/src/Sa.Outbox/Repositories/IOutboxContext.cs @@ -0,0 +1,93 @@ +namespace Sa.Outbox; + + +/// +/// Represents the context for an Outbox message processing operation. +/// This interface provides information about the message, its delivery status, and methods to update the status. +/// +public interface IOutboxContext +{ + /// + /// Gets the unique identifier for the Outbox message. + /// + string OutboxId { get; } + + /// + /// Gets information about the part of the Outbox message being processed. + /// + OutboxPartInfo PartInfo { get; } + + /// + /// Gets information about the delivery of the Outbox message. + /// + OutboxDeliveryInfo DeliveryInfo { get; } + + /// + /// Gets the result of the delivery attempt. + /// + DeliveryStatus DeliveryResult { get; } + + /// + /// Gets any exception that occurred during the processing of the message. + /// + Exception? Exception { get; } + + /// + /// Gets the duration for which the message processing is postponed. + /// + TimeSpan PostponeAt { get; } + + /// + /// Marks the message processing as successful. + /// + /// An optional message providing additional context. + /// The current Outbox context. + IOutboxContext Ok(string? message = null); + + /// + /// Marks the message processing as aborted. + /// + /// An optional message providing additional context. + /// The current Outbox context. + IOutboxContext Aborted(string? message = null); + + /// + /// Marks the message processing as an error. + /// + /// The exception that occurred during processing. + /// An optional message providing additional context. + /// The status code associated with the error. + /// An optional duration to postpone processing. + /// The current Outbox context. + IOutboxContext Error(Exception exception, string? message = null, int statusCode = DeliveryStatusCode.Error, TimeSpan? postpone = null); + + /// + /// Marks the message processing as a permanent error. + /// + /// The exception that occurred during processing. + /// An optional message providing additional context. + /// The status code associated with the permanent error. + /// The current Outbox context. + IOutboxContext PermanentError(Exception exception, string? message = null, int statusCode = DeliveryStatusCode.PermanentError); + + /// + /// Marks the message processing as postponed. + /// + /// The duration to postpone processing. + /// An optional message providing additional context. + /// The current Outbox context. + IOutboxContext Postpone(TimeSpan postpone, string? message = null); +} + +/// +/// Represents the context for an Outbox message processing operation with a specific message type. +/// This interface extends the to include the message payload. +/// +/// The type of the message being processed. +public interface IOutboxContext : IOutboxContext +{ + /// + /// Gets the payload of the Outbox message being processed. + /// + TMessage Payload { get; } +} \ No newline at end of file diff --git a/src/Sa.Outbox/Repositories/IOutboxRepository.cs b/src/Sa.Outbox/Repositories/IOutboxRepository.cs new file mode 100644 index 0000000..d4d6617 --- /dev/null +++ b/src/Sa.Outbox/Repositories/IOutboxRepository.cs @@ -0,0 +1,17 @@ +namespace Sa.Outbox; + +/// +/// Represents a repository for storing outbox messages. +/// +public interface IOutboxRepository +{ + /// + /// Saves a collection of outbox messages to the repository. + /// + /// The type of message being saved. + /// The type of payload being saved. + /// The collection of outbox messages to save. + /// A token to cancel the operation. + /// A task representing the asynchronous operation, containing the number of messages saved. + ValueTask Save(string payloadType, ReadOnlyMemory> messages, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/Sa.Outbox/Repositories/OutboxContext.cs b/src/Sa.Outbox/Repositories/OutboxContext.cs new file mode 100644 index 0000000..c8ea2c7 --- /dev/null +++ b/src/Sa.Outbox/Repositories/OutboxContext.cs @@ -0,0 +1,65 @@ +using Sa.Outbox.Exceptions; +using Sa.Timing.Providers; + + +namespace Sa.Outbox.Repository; + +/// +/// OutboxMessage +/// +internal class OutboxContext(OutboxDeliveryMessage delivery, ICurrentTimeProvider timeProvider) : IOutboxContext +{ + public string OutboxId { get; } = delivery.OutboxId; + public OutboxPartInfo PartInfo { get; } = delivery.PartInfo; + + + public string PayloadId { get; } = delivery.PayloadId; + public TMessage Payload { get; } = delivery.Payload; + + + public OutboxDeliveryInfo DeliveryInfo { get; } = delivery.DeliveryInfo; + + + public DeliveryStatus DeliveryResult { get; private set; } + public TimeSpan PostponeAt { get; private set; } + public Exception? Exception { get; private set; } + + public IOutboxContext PermanentError(Exception exception, string? message = null, int statusCode = DeliveryStatusCode.PermanentError) + { + return Error(exception, message, statusCode); + } + + public IOutboxContext Error(Exception exception, string? message = null, int statusCode = DeliveryStatusCode.Error, TimeSpan? postpone = null) + { + DeliveryException? deliveryException = exception as DeliveryException; + + DeliveryResult = new DeliveryStatus(deliveryException?.StatusCode ?? statusCode, message ?? exception.Message, timeProvider.GetUtcNow()); + Exception = exception; + PostponeAt = postpone ?? deliveryException?.PostponeAt ?? TimeSpan.Zero; + return this; + } + + public IOutboxContext Ok(string? message = null) + { + DeliveryResult = new DeliveryStatus(DeliveryStatusCode.Ok, message ?? string.Empty, timeProvider.GetUtcNow()); + Exception = null; + PostponeAt = TimeSpan.Zero; + return this; + } + + public IOutboxContext Postpone(TimeSpan postpone, string? message = null) + { + DeliveryResult = new DeliveryStatus(DeliveryStatusCode.Postpone, message ?? string.Empty, timeProvider.GetUtcNow()); + Exception = null; + PostponeAt = postpone; + return this; + } + + public IOutboxContext Aborted(string? message = null) + { + DeliveryResult = new DeliveryStatus(DeliveryStatusCode.Aborted, message ?? string.Empty, timeProvider.GetUtcNow()); + Exception = null; + PostponeAt = TimeSpan.Zero; + return this; + } +} diff --git a/src/Sa.Outbox/Repositories/OutboxMessage.cs b/src/Sa.Outbox/Repositories/OutboxMessage.cs new file mode 100644 index 0000000..cd42ef1 --- /dev/null +++ b/src/Sa.Outbox/Repositories/OutboxMessage.cs @@ -0,0 +1,102 @@ +namespace Sa.Outbox; + + +/// +/// Represents a message in the Outbox with its associated payload and part information. +/// +/// The type of the message payload. +public record struct OutboxMessage( + /// + /// Gets the unique identifier for the payload. + /// + string PayloadId, + + /// + /// Gets the actual message payload. + /// + TMessage Payload, + + /// + /// Gets information about the part of the Outbox message. + /// + OutboxPartInfo PartInfo +); + +/// +/// Represents a delivery message in the Outbox with its associated payload, part information, and delivery details. +/// +/// The type of the message payload. +public record struct OutboxDeliveryMessage( + /// + /// Gets the unique identifier for the Outbox delivery. + /// + string OutboxId, + + /// + /// Gets the unique identifier for the payload. + /// + string PayloadId, + + /// + /// Gets the actual message payload. + /// + TMessage Payload, + + /// + /// Gets information about the part of the Outbox message. + /// + OutboxPartInfo PartInfo, + + /// + /// Gets information about the delivery of the Outbox message. + /// + OutboxDeliveryInfo DeliveryInfo +); + +/// +/// Represents information about a part of the Outbox message. +/// +public record struct OutboxPartInfo( + /// + /// Gets the identifier for the tenant associated with the message. + /// + int TenantId, + + /// + /// Gets the part identifier for the Outbox message. + /// + string Part, + + /// + /// Gets the date and time when the part was created. + /// + DateTimeOffset CreatedAt +); + +/// +/// Represents information about the delivery of an Outbox message. +/// +/// The unique identifier for the delivery. +/// The number of delivery attempts made. +/// The identifier of the last error encountered during delivery. +/// The current status of the delivery. +/// The date and time when the delivery was created. +public record struct OutboxDeliveryInfo( + string? DeliveryId, + int Attempt, + string LastErrorId, + DeliveryStatus Status, + DateTimeOffset CreatedAt +); + +/// +/// Represents the status of a delivery attempt. +/// +/// The status code representing the result of the delivery. +/// A message providing additional context about the delivery status. +/// The date and time when the status was created. +public record struct DeliveryStatus( + int Code, + string Message, + DateTimeOffset CreatedAt +); \ No newline at end of file diff --git a/src/Sa.Outbox/Repositories/OutboxMessageFilter.cs b/src/Sa.Outbox/Repositories/OutboxMessageFilter.cs new file mode 100644 index 0000000..b54e69e --- /dev/null +++ b/src/Sa.Outbox/Repositories/OutboxMessageFilter.cs @@ -0,0 +1,39 @@ +namespace Sa.Outbox; + +/// +/// Represents a filter for querying Outbox messages based on specific criteria. +/// This record is used to define the parameters for filtering messages in the Outbox. +/// +public record OutboxMessageFilter( + /// + /// Gets the transaction identifier associated with the Outbox message. + /// + string TransactId, + + /// + /// Gets the type of the payload contained in the Outbox message. + /// + string PayloadType, + + /// + /// Gets the identifier for the tenant associated with the Outbox message. + /// + int TenantId, + + /// + /// Gets the part identifier for the Outbox message. + /// + string Part, + + /// + /// Gets the starting date and time for filtering messages. + /// Only messages created on or after this date will be included. + /// + DateTimeOffset FromDate, + + /// + /// Gets the current date and time for filtering messages. + /// Only messages created on or before this date will be included. + /// + DateTimeOffset NowDate +); \ No newline at end of file diff --git a/src/Sa.Outbox/Sa.Outbox.csproj b/src/Sa.Outbox/Sa.Outbox.csproj new file mode 100644 index 0000000..f0df714 --- /dev/null +++ b/src/Sa.Outbox/Sa.Outbox.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/src/Sa.Outbox/Setup.cs b/src/Sa.Outbox/Setup.cs new file mode 100644 index 0000000..6dbc7ff --- /dev/null +++ b/src/Sa.Outbox/Setup.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Configuration; + +namespace Sa.Outbox; + +public static class Setup +{ + public static IServiceCollection AddOutbox(this IServiceCollection services, Action? build = null) + { + OutboxBuilder builder = new(services); + build?.Invoke(builder); + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Cache/IPartCache.cs b/src/Sa.Partitional.PostgreSql/Cache/IPartCache.cs new file mode 100644 index 0000000..f40aa75 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cache/IPartCache.cs @@ -0,0 +1,10 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql.Cache; + +public interface IPartCache +{ + ValueTask InCache(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default); + ValueTask EnsureCache(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default); + ValueTask RemoveCache(string tableName, CancellationToken cancellationToken = default); +} diff --git a/src/Sa.Partitional.PostgreSql/Cache/PartCache.cs b/src/Sa.Partitional.PostgreSql/Cache/PartCache.cs new file mode 100644 index 0000000..d250421 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cache/PartCache.cs @@ -0,0 +1,78 @@ +using Sa.Classes; +using Sa.Extensions; +using Sa.Timing.Providers; +using ZiggyCreatures.Caching.Fusion; + +namespace Sa.Partitional.PostgreSql.Cache; + +internal class PartCache( + IFusionCacheProvider cacheProvider + , IPartRepository repository + , ISqlBuilder sqlBuilder + , ICurrentTimeProvider timeProvider + , PartCacheSettings settings +) : IPartCache +{ + internal static class Env + { + public const string CacheName = "sa-partitional"; + } + + private readonly IFusionCache _cache = cacheProvider.GetCache(Env.CacheName); + + + public async ValueTask InCache(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default) + { + if (sqlBuilder[tableName] == null) return false; + + List list = await GetPartsInCache(tableName, cancellationToken); + + if (list.Count == 0) return false; + + return list.Exists(c => partValues.SequenceEqual(c.PartValues) && c.PartBy.GetRange(c.FromDate).InRange(date)); + } + + private ValueTask> GetPartsInCache(string tableName, CancellationToken cancellationToken) + { + return _cache.GetOrSetAsync>( + tableName + , async (ctx, t) => await SelectPartsInDb(ctx, tableName, t) + , options: null + , token: cancellationToken); + } + + // search and set the cache duration based result set + private async Task> SelectPartsInDb(FusionCacheFactoryExecutionContext> context, string tableName, CancellationToken cancellationToken) + { + try + { + DateTimeOffset from = (timeProvider.GetUtcNow() - settings.CachedFromDate).StartOfDay(); + List list = await repository.GetPartsFromDate(tableName, from, cancellationToken); + context.Options.Duration = settings.CacheDuration; + return list; + } + catch (Npgsql.PostgresException ex) when (ex.SqlState == Npgsql.PostgresErrorCodes.UndefinedTable) + { + context.Options.Duration = TimeSpan.Zero; + + return []; + } + } + + public async ValueTask EnsureCache(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default) + { + bool result = await InCache(tableName, date, partValues, cancellationToken); + if (result) return true; + + await repository.CreatePart(tableName, date, partValues, cancellationToken); + + await RemoveCache(tableName, cancellationToken); + + result = await InCache(tableName, date, partValues, cancellationToken); + + return result; + } + + public ValueTask RemoveCache(string tableName, CancellationToken cancellationToken = default) + => _cache.RemoveAsync(tableName, null, cancellationToken); +} diff --git a/src/Sa.Partitional.PostgreSql/Cache/PartCacheSettings.cs b/src/Sa.Partitional.PostgreSql/Cache/PartCacheSettings.cs new file mode 100644 index 0000000..3df12b9 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cache/PartCacheSettings.cs @@ -0,0 +1,8 @@ +namespace Sa.Partitional.PostgreSql; + +public class PartCacheSettings +{ + public TimeSpan CacheDuration { get; set; } = TimeSpan.FromMinutes(2); + + public TimeSpan CachedFromDate { get; set; } = TimeSpan.FromDays(1); +} diff --git a/src/Sa.Partitional.PostgreSql/Cache/Setup.cs b/src/Sa.Partitional.PostgreSql/Cache/Setup.cs new file mode 100644 index 0000000..399c67b --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cache/Setup.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +using Sa.Data.Cache; + +namespace Sa.Partitional.PostgreSql.Cache; + + +internal static class Setup +{ + public static IServiceCollection AddPartCache(this IServiceCollection services, Action? configure = null) + { + + services.AddTransient(); + + services.AddFusionCacheEx(PartCache.Env.CacheName, (sp, opts) => + { + PartCacheSettings cacheSettings = sp.GetRequiredService(); + configure?.Invoke(sp, cacheSettings); + opts.Duration = cacheSettings.CacheDuration; + }); + + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Cleaning/IPartCleanupService.cs b/src/Sa.Partitional.PostgreSql/Cleaning/IPartCleanupService.cs new file mode 100644 index 0000000..8073b8c --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cleaning/IPartCleanupService.cs @@ -0,0 +1,26 @@ + +namespace Sa.Partitional.PostgreSql; + +/// +/// Represents a service interface for cleaning up Outbox message parts. +/// This interface defines methods for performing cleanup operations on message parts. +/// +public interface IPartCleanupService +{ + /// + /// Asynchronously cleans up Outbox message parts. + /// This method removes parts that are no longer needed based on the retention policy. + /// + /// A cancellation token to signal the operation's cancellation. + /// A task representing the asynchronous operation, containing the number of parts cleaned up. + Task Clean(CancellationToken cancellationToken); + + /// + /// Asynchronously cleans up Outbox message parts up to a specified date. + /// This method removes parts that are older than the provided date. + /// + /// The date up to which parts should be cleaned up. + /// A cancellation token to signal the operation's cancellation. + /// A task representing the asynchronous operation, containing the number of parts cleaned up. + Task Clean(DateTimeOffset toDate, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupJob.cs b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupJob.cs new file mode 100644 index 0000000..d3a9059 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupJob.cs @@ -0,0 +1,11 @@ +using Sa.Schedule; + +namespace Sa.Partitional.PostgreSql.Cleaning; + +internal class PartCleanupJob(IPartCleanupService cleaningService) : IJob +{ + public Task Execute(IJobContext context, CancellationToken cancellationToken) + { + return cleaningService.Clean(cancellationToken); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupScheduleSettings.cs b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupScheduleSettings.cs new file mode 100644 index 0000000..0f39b54 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupScheduleSettings.cs @@ -0,0 +1,34 @@ +namespace Sa.Partitional.PostgreSql; + +/// +/// Represents the settings for scheduling the cleanup of Outbox message parts. +/// This class contains configuration options related to how and when parts should be cleaned up. +/// +public class PartCleanupScheduleSettings +{ + /// + /// Gets or sets a value indicating whether the cleanup should be executed as a background job. + /// Default is set to false, meaning the cleanup will not run as a job. + /// + public bool AsJob { get; set; } = false; + + /// + /// Gets or sets the duration after which old parts will be dropped. + /// Default is set to 30 days. + /// + public TimeSpan DropPartsAfterRetention { get; set; } = TimeSpan.FromDays(30); + + /// + /// Gets or sets the interval at which the cleanup job will be executed. + /// Default is set to every 4 hours, with a random additional delay of up to 59 minutes. + /// + public TimeSpan ExecutionInterval { get; set; } = TimeSpan + .FromHours(4) + .Add(TimeSpan.FromMinutes(Random.Shared.Next(1, 59))); + + /// + /// Gets or sets the initial delay before the cleanup job starts executing. + /// Default is set to 1 minute. + /// + public TimeSpan InitialDelay { get; set; } = TimeSpan.FromMinutes(1); +} diff --git a/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupService.cs b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupService.cs new file mode 100644 index 0000000..65310b0 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cleaning/PartCleanupService.cs @@ -0,0 +1,27 @@ +using Sa.Timing.Providers; + +namespace Sa.Partitional.PostgreSql.Cleaning; + +internal class PartCleanupService( + IPartRepository repository + , PartCleanupScheduleSettings settings + , ICurrentTimeProvider timeProvider + , ISqlBuilder sqlBuilder +) : IPartCleanupService +{ + public async Task Clean(DateTimeOffset toDate, CancellationToken cancellationToken) + { + int cnt = 0; + foreach (string tableName in sqlBuilder.Tables.Select(c => c.FullName)) + { + cnt += await repository.DropPartsToDate(tableName, toDate, cancellationToken); + } + return cnt; + } + + public Task Clean(CancellationToken cancellationToken) + { + DateTimeOffset toDate = timeProvider.GetUtcNow().Add(-settings.DropPartsAfterRetention); + return Clean(toDate, cancellationToken); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Cleaning/Setup.cs b/src/Sa.Partitional.PostgreSql/Cleaning/Setup.cs new file mode 100644 index 0000000..ecf6710 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Cleaning/Setup.cs @@ -0,0 +1,69 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Schedule; +using System.Collections.Concurrent; + +namespace Sa.Partitional.PostgreSql.Cleaning; + +internal static class Setup +{ + readonly static Guid JobId = Guid.Parse("7da81411-9db7-4553-8e93-bd1f12d02b38"); + + private static readonly ConcurrentDictionary>> s_invokers = []; + + public static IServiceCollection AddPartCleaning(this IServiceCollection services, Action? configure = null) + { + + if (configure != null) + { + if (s_invokers.TryGetValue(services, out var builder)) + { + builder.Add(configure); + } + else + { + s_invokers[services] = [configure]; + } + } + + services.TryAddSingleton(sp => + { + var item = new PartCleanupScheduleSettings(); + if (s_invokers.TryGetValue(services, out var invokers)) + { + foreach (Action invoker in invokers) + { + invoker.Invoke(sp, item); + } + s_invokers.Remove(services, out _); + } + return item; + }); + + services.TryAddSingleton(); + + services.AddSchedule(b => b + .UseHostedService() + .AddJob((sp, builder) => + { + builder.WithName("Cleanup job"); + + PartCleanupScheduleSettings settings = sp.GetRequiredService(); + + builder + .WithInitialDelay(settings.InitialDelay) + .EveryTime(settings.ExecutionInterval) + .ConfigureErrorHandling(berr => berr.DoSuppressError(err => true)) + ; + + if (!settings.AsJob) + { + builder.Disabled(); + } + + }, JobId) + ); + + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISchemaBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISchemaBuilder.cs new file mode 100644 index 0000000..d6fab81 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISchemaBuilder.cs @@ -0,0 +1,8 @@ +namespace Sa.Partitional.PostgreSql; + +public interface ISchemaBuilder +{ + ITableBuilder CreateTable(string tableName); + ITableBuilder AddTable(string tableName, params string[] sqlFields); + ITableSettings[] Build(); +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISettingsBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISettingsBuilder.cs new file mode 100644 index 0000000..50c91c1 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ISettingsBuilder.cs @@ -0,0 +1,9 @@ +namespace Sa.Partitional.PostgreSql; + + +public interface ISettingsBuilder +{ + ISettingsBuilder AddSchema(Action schemaBuilder); + ISettingsBuilder AddSchema(string schemaName, Action schemaBuilder); + ITableSettingsStorage Build(); +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/ITableBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ITableBuilder.cs new file mode 100644 index 0000000..3b2f804 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/ITableBuilder.cs @@ -0,0 +1,31 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +public interface ITableBuilder +{ + ITableBuilder AddFields(params string[] sqlFields); + ITableBuilder PartByList(params string[] fieldNames); + ITableBuilder PartByRange(PgPartBy partBy, string? timestampFieldName = null); + + ITableBuilder TimestampAs(string timestampFieldName); + ITableBuilder WithPartSeparator(string partSeparator); + + ITableBuilder AddPostSql(Func postSql); + ITableBuilder AddConstraintPkSql(Func pkSql); + + + ITableSettings Build(); + + ITableBuilder AddMigration(IPartTableMigrationSupport migrationSupport); + + ITableBuilder AddMigration(Func> getPartValues); + + ITableBuilder AddMigration(params StrOrNum[] partValues); + + ITableBuilder AddMigration(StrOrNum parent, StrOrNum[] childs) + { + foreach (StrOrNum child in childs) AddMigration(parent, child); + return this; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/SchemaBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/SchemaBuilder.cs new file mode 100644 index 0000000..9c30244 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/SchemaBuilder.cs @@ -0,0 +1,19 @@ +namespace Sa.Partitional.PostgreSql.Configuration.Builder; + +internal class SchemaBuilder(string schemaName) : ISchemaBuilder +{ + public readonly Dictionary _tables = []; + + public ITableBuilder CreateTable(string tableName) + { + if (_tables.TryGetValue(tableName, out TableBuilder? table)) return table; + TableBuilder builder = new(schemaName, tableName); + _tables[tableName] = builder; + return builder; + } + + public ITableBuilder AddTable(string tableName, params string[] sqlFields) + => CreateTable(tableName).AddFields(sqlFields); + + public ITableSettings[] Build() => _tables.Values.Select(c => c.Build()).ToArray(); +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/SettingsBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/SettingsBuilder.cs new file mode 100644 index 0000000..6f9439c --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/SettingsBuilder.cs @@ -0,0 +1,32 @@ +using Sa.Partitional.PostgreSql.Settings; + +namespace Sa.Partitional.PostgreSql.Configuration.Builder; + + +internal class SettingsBuilder : ISettingsBuilder +{ + private readonly Dictionary _schemas = []; + + public ISettingsBuilder AddSchema(Action schemaBuilder) + { + return AddSchema("public", schemaBuilder); + } + + public ISettingsBuilder AddSchema(string schemaName, Action schemaBuilder) + { + if (!_schemas.TryGetValue(schemaName, out ISchemaBuilder? builder)) + { + builder = new SchemaBuilder(schemaName); + _schemas[schemaName] = builder; + } + + schemaBuilder.Invoke(builder); + return this; + } + + public ITableSettingsStorage Build() + { + ITableSettings[] tables = _schemas.Values.SelectMany(c => c.Build()).ToArray(); + return new TableSettingsStorage(tables); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/Setup.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/Setup.cs new file mode 100644 index 0000000..3930b1e --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/Setup.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System.Collections.Concurrent; + +namespace Sa.Partitional.PostgreSql.Configuration.Builder; + + +public static class Setup +{ + private static readonly ConcurrentDictionary>> s_invokers = []; + + public static IServiceCollection AddSettigs(this IServiceCollection services, Action build) + { + if (s_invokers.TryGetValue(services, out var invokers)) + { + invokers.Add(build); + } + else + { + s_invokers[services] = [build]; + } + + services.TryAddSingleton(sp => + { + var builder = new SettingsBuilder(); + if (s_invokers.TryGetValue(services, out var invokers)) + { + foreach (Action build in invokers) + { + build.Invoke(sp, builder); + } + + s_invokers.Remove(services, out _); + } + return builder; + }); + + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/Builder/TableBuilder.cs b/src/Sa.Partitional.PostgreSql/Configuration/Builder/TableBuilder.cs new file mode 100644 index 0000000..1cbf523 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/Builder/TableBuilder.cs @@ -0,0 +1,125 @@ +using Sa.Classes; +using Sa.Partitional.PostgreSql.Settings; + +namespace Sa.Partitional.PostgreSql.Configuration.Builder; + +internal class TableBuilder(string schemaName, string tableName) : ITableBuilder +{ + private readonly List _fields = []; + private readonly List _parts = []; + + private readonly List _migrationPartValues = []; + private IPartTableMigrationSupport? _migrationSupport; + private Func>? _getPartValues; + + private string? _timestamp; + private PgPartBy? _partBy; + private string? _separator = null; + + private Func? _postSql = null; + private Func? _pkSql = null; + + public ITableBuilder AddFields(params string[] sqlFields) + { + ArgumentNullException.ThrowIfNull(sqlFields); + + if (sqlFields.Length == 0) throw new ArgumentException("fields is empty", nameof(sqlFields)); + _fields.AddRange(sqlFields); + return this; + } + + public ITableBuilder PartByList(params string[] fieldNames) + { + ArgumentNullException.ThrowIfNull(fieldNames); + + _parts.AddRange(fieldNames); + return this; + } + + public ITableBuilder TimestampAs(string timestampFieldName) + { + _timestamp = timestampFieldName; + return this; + } + + public ITableBuilder PartByRange(PgPartBy partBy, string? timestampFieldName = null) + { + _partBy = partBy; + _timestamp ??= timestampFieldName; + return this; + } + + public ITableBuilder WithPartSeparator(string partSeparator) + { + _separator = partSeparator; + return this; + } + + public ITableBuilder AddPostSql(Func postSql) + { + _postSql = postSql ?? throw new ArgumentNullException(nameof(postSql)); + return this; + } + + public ITableBuilder AddConstraintPkSql(Func pkSql) + { + _pkSql = pkSql ?? throw new ArgumentNullException(nameof(pkSql)); + return this; + } + + public ITableSettings Build() => new TableSettings( + schemaName + , tableName + , [.. _fields] + , [.. _parts] + , new PartTableMigrationSupport(_migrationPartValues, _getPartValues, _migrationSupport) + , _partBy + , _postSql + , _pkSql + , _timestamp + , _separator + ); + + public ITableBuilder AddMigration(params StrOrNum[] partValues) + { + _migrationPartValues.Add(partValues); + return this; + } + + public ITableBuilder AddMigration(Func> getPartValues) + { + _getPartValues = getPartValues; + return this; + } + + public ITableBuilder AddMigration(IPartTableMigrationSupport migrationSupport) + { + _migrationSupport = migrationSupport; + return this; + } + + + + internal class PartTableMigrationSupport(IReadOnlyCollection? partValues, Func>? getPartValues, IPartTableMigrationSupport? original) : IPartTableMigrationSupport + { + public async Task GetPartValues(CancellationToken cancellationToken) + { + List result = partValues != null ? [.. partValues] : []; + + if (getPartValues != null) + { + StrOrNum[][] partItems = await getPartValues(cancellationToken); + result.AddRange(partItems); + } + + if (original != null) + { + StrOrNum[][] partItems = await original.GetPartValues(cancellationToken); + result.AddRange(partItems); + } + + return [.. result]; + } + } + +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/IPartConfiguration.cs b/src/Sa.Partitional.PostgreSql/Configuration/IPartConfiguration.cs new file mode 100644 index 0000000..ea2894f --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/IPartConfiguration.cs @@ -0,0 +1,11 @@ +namespace Sa.Partitional.PostgreSql; + +public interface IPartConfiguration +{ + IPartConfiguration AddPartTables(Action configure); + IPartConfiguration AddPartCache(Action? configure = null); + IPartConfiguration AddPartMigrationSchedule(Action? configure = null); + IPartConfiguration AddPartCleanupSchedule(Action? configure = null); + + IPartConfiguration AddDataSource(Action? configure = null); +} diff --git a/src/Sa.Partitional.PostgreSql/Configuration/PartConfiguration.cs b/src/Sa.Partitional.PostgreSql/Configuration/PartConfiguration.cs new file mode 100644 index 0000000..aa9893b --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Configuration/PartConfiguration.cs @@ -0,0 +1,51 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql; +using Sa.Partitional.PostgreSql.Cache; +using Sa.Partitional.PostgreSql.Cleaning; +using Sa.Partitional.PostgreSql.Configuration.Builder; +using Sa.Partitional.PostgreSql.Migration; +using Sa.Partitional.PostgreSql.Repositories; +using Sa.Partitional.PostgreSql.SqlBuilder; + +namespace Sa.Partitional.PostgreSql.Configuration; + +internal class PartConfiguration(IServiceCollection services) : IPartConfiguration +{ + + public IPartConfiguration AddPartTables(Action configure) + { + services + .AddSettigs(configure) + .AddSqlBuilder() + ; + + return this; + } + + public IPartConfiguration AddDataSource(Action? configure = null) + { + services.AddPgDataSource(configure); + + // inner + services.AddPartRepository(); + return this; + } + + public IPartConfiguration AddPartCache(Action? configure = null) + { + services.AddPartCache(configure); + return this; + } + + public IPartConfiguration AddPartMigrationSchedule(Action? configure = null) + { + services.AddPartMigration(configure); + return this; + } + + public IPartConfiguration AddPartCleanupSchedule(Action? configure = null) + { + services.AddPartCleaning(configure); + return this; + } +} diff --git a/src/Sa.Partitional.PostgreSql/GlobalSuppressions.cs b/src/Sa.Partitional.PostgreSql/GlobalSuppressions.cs new file mode 100644 index 0000000..4ca2bde --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/GlobalSuppressions.cs @@ -0,0 +1,9 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0130:Namespace does not match folder structure")] + diff --git a/src/Sa.Partitional.PostgreSql/IPartitionManager.cs b/src/Sa.Partitional.PostgreSql/IPartitionManager.cs new file mode 100644 index 0000000..b6a4375 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/IPartitionManager.cs @@ -0,0 +1,35 @@ +namespace Sa.Partitional.PostgreSql; + +/// +/// interface for managing partitions in the database +/// +public interface IPartitionManager +{ + /// + /// Migrates the existing partitions in the database. + /// This method may be used to reorganize or update partitions based on the current state of the data. + /// + /// A token to monitor for cancellation requests. + /// A task representing the asynchronous operation, with an integer result indicating the number of partitions migrated. + Task Migrate(CancellationToken cancellationToken = default); + + /// + /// Migrates partitions for specific dates. + /// This method allows for targeted migration of partitions based on the provided date range. + /// + /// An array of dates for which partitions should be migrated. + /// A token to monitor for cancellation requests. + /// A task representing the asynchronous operation, with an integer result indicating the number of partitions migrated. + Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default); + + /// + /// Ensures that the specified partitions exist for a given table and date. + /// This method checks if the specified partitions are present and creates them if they are not. + /// + /// The name of the table for which partitions are being ensured. + /// The date associated with the partition. + /// An array of values that define the partitions (could be strings or numbers). + /// A token to monitor for cancellation requests. + /// A value task representing the asynchronous operation, with a boolean result indicating whether the partitions were ensured successfully. + ValueTask EnsureParts(string tableName, DateTimeOffset date, Classes.StrOrNum[] partValues, CancellationToken cancellationToken = default); +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/IPartMigrationService.cs b/src/Sa.Partitional.PostgreSql/Migration/IPartMigrationService.cs new file mode 100644 index 0000000..83e6dfe --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/IPartMigrationService.cs @@ -0,0 +1,18 @@ + +namespace Sa.Partitional.PostgreSql; + +public interface IPartMigrationService +{ + CancellationToken OutboxMigrated { get; } + Task Migrate(CancellationToken cancellationToken = default); + Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default); + + Task WaitMigration(TimeSpan timeout, CancellationToken cancellationToken = default) + { + if (OutboxMigrated.IsCancellationRequested) return Task.FromResult(true); + + var tcs = new TaskCompletionSource(); + OutboxMigrated.Register(() => tcs.SetResult()); + return Task.Run(() => Task.WaitAny(tcs.Task, Task.Delay(timeout, cancellationToken)) == 0); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/MigrationJobConstance.cs b/src/Sa.Partitional.PostgreSql/Migration/MigrationJobConstance.cs new file mode 100644 index 0000000..5eda465 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/MigrationJobConstance.cs @@ -0,0 +1,7 @@ +namespace Sa.Partitional.PostgreSql.Migration; + +public static class MigrationJobConstance +{ + public readonly static Guid MigrationJobId = Guid.Parse("43588353-0005-4C84-97CA-40F2A620BC4C"); + public const string MigrationDefaultJobName = "Migration job"; +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/PartMigrationJob.cs b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationJob.cs new file mode 100644 index 0000000..a025652 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationJob.cs @@ -0,0 +1,11 @@ +using Sa.Schedule; + +namespace Sa.Partitional.PostgreSql.Migration; + +internal class PartMigrationJob(IPartMigrationService service) : IJob +{ + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + await service.Migrate(cancellationToken); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/PartMigrationScheduleSettings.cs b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationScheduleSettings.cs new file mode 100644 index 0000000..3383859 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationScheduleSettings.cs @@ -0,0 +1,16 @@ +namespace Sa.Partitional.PostgreSql; + +public class PartMigrationScheduleSettings +{ + public int ForwardDays { get; set; } = 2; + + public bool AsJob { get; set; } = false; + + public string? MigrationJobName { get; set; } + + public TimeSpan ExecutionInterval { get; set; } = TimeSpan + .FromHours(4) + .Add(TimeSpan.FromMinutes(Random.Shared.Next(1, 59))); + + public TimeSpan WaitMigrationTimeout { get; set; } = TimeSpan.FromSeconds(3); +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/PartMigrationService.cs b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationService.cs new file mode 100644 index 0000000..56e4943 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/PartMigrationService.cs @@ -0,0 +1,59 @@ +using Sa.Extensions; +using Sa.Timing.Providers; + +namespace Sa.Partitional.PostgreSql.Migration; + +internal sealed class PartMigrationService( + IPartRepository repository + , ICurrentTimeProvider timeProvider + , PartMigrationScheduleSettings settings +) + : IPartMigrationService, IDisposable +{ + private int s_triggered = 0; + private readonly CancellationTokenSource _cts = new(); + + public CancellationToken OutboxMigrated => _cts.Token; + + public void Dispose() + { + _cts.Dispose(); + } + + public Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default) + => repository.Migrate(dates, cancellationToken); + + public async Task Migrate(CancellationToken cancellationToken = default) + { + if (Interlocked.CompareExchange(ref s_triggered, 1, 0) == 0) + { + try + { + DateTimeOffset now = timeProvider.GetUtcNow().StartOfDay(); + DateTimeOffset[] dates = Enumerable + .Range(0, settings.ForwardDays) + .Select(i => now.AddDays(i)) + .ToArray(); + + int result = await repository.Migrate(dates, cancellationToken); + await _cts.CancelAsync(); + return result; + } + finally + { + Interlocked.CompareExchange(ref s_triggered, 0, 1); + } + } + else + { + do + { + Console.WriteLine("waiting"); + await Task.Delay(settings.WaitMigrationTimeout, cancellationToken); + } + while (s_triggered != 0); + } + + return -1; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Migration/Setup.cs b/src/Sa.Partitional.PostgreSql/Migration/Setup.cs new file mode 100644 index 0000000..58c5987 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Migration/Setup.cs @@ -0,0 +1,70 @@ +using System.Collections.Concurrent; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Schedule; + +namespace Sa.Partitional.PostgreSql.Migration; + + + +internal static class Setup +{ + private static readonly ConcurrentDictionary>> s_invokers = []; + + public static IServiceCollection AddPartMigration(this IServiceCollection services, Action? configure = null) + { + + if (configure != null) + { + if (s_invokers.TryGetValue(services, out var builder)) + { + builder.Add(configure); + } + else + { + s_invokers[services] = [configure]; + } + } + + services.TryAddSingleton(sp => + { + var item = new PartMigrationScheduleSettings(); + if (s_invokers.TryGetValue(services, out var invokers)) + { + foreach (Action invoker in invokers) + { + invoker.Invoke(sp, item); + } + s_invokers.Remove(services, out _); + } + return item; + }); + + services.TryAddSingleton(); + + + services.AddSchedule(b => b + .UseHostedService() + .AddJob((sp, builder) => + { + PartMigrationScheduleSettings migrationSettings = sp.GetRequiredService(); + + builder.WithName(migrationSettings.MigrationJobName ?? MigrationJobConstance.MigrationDefaultJobName); + + builder + .StartImmediate() + .EveryTime(migrationSettings.ExecutionInterval) + .ConfigureErrorHandling(berr => berr.DoSuppressError(err => true)) + ; + + if (!migrationSettings.AsJob) + { + builder.Disabled(); + } + + }, MigrationJobConstance.MigrationJobId) + ); + + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Part.cs b/src/Sa.Partitional.PostgreSql/Part.cs new file mode 100644 index 0000000..78c4a57 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Part.cs @@ -0,0 +1,10 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +public record Part(string Name, PartByRange PartBy) : Enumeration(Name.GetHashCode(), Name) +{ + public const string RootId = "root"; + + public static readonly Part Root = new(RootId, PartByRange.Day); +} diff --git a/src/Sa.Partitional.PostgreSql/PartByRange.cs b/src/Sa.Partitional.PostgreSql/PartByRange.cs new file mode 100644 index 0000000..55f3eb1 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/PartByRange.cs @@ -0,0 +1,20 @@ +namespace Sa.Partitional.PostgreSql; + +/// +/// Enumerates the possible partitional ranges for a PostgreSQL database. +/// +public enum PartByRange +{ + /// + /// Partition by day. + /// + Day, + /// + /// Partition by month. + /// + Month, + /// + /// Partition by year. + /// + Year +} \ No newline at end of file diff --git a/src/Sa.Partitional.PostgreSql/PartitionManager.cs b/src/Sa.Partitional.PostgreSql/PartitionManager.cs new file mode 100644 index 0000000..f4b5528 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/PartitionManager.cs @@ -0,0 +1,23 @@ +using Sa.Classes; +using Sa.Partitional.PostgreSql.Cache; + +namespace Sa.Partitional.PostgreSql; + + +internal class PartitionManager(IPartCache cache, IPartMigrationService migrationService) : IPartitionManager +{ + public ValueTask EnsureParts(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default) + { + return cache.EnsureCache(tableName, date, partValues, cancellationToken); + } + + public Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default) + { + return migrationService.Migrate(dates, cancellationToken); + } + + public Task Migrate(CancellationToken cancellationToken = default) + { + return migrationService.Migrate(cancellationToken); + } +} diff --git a/src/Sa.Partitional.PostgreSql/PgPartBy.cs b/src/Sa.Partitional.PostgreSql/PgPartBy.cs new file mode 100644 index 0000000..0b3de93 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/PgPartBy.cs @@ -0,0 +1,82 @@ +using Sa.Classes; +using Sa.Extensions; +using System.Text.RegularExpressions; + +namespace Sa.Partitional.PostgreSql; + +public record PgPartBy( + PartByRange PartByRange + , Func> GetRange + , Func Fmt + , Func ParseFmt +) + : Enumeration((int)PartByRange, PartByRange.ToString()) +{ + + public static readonly PgPartBy Day = new( + PartByRange: PartByRange.Day + , GetRange: static date => date.ToUniversalTime().StartOfDay().RangeTo(date => date.AddDays(1), false) + , Fmt: static ts => $"y{ts.Year:0000}m{ts.Month:00}d{ts.Day:00}" + , ParseFmt: static str => StrToDate(str, PartByRange.Day) + ); + + public static readonly PgPartBy Month = new( + PartByRange: PartByRange.Month + , GetRange: static date => date.ToUniversalTime().StartOfMonth().RangeTo(date => date.AddMonths(1), false) + , Fmt: static ts => $"y{ts.Year:0000}m{ts.Month:00}" + , ParseFmt: static str => StrToDate(str, PartByRange.Month) + ); + + public static readonly PgPartBy Year = new( + PartByRange: PartByRange.Year + , GetRange: static date => date.ToUniversalTime().StartOfYear().RangeTo(date => date.AddYears(1), false) + , Fmt: static ts => $"y{ts.Year:0000}" + , ParseFmt: static str => StrToDate(str, PartByRange.Year) + ); + + + + #region methods + + public static PgPartBy FromRange(PartByRange range) + => GetAll().FirstOrDefault(c => c.PartByRange == range) ?? Day; + + public static PgPartBy FromPartName(string part) + { + Part current = Part.TryFromName(part, out Part? item) ? item : Part.Root; + return FromRange(current.PartBy); + } + + public override string ToString() => Name; + + + private static DateTimeOffset? StrToDate(string str, PartByRange range) + { + if (string.IsNullOrWhiteSpace(str)) return null; + + ReadOnlySpan span = str.AsSpan(); + + return range switch + { + PartByRange.Day => FmtRegex.GetDayRegEx().IsMatch(span) ? new DateTimeOffset(span[^10..^6].StrToInt()!.Value, span[^5..^3].StrToInt()!.Value, span[^2..].StrToInt()!.Value, 0, 0, 0, TimeSpan.Zero) : null, + PartByRange.Month => FmtRegex.GetMonthRegEx().IsMatch(span) ? new DateTimeOffset(span[^7..^3].StrToInt()!.Value, span[^2..].StrToInt()!.Value, 1, 0, 0, 0, TimeSpan.Zero) : null, + PartByRange.Year => FmtRegex.GetYearRegEx().IsMatch(span) ? new DateTimeOffset(span[^4..].StrToInt()!.Value, 1, 1, 0, 0, 0, TimeSpan.Zero) : null, + _ => null, + }; + } + + #endregion +} + + +static partial class FmtRegex +{ + [GeneratedRegex(@".*y(\d{4})m(\d{2})d(\d{2})$")] + public static partial Regex GetDayRegEx(); + + [GeneratedRegex(@".*y(\d{4})m(\d{2})$")] + public static partial Regex GetMonthRegEx(); + + [GeneratedRegex(@".*y(\d{4})$")] + public static partial Regex GetYearRegEx(); +} diff --git a/src/Sa.Partitional.PostgreSql/Readme.md b/src/Sa.Partitional.PostgreSql/Readme.md new file mode 100644 index 0000000..cbe792e --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Readme.md @@ -0,0 +1,226 @@ +# Sa.Partitional.PostgreSql + +Библиотека, предназначенная для управления партиционированием таблиц в PostgreSQL +c целью улучшения производительности и управляемости в больших объемах данных. + +## Позволяет + +- Декларативно описать секционируемую таблицу по времени (день, месяц, год). +- Задать секции по спискам ключей для строк или чисел. +- Задать расписание миграций для создания новых партиций. +- Задать расписание для удаления старых партиций. +- Управлять партициями. + + +## Особенности + +- Так как макс. длина наименования таблицы составляет 63 символа, то следует учитывать выбор значения при создании партиции. +- Все таблицы имеют финальной секцией интервал по времени, который представлен столбцом с типом `int64` в формате Unix timestamps in seconds. +- Удаление старых партиций производится через DROP. + + +## Пример конфигурирования + +```csharp + +public static class PartitioningSetup +{ + public static IServiceCollection AddPartitioning(this IServiceCollection services) + { + services.AddPartitional((sp, builder) => + { + builder.AddSchema("public", schema => + { + // Настройка таблицы orders + schema.AddTable("orders", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "region TEXT NOT NULL", + "amount DECIMAL(10, 2) NOT NULL" + ) + // Партиционирование по tenant_id и region + .PartByList("tenant_id", "region") + // с интервалом в месяц по заданному столбцу + .PartByRange(PgPartBy.Month, "created_at") + ; + + + // Настройка таблицы customer + schema.AddTable("customer", + "id INT NOT NULL", + "country TEXT NOT NULL", + "city TEXT NOT NULL" + ) + // разделить в таблицах меж партиций + .WithPartSeparator("_") + // Партиционирование по country и city (если не задан PartByRange то по дням) + .PartByList("country", "city") + // Миграция партиций каждого тенанта по city + .AddMigration("RU", ["Moscow", "Samara"]) + .AddMigration("USA", ["Alabama", "New York"]) + .AddMigration("FR", ["Paris", "Lyon", "Bordeaux"]); + }); + }) + // расписание миграций - создания новых партиций + .AddPartMigrationSchedule((sp, opts) => + { + opts.AsJob = true; + opts.ExecutionInterval = TimeSpan.FromHour(12); + opts.ForwardDays = 2; + }) + // расписание удаления старых партиций + .AddPartCleanupSchedule((sp, opts) => + { + opts.AsJob = true; + opts.DropPartsAfterRetention = TimeSpan.FromDays(21); + }) + ; + + return services; + } +} + +``` + +### Результат миграции + +Для примера выше - результатом миграции будут две таблицы: + +`customer` - *таблица с данными* + +|id|country|city|created_at| +|--|-------|----|----------| +||||| + + +`customer_$part` - *таблица для учета партиций (фрагмент)* + +|id|root|part_values|part_by|from_date|to_date| +|--|----|-----------|-------|---------|-------| +|public."customer_RU_Samara_y2025m01d08"|public.customer|["s:RU","s:Samara"]|Day|1736294400|1736380800| +|public."customer_RU_Samara_y2025m01d09"|public.customer|["s:RU","s:Samara"]|Day|1736380800|1736467200| +|public."customer_USA_Alabama_y2025m01d08"|public.customer|["s:USA","s:Alabama"]|Day|1736294400|1736380800| + + +#### Итоговый DDL + +```sql + +CREATE TABLE public."customer_$part" ( + id text NOT NULL, + root text NOT NULL, + part_values text NOT NULL, + part_by text NOT NULL, + from_date int8 NOT NULL, + to_date int8 NOT NULL, + CONSTRAINT "customer_$part_pkey" PRIMARY KEY (id) +); + + +CREATE TABLE public.customer ( + id int4 NOT NULL, + country text NOT NULL, + city text NOT NULL, + created_at int8 NOT NULL, + CONSTRAINT pk_customer PRIMARY KEY (id, country, city, created_at) +) +PARTITION BY LIST (country); + +-- Partitions + +CREATE TABLE public."customer_FR" PARTITION OF public.customer FOR VALUES IN ('FR') +PARTITION BY LIST (city); + +-- Partitions + +CREATE TABLE public."customer_FR_Bordeaux" PARTITION OF public."customer_FR" FOR VALUES IN ('Bordeaux') +PARTITION BY RANGE (created_at); + +-- Partitions + +CREATE TABLE public."customer_FR_Bordeaux_y2025m01d08" PARTITION OF public."customer_FR_Bordeaux" FOR VALUES FROM ('1736294400') TO ('1736380800'); +CREATE TABLE public."customer_FR_Bordeaux_y2025m01d09" PARTITION OF public."customer_FR_Bordeaux" FOR VALUES FROM ('1736380800') TO ('1736467200'); + + +CREATE TABLE public."customer_FR_Lyon" PARTITION OF public."customer_FR" FOR VALUES IN ('Lyon') +PARTITION BY RANGE (created_at); + +-- Partitions + +CREATE TABLE public."customer_FR_Lyon_y2025m01d08" PARTITION OF public."customer_FR_Lyon" FOR VALUES FROM ('1736294400') TO ('1736380800'); +CREATE TABLE public."customer_FR_Lyon_y2025m01d09" PARTITION OF public."customer_FR_Lyon" FOR VALUES FROM ('1736380800') TO ('1736467200'); + + +CREATE TABLE public."customer_FR_Paris" PARTITION OF public."customer_FR" FOR VALUES IN ('Paris') +PARTITION BY RANGE (created_at); + +-- Partitions + +CREATE TABLE public."customer_FR_Paris_y2025m01d08" PARTITION OF public."customer_FR_Paris" FOR VALUES FROM ('1736294400') TO ('1736380800'); +CREATE TABLE public."customer_FR_Paris_y2025m01d09" PARTITION OF public."customer_FR_Paris" FOR VALUES FROM ('1736380800') TO ('1736467200'); + +-- RU + +CREATE TABLE public."customer_RU" PARTITION OF public.customer FOR VALUES IN ('RU') +PARTITION BY LIST (city); + +CREATE TABLE public."customer_RU_Moscow" PARTITION OF public."customer_RU" FOR VALUES IN ('Moscow') +PARTITION BY RANGE (created_at); + +CREATE TABLE public."customer_RU_Moscow_y2025m01d08" PARTITION OF public."customer_RU_Moscow" FOR VALUES FROM ('1736294400') TO ('1736380800'); +CREATE TAB... + +-- USA + +... +``` + + + +## PartByRange + +Используется для обозначения интервалов партиционирования данных - разбиение данных на части по дням, месяцам или годам. + +```csharp +/// +/// Enumerates the possible partitional ranges for a PostgreSQL database. +/// +public enum PartByRange +{ + Day, + Month, + Year +} +``` +*По умолчанию используется столбец `created_at` с разбиением по дням* + + +## IPartitionManager + +Интерфейс для управления партициями в базе данных. + +```csharp +public interface IPartitionManager +{ + /// + /// Migrates the existing partitions in the database. + /// This method may be used to reorganize or update partitions based on the current state of the data. + Task Migrate(CancellationToken cancellationToken = default); + + /// + /// Migrates partitions for specific dates. + /// This method allows for targeted migration of partitions based on the provided date range. + /// + Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default); + + /// + /// Ensures that the specified partitions exist for a given table and date. + /// This method checks if the specified partitions are present and creates them if they are not. + /// + /// The name of the table for which partitions are being ensured. + /// The date associated with the partition. + /// An array of values that define the partitions (could be strings or numbers). + /// A token to monitor for cancellation requests. + ValueTask EnsureParts(string tableName, DateTimeOffset date, Classes.StrOrNum[] partValues, CancellationToken cancellationToken = default); +} +``` \ No newline at end of file diff --git a/src/Sa.Partitional.PostgreSql/Repositories/IPartRepository.cs b/src/Sa.Partitional.PostgreSql/Repositories/IPartRepository.cs new file mode 100644 index 0000000..dd66ed9 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Repositories/IPartRepository.cs @@ -0,0 +1,27 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +/// +/// Represents information about a partition in a database table based on a range of values. +/// +/// The unique identifier for the partition - fully qualified name of the database table, including the schema. +/// The name of the original table from which this partition is derived. +/// An array of values that define the partitioning criteria, which can be either string or numeric. +/// The method used for partitioning (e.g., by range, list, etc.). +/// The date from which this partition is valid. +public record PartByRangeInfo(string Id, string RootTableName, StrOrNum[] PartValues, PgPartBy PartBy, DateTimeOffset FromDate); + +/// +/// Represents a repository interface for managing database partitions. +/// This interface defines methods for creating, migrating, retrieving, and dropping partitions in a database. +/// +public interface IPartRepository +{ + Task CreatePart(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default); + Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default); + Task Migrate(DateTimeOffset[] dates, Func> resolve, CancellationToken cancellationToken = default); + Task> GetPartsFromDate(string tableName, DateTimeOffset fromDate, CancellationToken cancellationToken = default); + Task> GetPartsToDate(string tableName, DateTimeOffset toDate, CancellationToken cancellationToken = default); + Task DropPartsToDate(string tableName, DateTimeOffset toDate, CancellationToken cancellationToken = default); +} diff --git a/src/Sa.Partitional.PostgreSql/Repositories/PartRepository.cs b/src/Sa.Partitional.PostgreSql/Repositories/PartRepository.cs new file mode 100644 index 0000000..02c6dad --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Repositories/PartRepository.cs @@ -0,0 +1,209 @@ +using Microsoft.Extensions.Logging; +using Npgsql; +using Sa.Classes; +using Sa.Data.PostgreSql; +using Sa.Extensions; +using Sa.Partitional.PostgreSql.SqlBuilder; + +namespace Sa.Partitional.PostgreSql.Repositories; + +internal sealed class PartRepository(IPgDataSource dataSource, ISqlBuilder sqlBuilder, ILogger? logger = null) : IPartRepository, IDisposable +{ + + /// + /// Semaphore to ensure we don't perform ddl sql concurrently for this data source. + /// + private readonly SemaphoreSlim _migrationSemaphore = new(1, 1); + + public async Task ExecuteDDL(string sql, CancellationToken cancellationToken) + { + await _migrationSemaphore.WaitAsync(cancellationToken); + try + { + return await dataSource.ExecuteNonQuery(sql, cancellationToken); + } + finally + { + _migrationSemaphore.Release(); + } + } + + public async Task CreatePart(string tableName, DateTimeOffset date, StrOrNum[] partValues, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(partValues); + + ISqlTableBuilder builder = sqlBuilder[tableName] ?? throw new KeyNotFoundException(nameof(tableName)); + string sql = builder.CreateSql(date, partValues); + return await ExecuteDDL(sql, cancellationToken); + } + + public async Task Migrate(DateTimeOffset[] dates, Func> resolve, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(dates); + ArgumentNullException.ThrowIfNull(resolve); + + int i = 0; + + await foreach (string sql in sqlBuilder.MigrateSql(dates, resolve)) + { + await ExecuteDDL(sql, cancellationToken); + i++; + } + return i; + } + + + public async Task Migrate(DateTimeOffset[] dates, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(dates); + int i = await Migrate(dates, async table => + { + ITableSettings? tableSettings = sqlBuilder[table]?.Settings; + + if (tableSettings != null) + { + IPartTableMigrationSupport? supMigration = tableSettings.Migration; + + if (supMigration != null) + { + return await supMigration.GetPartValues(cancellationToken); + } + else + { + if (tableSettings.PartByListFieldNames.Length > 0) + { + throw new InvalidOperationException($"Migration support is required for table '{table}' because 'PartByListFieldNames' is specified."); + } + } + } + + return []; + + }, cancellationToken); + + return i; + } + + public async Task> GetPartsFromDate(string tableName, DateTimeOffset fromDate, CancellationToken cancellationToken = default) + { + string sql = sqlBuilder.SelectPartsFromDateSql(tableName); + long unixTime = fromDate.ToUnixTimeSeconds(); + + return await Retry.Jitter( + async t => + { + try + { + return await dataSource.ExecuteReaderList(sql, ReadPartInfo, [new("from_date", unixTime)], t); + } + catch (PostgresException ex) when (UndefinedTable(ex)) + { + return []; + } + } + , next: HandleError + , cancellationToken: cancellationToken); + } + + + + public async Task> GetPartsToDate(string tableName, DateTimeOffset toDate, CancellationToken cancellationToken = default) + { + string sql = sqlBuilder.SelectPartsToDateSql(tableName); + try + { + return await dataSource.ExecuteReaderList( + sql + , ReadPartInfo + , [new("to_date", toDate.ToUnixTimeSeconds())] + , cancellationToken); + } + catch (PostgresException ex) when (UndefinedTable(ex)) + { + return []; + } + } + + public async Task DropPartsToDate(string tableName, DateTimeOffset toDate, CancellationToken cancellationToken = default) + { + int droppedCount = 0; + List list = await GetPartsToDate(tableName, toDate, cancellationToken); + + logger?.LogInformation("Starting to drop parts for table {TableName} up to date {ToDate}.", tableName, toDate); + + foreach (PartByRangeInfo part in list) + { + ITableSettings? settings = sqlBuilder[part.RootTableName]?.Settings; + + if (settings != null) + { + string sql = settings.DropPartSql(part.Id); + try + { + await ExecuteDDL(sql, cancellationToken); + droppedCount++; + logger?.LogInformation("Successfully dropped part with ID {PartId} from table {TableName}.", part.Id, part.RootTableName); + } + catch (PostgresException pgErr) when (UndefinedTable(pgErr)) + { + logger?.LogWarning(pgErr, "Skip to drop part with ID {PartId}.", part.Id); + } + catch (Exception ex) + { + logger?.LogError(ex, "Failed to drop part with ID {PartId}.", part.Id); + } + } + else + { + logger?.LogDebug("No settings found for root table {RootTableName}. Skipping part with ID {PartId}.", part.RootTableName, part.Id); + } + } + + + logger?.LogInformation("Finished dropping parts. Total dropped: {DroppedCount}.", droppedCount); + + return droppedCount; + } + + private static PartByRangeInfo ReadPartInfo(NpgsqlDataReader reader) + { + return new PartByRangeInfo( + reader.GetString(0) + , reader.GetString(1) + , reader.GetString(2).FromJson()! + , PgPartBy.FromPartName(reader.GetString(3)) + , reader.GetInt64(4).ToDateTimeOffsetFromUnixTimestamp() + ); + } + + private static bool HandleError(Exception ex, int _ = 0) + { + if (ex is PostgresException err) + { + return err.SqlState switch + { + PostgresErrorCodes.ConnectionException + or PostgresErrorCodes.ConnectionFailure + or PostgresErrorCodes.DeadlockDetected + or PostgresErrorCodes.CannotConnectNow + => true, //continue + + + _ => false, // abort + }; + } + + return true; + } + + + private static bool UndefinedTable(PostgresException ex) => + ex.SqlState == PostgresErrorCodes.UndefinedTable + || ex.SqlState == PostgresErrorCodes.InvalidSchemaName + ; + + public void Dispose() + { + _migrationSemaphore.Dispose(); + } +} diff --git a/src/Sa.Partitional.PostgreSql/Repositories/Setup.cs b/src/Sa.Partitional.PostgreSql/Repositories/Setup.cs new file mode 100644 index 0000000..0af8cb6 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Repositories/Setup.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Partitional.PostgreSql.Repositories; + +public static class Setup +{ + public static IServiceCollection AddPartRepository(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/Sa.Partitional.PostgreSql.csproj b/src/Sa.Partitional.PostgreSql/Sa.Partitional.PostgreSql.csproj new file mode 100644 index 0000000..3e06b4e --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Sa.Partitional.PostgreSql.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/src/Sa.Partitional.PostgreSql/Settings/IPartTableMigrationSupport.cs b/src/Sa.Partitional.PostgreSql/Settings/IPartTableMigrationSupport.cs new file mode 100644 index 0000000..02d43df --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Settings/IPartTableMigrationSupport.cs @@ -0,0 +1,8 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +public interface IPartTableMigrationSupport +{ + Task GetPartValues(CancellationToken cancellationToken); +} diff --git a/src/Sa.Partitional.PostgreSql/Settings/ITableSettings.cs b/src/Sa.Partitional.PostgreSql/Settings/ITableSettings.cs new file mode 100644 index 0000000..469fb39 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Settings/ITableSettings.cs @@ -0,0 +1,68 @@ +namespace Sa.Partitional.PostgreSql; + +/// +/// for managing database table configurations +/// +public interface ITableSettings +{ + /// + /// Gets the full name of the table, including schema. + /// + string FullName { get; } + + /// + /// Gets the name of the database schema where the table resides. + /// + string DatabaseSchemaName { get; } + + /// + /// Gets the actual name of the table in the database. + /// + string DatabaseTableName { get; } + + /// + /// Gets the name of the primary key field for the table. + /// + string IdFieldName { get; } + + /// + /// Gets an array of field names that are part of the table. + /// + string[] Fields { get; } + + /// + /// Gets an array of field names used for partitioning the table by list. + /// + string[] PartByListFieldNames { get; } + + /// + /// Gets the name of the field used for range partitioning. + /// Typically a date or numeric field. + /// + string PartByRangeFieldName { get; } + + /// + /// Gets the type of partitioning being used (e.g., list, range). + /// + PgPartBy PartBy { get; } + + /// + /// Gets an instance that supports migration for partitioned tables. + /// + IPartTableMigrationSupport Migration { get; } + + /// + /// Gets the SQL separator used in partitioning queries. + /// + string SqlPartSeparator { get; } + + /// + /// Gets a function that returns additional SQL to be executed after the root SQL statement. + /// + Func? PostRootSql { get; } + + /// + /// Gets a function that returns SQL for defining primary key constraints. + /// + Func? ConstraintPkSql { get; } +} \ No newline at end of file diff --git a/src/Sa.Partitional.PostgreSql/Settings/ITableSettingsStorage.cs b/src/Sa.Partitional.PostgreSql/Settings/ITableSettingsStorage.cs new file mode 100644 index 0000000..1125fe4 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Settings/ITableSettingsStorage.cs @@ -0,0 +1,8 @@ + +namespace Sa.Partitional.PostgreSql; + +public interface ITableSettingsStorage +{ + IReadOnlyCollection Schemas { get; } + IReadOnlyCollection Tables { get; } +} diff --git a/src/Sa.Partitional.PostgreSql/Settings/TableSettings.cs b/src/Sa.Partitional.PostgreSql/Settings/TableSettings.cs new file mode 100644 index 0000000..a485f8f --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Settings/TableSettings.cs @@ -0,0 +1,69 @@ +using System.Diagnostics; + +namespace Sa.Partitional.PostgreSql.Settings; + +[DebuggerDisplay("settings root = {DatabaseTableName}")] +internal class TableSettings : ITableSettings +{ + static class Default + { + public readonly static PgPartBy DefaultPartBy = PgPartBy.Day; + public const string PartByRangeFieldName = "created_at"; + public const string SqlPartSeparator = "__"; + } + + public TableSettings( + string schemaName + , string tableName + , string[] fields + , string[] partByListFields + , IPartTableMigrationSupport migration + , PgPartBy? partByRange + , Func? postRootSql = null + , Func? constraintPkSql = null + , string? timestampField = null + , string? sqlPartSeparator = null + ) + { + DatabaseSchemaName = schemaName; + DatabaseTableName = tableName.Trim('"'); + Fields = fields; + Migration = migration; + + PartBy = partByRange ?? Default.DefaultPartBy; + + PartByListFieldNames = partByListFields; + PartByRangeFieldName = timestampField ?? Default.PartByRangeFieldName; + PartitionByFieldName = PartByListFieldNames.Length == 0 ? PartByRangeFieldName : partByListFields[0]; + + PostRootSql = postRootSql; + ConstraintPkSql = constraintPkSql; + + IdFieldName = GetIdName(Array.Find(fields, c => !string.IsNullOrWhiteSpace(c))); + + FullName = $@"{DatabaseSchemaName}.{DatabaseTableName}"; + SqlPartSeparator = sqlPartSeparator ?? Default.SqlPartSeparator; + } + + public string IdFieldName { get; } + public string[] Fields { get; } + public IPartTableMigrationSupport Migration { get; } + + public PgPartBy PartBy { get; } + + public string DatabaseSchemaName { get; } + public string DatabaseTableName { get; } + public string PartByRangeFieldName { get; } + public string[] PartByListFieldNames { get; } + public string PartitionByFieldName { get; } + public string FullName { get; } + public string SqlPartSeparator { get; } + + + // extensions + public Func? PostRootSql { get; } + public Func? ConstraintPkSql { get; } + + static string GetIdName(string? idSql) => idSql?.Trim().Split(' ')[0] ?? string.Empty; + +} diff --git a/src/Sa.Partitional.PostgreSql/Settings/TableSettingsStorage.cs b/src/Sa.Partitional.PostgreSql/Settings/TableSettingsStorage.cs new file mode 100644 index 0000000..2e34692 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Settings/TableSettingsStorage.cs @@ -0,0 +1,13 @@ + +namespace Sa.Partitional.PostgreSql.Settings; + +internal class TableSettingsStorage(IReadOnlyCollection settings) : ITableSettingsStorage +{ + + public IReadOnlyCollection Schemas { get; } = settings + .Select(c => c.DatabaseSchemaName) + .Distinct() + .ToArray(); + + public IReadOnlyCollection Tables => settings; +} diff --git a/src/Sa.Partitional.PostgreSql/Setup.cs b/src/Sa.Partitional.PostgreSql/Setup.cs new file mode 100644 index 0000000..52137ed --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/Setup.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Partitional.PostgreSql.Configuration; + +namespace Sa.Partitional.PostgreSql; + +public static class Setup +{ + public static IPartConfiguration AddPartitional(this IServiceCollection services, Action configure, bool? asJob = null) + { + services.AddSaInfrastructure(); + services.TryAddSingleton(); + + return new PartConfiguration(services) + // defaults + .AddDataSource() + .AddPartTables(configure) + .AddPartCache() + .AddPartMigrationSchedule((_, settings) => settings.AsJob = asJob ?? settings.AsJob) + .AddPartCleanupSchedule((_, settings) => settings.AsJob = asJob ?? settings.AsJob) + ; + } +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilder.cs new file mode 100644 index 0000000..e8e5e4b --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilder.cs @@ -0,0 +1,22 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +public interface ISqlBuilder +{ + ISqlTableBuilder? this[string tableName] { get; } + + IReadOnlyCollection Tables { get; } + + IAsyncEnumerable MigrateSql(DateTimeOffset[] dates, Func> resolve); + + string CreatePartSql(string tableName, DateTimeOffset date, StrOrNum[] partValues); + + string SelectPartsQualifiedTablesSql(string tableName, StrOrNum[] partValues); + + string SelectPartsQualifiedTablesSql(string qualifiedTablesSql); + + string SelectPartsFromDateSql(string tableName); + + string SelectPartsToDateSql(string tableName); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilderFactory.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilderFactory.cs new file mode 100644 index 0000000..a4a0f99 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlBuilderFactory.cs @@ -0,0 +1,6 @@ +namespace Sa.Partitional.PostgreSql; + +public interface ISqlBuilderFactory +{ + ISqlBuilder Create(); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlTableBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlTableBuilder.cs new file mode 100644 index 0000000..7554f66 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/ISqlTableBuilder.cs @@ -0,0 +1,17 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql; + +public interface ISqlTableBuilder +{ + string FullName { get; } + + ITableSettings Settings { get; } + + string SelectPartsFromDate { get; } + string SelectPartsToDate { get; } + + string GetPartsSql(StrOrNum[] partValues); + + string CreateSql(DateTimeOffset date, params StrOrNum[] partValues); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/Setup.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/Setup.cs new file mode 100644 index 0000000..31d00fd --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/Setup.cs @@ -0,0 +1,15 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +internal static class Setup +{ + public static IServiceCollection AddSqlBuilder(this IServiceCollection services) + { + services.TryAddSingleton(); + services.TryAddSingleton(sp => sp.GetRequiredService().Create()); + + return services; + } +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilder.cs new file mode 100644 index 0000000..3111bd1 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilder.cs @@ -0,0 +1,89 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +internal class SqlBuilder(ITableSettingsStorage storage) : ISqlBuilder +{ + private readonly Dictionary builders = storage + .Tables + .Select(table => new SqlTableBuilder(table)) + .ToDictionary(c => c.FullName); + + + public IReadOnlyCollection Tables => builders.Values; + + public async IAsyncEnumerable MigrateSql(DateTimeOffset[] dates, Func> resolve) + { + foreach (string table in builders.Keys) + { + SqlTableBuilder builder = builders[table] ?? throw new KeyNotFoundException(table); + + StrOrNum[][] parValues = await resolve(table); + + if (parValues.Length > 0) + { + foreach (StrOrNum[] parts in parValues) + { + foreach (DateTimeOffset date in dates) + { + string sql = builder.CreateSql(date, parts); + yield return sql; + } + } + } + else + { + foreach (DateTimeOffset date in dates) + { + string sql = builder.CreateSql(date); + yield return sql; + } + } + } + } + + public ISqlTableBuilder? this[string tableName] => Find(tableName ?? throw new ArgumentNullException(nameof(tableName))); + + + public string SelectPartsQualifiedTablesSql(string tableName, StrOrNum[] partValues) + => (Find(tableName) ?? throw new KeyNotFoundException(tableName)).GetPartsSql(partValues); + + public string SelectPartsQualifiedTablesSql(string qualifiedTablesSql) + => SqlTemplate.SelectPartsQualifiedTablesSql(qualifiedTablesSql); + + public string SelectPartsFromDateSql(string tableName) + => (Find(tableName) ?? throw new KeyNotFoundException(tableName)).SelectPartsFromDate; + + public string SelectPartsToDateSql(string tableName) + => (Find(tableName) ?? throw new KeyNotFoundException(tableName)).SelectPartsToDate; + + public string CreatePartSql(string tableName, DateTimeOffset date, StrOrNum[] partValues) + => (Find(tableName) ?? throw new KeyNotFoundException(tableName)).CreateSql(date); + + #region privates + private ISqlTableBuilder? Find(string tableName) + { + ISqlTableBuilder? item = + ( + storage.Schemas.Count == 1 + ? builders.GetValueOrDefault(GetFullName(storage.Schemas.First(), tableName)) + : builders.Values.FirstOrDefault(c => c.FullName == tableName) + ) + ?? builders.GetValueOrDefault(tableName); + + if (item != null) return item; + + if (tableName.Contains('"')) + { + tableName = tableName.Replace("\"", ""); + return Find(tableName); + } + return item; + } + + static string GetFullName(string schemaName, string tableName) => $"{schemaName}.{tableName}"; + + + + #endregion +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilderFactory.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilderFactory.cs new file mode 100644 index 0000000..21bcaea --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlBuilderFactory.cs @@ -0,0 +1,6 @@ +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +internal class SqlBuilderFactory(ISettingsBuilder configuration) : ISqlBuilderFactory +{ + public ISqlBuilder Create() => new SqlBuilder(configuration.Build()); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartListBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartListBuilder.cs new file mode 100644 index 0000000..ccd361e --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartListBuilder.cs @@ -0,0 +1,18 @@ +using Sa.Classes; +using Sa.Extensions; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +/// +/// public."_outbox_root" +/// +internal class SqlPartListBuilder(ITableSettings settings) +{ + public string CreateSql(StrOrNum[] partValues) + => partValues.Length > 0 + ? partValues + .Select((c, i) => settings.CreateNestedSql(partValues[0..(i + 1)])) + .JoinByString(Environment.NewLine) + : string.Empty + ; +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartRangeBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartRangeBuilder.cs new file mode 100644 index 0000000..4ec9767 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlPartRangeBuilder.cs @@ -0,0 +1,12 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +/// +/// public."_outbox_root__y2024m12d11" +/// +internal class SqlPartRangeBuilder(ITableSettings settings) +{ + public string CreateSql(DateTimeOffset date, StrOrNum[] partValues) + => settings.CreatePartByRangeSql(date, partValues); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlRootBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlRootBuilder.cs new file mode 100644 index 0000000..ae9abbe --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlRootBuilder.cs @@ -0,0 +1,12 @@ +namespace Sa.Partitional.PostgreSql.SqlBuilder; + + +/// +/// public."_outbox" +/// -- CREATE INDEX IF NOT EXISTS ix__outbox__payload_type ON public."_outbox" (payload_type); +/// +internal class SqlRootBuilder(ITableSettings settings) +{ + private readonly Lazy _sql = new(settings.CreateRootSql); + public string CreateSql() => _sql.Value; +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTableBuilder.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTableBuilder.cs new file mode 100644 index 0000000..e1b0b58 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTableBuilder.cs @@ -0,0 +1,47 @@ +using Sa.Classes; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +internal class SqlTableBuilder(ITableSettings settings) : ISqlTableBuilder +{ + private readonly SqlRootBuilder rootBuilder = new(settings); + private readonly SqlPartListBuilder partListBuilder = new(settings); + private readonly SqlPartRangeBuilder partRangeBuilder = new(settings); + + public string FullName => settings.FullName; + + public ITableSettings Settings => settings; + + + public string CreateSql(DateTimeOffset date, params StrOrNum[] partValues) + { + if (settings.PartByListFieldNames.Length != partValues.Length) + { + return +$""" +-- {date} +{rootBuilder.CreateSql()} + +-- incomplete number of parts +{partListBuilder.CreateSql(partValues)} +"""; + + } + + return +$""" +-- {date} +{rootBuilder.CreateSql()} +{partListBuilder.CreateSql(partValues)} +{partRangeBuilder.CreateSql(date, partValues)} +"""; + } + + public string GetPartsSql(StrOrNum[] partValues) => settings.SelectPartsQualifiedTablesSql(partValues); + + public override string ToString() => $"{FullName} {Settings.PartByListFieldNames}"; + + public string SelectPartsFromDate { get; } = settings.SelectPartsFromDateSql(); + + public string SelectPartsToDate { get; } = settings.SelectPartsToDateSql(); +} diff --git a/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTemplate.cs b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTemplate.cs new file mode 100644 index 0000000..03ba734 --- /dev/null +++ b/src/Sa.Partitional.PostgreSql/SqlBuilder/SqlTemplate.cs @@ -0,0 +1,159 @@ +using Sa.Classes; +using Sa.Extensions; + +namespace Sa.Partitional.PostgreSql.SqlBuilder; + +internal static class SqlTemplate +{ + const string CacheByRangeTableNamePostfix = "$part"; + + public static string CreateRootSql(this ITableSettings settings) + { + string pkList = settings.PartByListFieldNames.Contains(settings.IdFieldName) + ? settings.PartByListFieldNames.JoinByString(",") + : new string[] { settings.IdFieldName }.Concat(settings.PartByListFieldNames).JoinByString(",") + ; + + return $""" + +CREATE SCHEMA IF NOT EXISTS {settings.DatabaseSchemaName}; + +CREATE TABLE IF NOT EXISTS {settings.GetQualifiedTableName()} ( + {settings.Fields.JoinByString($",{Environment.NewLine} ")}, + {settings.PartByRangeFieldName} bigint NOT NULL, + CONSTRAINT "{settings.Pk()}" PRIMARY KEY ({pkList},{settings.PartByRangeFieldName}) +) {settings.GetPartitionalSql(0)} +; + +-- post sql +{settings.PostRootSql?.Invoke()} + +"""; + } + + public static string CreateNestedSql(this ITableSettings settings, StrOrNum[] values) => +$""" + + +-- {settings.GetPartitionalSql(values.Length - 1)[18..]} + +CREATE TABLE IF NOT EXISTS {settings.GetQualifiedTableName(values)} +PARTITION OF {settings.GetQualifiedTableName(values[0..^1])} +FOR VALUES IN ({values[^1].Match(s => $"'{s}'", n => n.ToString())}) +{settings.GetPartitionalSql(values.Length)} +; +"""; + + public static string CreatePartByRangeSql(this ITableSettings settings, DateTimeOffset date, StrOrNum[] values) + { + string timeRangeTablename = settings.GetQualifiedTableName(date, values); + LimSection range = settings.PartBy.GetRange(date); + string cacheTablename = settings.GetCacheByRangeTableName(); + + return +$""" + + +-- ({settings.PartByRangeFieldName}) part by: {settings.PartBy} + +CREATE TABLE IF NOT EXISTS {timeRangeTablename} +PARTITION OF {settings.GetQualifiedTableName(values)} +FOR VALUES FROM ({range.Start.ToUnixTimeSeconds()}) TO ({range.End.ToUnixTimeSeconds()}) +; + +-- cache + +CREATE TABLE IF NOT EXISTS {cacheTablename} ( + id TEXT PRIMARY KEY, + root TEXT NOT NULL, + part_values TEXT NOT NULL, + part_by TEXT NOT NULL, + from_date bigint NOT NULL, + to_date bigint NOT NULL +) +; + +INSERT INTO {cacheTablename} (id,root,part_values,part_by,from_date,to_date) +VALUES ('{timeRangeTablename}','{settings.FullName}','{values.ToJson()}','{settings.PartBy.Name}',{range.Start.ToUnixTimeSeconds()},{range.End.ToUnixTimeSeconds()}) +ON CONFLICT (id) DO NOTHING +; + +""" + ; + } + + public static string SelectPartsFromDateSql(this ITableSettings settings) + { + return +$""" +SELECT id,root,part_values,part_by,from_date +FROM {settings.GetCacheByRangeTableName()} +WHERE root = '{settings.FullName}' AND from_date >= @from_date +ORDER BY from_date DESC +; +"""; + } + + + public static string SelectPartsToDateSql(this ITableSettings settings) + { + return +$""" +SELECT id,root,part_values,part_by,from_date +FROM {settings.GetCacheByRangeTableName()} +WHERE + root = '{settings.FullName}' + AND to_date <= @to_date +ORDER BY from_date ASC +; +"""; + } + + + public static string SelectPartsQualifiedTablesSql(this ITableSettings settings, StrOrNum[] values) + => SelectPartsQualifiedTablesSql(settings.GetQualifiedTableName(values)); + + public static string SelectPartsQualifiedTablesSql(string qualifiedTableName) + => +$""" +WITH pt AS ( + SELECT inhrelid::regclass AS pt + FROM pg_inherits + WHERE inhparent = '{qualifiedTableName}'::regclass +) +SELECT pt::text from pt +; +"""; + + + public static string DropPartSql(this ITableSettings settings, string qualifiedTableName) + { + return $""" +DROP TABLE IF EXISTS {qualifiedTableName}; +DELETE FROM {settings.GetCacheByRangeTableName()} WHERE id='{qualifiedTableName}'; +"""; + } + + public static string GetQualifiedTableName(this ITableSettings settings, DateTimeOffset? date, StrOrNum[] values) + => date != null + ? settings.GetQualifiedTableName([.. values, settings.PartBy.Fmt(date.Value)]) + : settings.GetQualifiedTableName(values); + + + private static string GetCacheByRangeTableName(this ITableSettings settings) => settings.GetQualifiedTableName(CacheByRangeTableNamePostfix); + + + static string GetQualifiedTableName(this ITableSettings settings, params StrOrNum[] values) + => values.Length > 0 + ? $"{settings.DatabaseSchemaName}.\"{settings.DatabaseTableName}{settings.SqlPartSeparator}{values.JoinByString(settings.SqlPartSeparator)}\"" + : $"{settings.DatabaseSchemaName}.\"{settings.DatabaseTableName}\"" + ; + + static string GetPartitionalSql(this ITableSettings settings, int partIndex) + => partIndex >= 0 && partIndex < settings.PartByListFieldNames.Length + ? $"PARTITION BY LIST ({settings.PartByListFieldNames[partIndex]})" + : $"PARTITION BY RANGE ({settings.PartByRangeFieldName})" + ; + + static string Pk(this ITableSettings settings) => settings.ConstraintPkSql?.Invoke() ?? $"pk_{settings.DatabaseTableName}"; +} diff --git a/src/Sa.Partitional.Support/Part.cs b/src/Sa.Partitional.Support/Part.cs new file mode 100644 index 0000000..5757441 --- /dev/null +++ b/src/Sa.Partitional.Support/Part.cs @@ -0,0 +1,10 @@ +using Sa.Classes; + +namespace Sa.Partitional.Support; + +public record Part(string Name, PartByRange PartBy) : Enumeration(Name.GetHashCode(), Name) +{ + public const string RootId = "root"; + + public static readonly Part Root = new(RootId, PartByRange.Day); +} diff --git a/src/Sa.Partitional.Support/PartByRange.cs b/src/Sa.Partitional.Support/PartByRange.cs new file mode 100644 index 0000000..ed08c74 --- /dev/null +++ b/src/Sa.Partitional.Support/PartByRange.cs @@ -0,0 +1,8 @@ +namespace Sa.Partitional.Support; + +public enum PartByRange +{ + Day, + Month, + Year +} diff --git a/src/Sa.Partitional.Support/Sa.Partitional.Support.csproj b/src/Sa.Partitional.Support/Sa.Partitional.Support.csproj new file mode 100644 index 0000000..c9a9dd6 --- /dev/null +++ b/src/Sa.Partitional.Support/Sa.Partitional.Support.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.Schedule/Engine/JobContext.cs b/src/Sa.Schedule/Engine/JobContext.cs new file mode 100644 index 0000000..27b1b9d --- /dev/null +++ b/src/Sa.Schedule/Engine/JobContext.cs @@ -0,0 +1,59 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Sa.Schedule.Settings; + +namespace Sa.Schedule.Engine; + +public class JobContext(IJobSettings settings) : IJobContext +{ + public Guid JobId => settings.JobId; + + public string JobName => settings.Properties.JobName ?? $"{JobId}"; + + public JobStatus Status { get; set; } + + public IJobSettings Settings => settings; + + public ulong NumIterations { get; set; } + + public ulong FailedIterations { get; set; } + + public ulong CompetedIterations { get; set; } + + public int FailedRetries { get; set; } + + public JobException? LastError { get; set; } + + public DateTimeOffset CreatedAt { get; set; } + + public DateTimeOffset? ExecuteAt { get; set; } + + public ulong NumRuns { get; set; } + + public IServiceProvider JobServices { get; set; } = NullJobServices.Instance; + + public Queue Stack { get; private set; } = new(); + + IEnumerable IJobContext.Stack => Stack.Reverse(); + + public ILogger Logger => JobServices.GetService>() ?? NullLogger.Instance; + + public IJobContext Clone() + { + JobContext clone = new(Settings) + { + NumIterations = NumIterations, + FailedRetries = FailedRetries, + FailedIterations = FailedIterations, + LastError = LastError, + CreatedAt = CreatedAt, + ExecuteAt = ExecuteAt, + Status = Status, + NumRuns = NumRuns, + Stack = new Queue(Stack.Select(x => x.Clone())), + }; + + return clone; + } +} diff --git a/src/Sa.Schedule/Engine/JobController.cs b/src/Sa.Schedule/Engine/JobController.cs new file mode 100644 index 0000000..2a89ced --- /dev/null +++ b/src/Sa.Schedule/Engine/JobController.cs @@ -0,0 +1,132 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Sa.Schedule.Settings; +using Sa.Timing.Providers; + +namespace Sa.Schedule.Engine; + + +/// +/// job lifecycly controller with context +/// +internal class JobController(IJobSettings settings, IInterceptorSettings interceptorSettings, IServiceScopeFactory scopeFactory) : IJobController +{ + private readonly JobContext context = new(settings); + + private JobPipeline? _job; + + public IJobContext Context => context; + + public DateTimeOffset UtcNow => context.JobServices.GetService()?.GetUtcNow() + ?? DateTimeOffset.UtcNow; + + public async ValueTask WaitToRun(CancellationToken cancellationToken) + { + if (context.NumRuns == 0 && settings.Properties.InitialDelay.HasValue && settings.Properties.InitialDelay.Value != TimeSpan.Zero) + { + context.Status = JobStatus.WaitingToRun; + await Task.Delay(settings.Properties.InitialDelay.Value, cancellationToken); + } + } + + public void Running() + { + _job = new JobPipeline(settings, interceptorSettings, scopeFactory); + + context.JobServices = _job.JobServices; + context.Status = JobStatus.Running; + + if (context.NumRuns == 0) context.CreatedAt = UtcNow; + context.NumRuns++; + } + + public void Stopped(TaskStatus status) + { + switch (status) + { + case TaskStatus.Faulted: context.Status = JobStatus.Failed; break; + case TaskStatus.Canceled: context.Status = JobStatus.Cancelled; break; + case TaskStatus.RanToCompletion: context.Status = JobStatus.Completed; break; + } + + context.JobServices = NullJobServices.Instance; + _job?.Dispose(); + } + + public async ValueTask CanExecute(CancellationToken cancellationToken) + { + if (settings.Properties.IsRunOnce == true && context.NumIterations > 0) + return CanJobExecuteResult.Abort; + + if (context.NumIterations == 0 && settings.Properties.Immediate == true) + return CanJobExecuteResult.Ok; + + IJobTiming? timing = settings.Properties.Timing; + + if (timing != null) + { + DateTimeOffset now = UtcNow; + + DateTimeOffset? next = timing.GetNextOccurrence(now, context); + + if (!next.HasValue) + return CanJobExecuteResult.Abort; + + TimeSpan delay = next.Value - now; + + if (delay.TotalMilliseconds > 0) + { + await Task.Delay(delay, cancellationToken); + } + } + + int stackSize = settings.Properties.ContextStackSize.GetValueOrDefault(); + + if (stackSize > 0) + { + if (context.Stack.Count == stackSize) context.Stack.Dequeue(); + context.Stack.Enqueue(context.Clone()); + } + + return !cancellationToken.IsCancellationRequested + ? CanJobExecuteResult.Ok + : CanJobExecuteResult.Abort; + } + + public Task Execute(CancellationToken cancellationToken) + { + context.NumIterations++; + context.ExecuteAt = UtcNow; + return _job!.Execute(Context, cancellationToken); + } + + public void ExecutionCompleted() + { + context.CompetedIterations++; + context.FailedRetries = 0; + } + + public void ExecutionFailed(Exception exception) + { + JobException error = new(context, exception); + context.FailedIterations++; + context.LastError = error; + + IJobErrorHandling errorHandling = settings.ErrorHandling; + + if (errorHandling.HasSuppressError && errorHandling.SuppressError?.Invoke(exception) == true) + { + context.Logger.LogWarning("[{JobName}] the error: “{Error}” on job was suppressed to continue", context.JobName, exception.Message); + return; + } + + if (context.FailedRetries < settings.ErrorHandling.RetryCount) + { + context.FailedRetries++; + context.Logger.LogWarning("[{JobName}] {FailedRetryAttempts} out of {RetryCount} reps when the job failed due to an error: “{Error}”", context.JobName, context.FailedRetries, errorHandling.RetryCount, exception.Message); + return; + } + + context.JobServices.GetService()?.HandleError(Context, error); + } +} diff --git a/src/Sa.Schedule/Engine/JobErrorHandler.cs b/src/Sa.Schedule/Engine/JobErrorHandler.cs new file mode 100644 index 0000000..d80b05b --- /dev/null +++ b/src/Sa.Schedule/Engine/JobErrorHandler.cs @@ -0,0 +1,91 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Sa.Schedule.Engine; + +internal class JobErrorHandler(IScheduleSettings settings, IHostApplicationLifetime? lifetime, ILogger? logger) : IJobErrorHandler +{ + public void HandleError(IJobContext context, Exception exception) + { + if (settings.HandleError?.Invoke(context, exception) != true) + { + // default handle + DoHandleError(context, exception); + } + + throw exception; + } + + private void DoHandleError(IJobContext context, Exception exception) + { + switch (context.Settings.ErrorHandling.ThenAction) + { + case ErrorHandlingAction.AbortJob: + AbortJob(context.JobName, exception); + break; + + case ErrorHandlingAction.CloseApplication: + CloseApplication(context.JobName, context.JobServices.GetRequiredService(), exception); + break; + + case ErrorHandlingAction.StopAllJobs: + StopAllJobs(context.JobName, context.JobServices.GetRequiredService(), exception); + break; + + default: + logger?.LogError(exception, "[{JobName}] Unknown error", context.JobName); + break; + } + + throw context.LastError ?? exception; + } + + private void AbortJob(string jobName, Exception exception) + { + logger?.LogError(exception, @" +************ +JOB: {JobName} +ERROR: The job will be aborted, the reason is an error: +{Error} +************ + ", jobName, exception.Message); + } + + private void StopAllJobs(string jobName, IScheduler scheduler, Exception exception) + { + logger?.LogError(exception, @" +************ +JOB: {JobName} +ERROR: The all jobs will be stoped, the reason is an error: +{Error} +************ + ", jobName, exception.Message); + + + if (scheduler == null) throw exception; + scheduler.Stop(); + } + + private void CloseApplication(string jobName, IScheduler scheduler, Exception exception) + { + logger?.LogError(exception, @" +************ +JOB: {JobName} +ERROR: The application will be closed, the reason is an error: +{Error} +************ + ", jobName, exception.Message); + + if (lifetime == null) throw exception; + + if (scheduler.Settings.IsHostedService) + { + lifetime.StopApplication(); + } + else + { + scheduler.Stop().ContinueWith(_ => lifetime.StopApplication()); + } + } +} diff --git a/src/Sa.Schedule/Engine/JobFactory.cs b/src/Sa.Schedule/Engine/JobFactory.cs new file mode 100644 index 0000000..be332d3 --- /dev/null +++ b/src/Sa.Schedule/Engine/JobFactory.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Schedule.Settings; + +namespace Sa.Schedule.Engine; + +internal class JobFactory(IServiceScopeFactory scopeFactory, IInterceptorSettings interceptorSettings, IJobRunner jobRunner) : IJobFactory +{ + public IJobController CreateJobController(IJobSettings settings) + => new JobController(settings, interceptorSettings, scopeFactory); + + public IJobScheduler CreateJobSchedule(IJobSettings settings) + => new JobScheduler(jobRunner, CreateJobController(settings)); +} diff --git a/src/Sa.Schedule/Engine/JobPipeline.cs b/src/Sa.Schedule/Engine/JobPipeline.cs new file mode 100644 index 0000000..3400709 --- /dev/null +++ b/src/Sa.Schedule/Engine/JobPipeline.cs @@ -0,0 +1,47 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Schedule.Settings; + +namespace Sa.Schedule.Engine; + +internal sealed class JobPipeline : IJob, IDisposable +{ + #region proxy + class JobProxy(IJob job, IJobInterceptor interceptor, object? key) : IJob + { + public Task Execute(IJobContext context, CancellationToken cancellationToken) + => interceptor.OnHandle( + context + , () => job.Execute(context, cancellationToken) + , key + , cancellationToken); + } + #endregion + + private readonly IServiceScope _scope; + private readonly IJob _job; + + public JobPipeline(IJobSettings settings, IInterceptorSettings interceptorSettings, IServiceScopeFactory scopeFactory) + { + _scope = scopeFactory.CreateScope(); + IJob originalJob = (IJob)_scope.ServiceProvider.GetRequiredKeyedService(settings.JobType, settings.JobId); + + if (interceptorSettings.Interceptors.Count > 0) + { + _job = interceptorSettings + .Interceptors + .Reverse() + .Aggregate(originalJob, (job, s) + => new JobProxy(job, (IJobInterceptor)_scope.ServiceProvider.GetRequiredKeyedService(s.HandlerType, s.Key), s.Key)); + } + else + { + _job = originalJob; + } + } + + public IServiceProvider JobServices => _scope.ServiceProvider; + + public void Dispose() => _scope.Dispose(); + + public Task Execute(IJobContext context, CancellationToken cancellationToken) => _job.Execute(context, cancellationToken); +} diff --git a/src/Sa.Schedule/Engine/JobRunner.cs b/src/Sa.Schedule/Engine/JobRunner.cs new file mode 100644 index 0000000..4dcc155 --- /dev/null +++ b/src/Sa.Schedule/Engine/JobRunner.cs @@ -0,0 +1,44 @@ +using System.Diagnostics; + +namespace Sa.Schedule.Engine; + + +internal class JobRunner() : IJobRunner +{ + public async Task Run(IJobController controller, CancellationToken cancellationToken) + { + await controller.WaitToRun(cancellationToken); + + controller.Running(); + + await RunLoop(controller, cancellationToken) + .ContinueWith(t => controller.Stopped(t.Status), CancellationToken.None); + } + + [StackTraceHidden] + private static async Task RunLoop(IJobController controller, CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested) + { + CanJobExecuteResult next = await controller.CanExecute(cancellationToken); + + if (next == CanJobExecuteResult.Abort) break; + if (next == CanJobExecuteResult.Skip) continue; + + try + { + await controller.Execute(cancellationToken); + controller.ExecutionCompleted(); + } + catch (OperationCanceledException ex) when (ex.CancellationToken == cancellationToken) + { + // skip + } + catch (Exception ex) + { + controller.ExecutionFailed(ex); + } + } + } +} + diff --git a/src/Sa.Schedule/Engine/JobScheduler.cs b/src/Sa.Schedule/Engine/JobScheduler.cs new file mode 100644 index 0000000..6612427 --- /dev/null +++ b/src/Sa.Schedule/Engine/JobScheduler.cs @@ -0,0 +1,99 @@ +using Microsoft.Extensions.Primitives; + +namespace Sa.Schedule.Engine; + +internal sealed class JobScheduler(IJobRunner runner, IJobController controller) : IJobScheduler, IDisposable, IAsyncDisposable +{ + private readonly static IChangeToken NoneChangeToken = new CancellationChangeToken(CancellationToken.None); + + private readonly object _locked = new(); + + private TaskCompletionSource? _stoppingTask; + + private CancellationTokenSource _stoppingToken = new(); + private CancellationToken _originalToken; + + private bool _disposed; + + public IJobContext Context => controller.Context; + + public bool IsActive => _stoppingTask?.Task.Status == TaskStatus.WaitingForActivation; + + public IChangeToken GetActiveChangeToken() + { + if (_disposed) return NoneChangeToken; + + lock (_locked) + { + return new CancellationChangeToken(_stoppingToken.Token); + } + } + + /// + /// Start all jobs + /// + public bool Start(CancellationToken cancellationToken) + { + if (IsActive) return false; + + lock (_locked) + { + _stoppingToken.Cancel(); + _stoppingToken.Dispose(); + + _originalToken = cancellationToken; + _stoppingToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + + _stoppingTask = new TaskCompletionSource(); + + Task task = runner.Run(controller, _stoppingToken.Token); + + task.ContinueWith(Done, CancellationToken.None); + + return true; + } + } + + public bool Restart() => Start(_originalToken); + + public Task Stop() + { + if (IsActive) + { + lock (_locked) + { + _stoppingToken?.Cancel(); + } + } + + return _stoppingTask?.Task ?? Task.CompletedTask; + } + + private void Done(Task task) + { + lock (_locked) + { + _stoppingTask?.TrySetResult(); + } + } + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + _ = Stop(); + _stoppingToken.Dispose(); + } + } + + public async ValueTask DisposeAsync() + { + if (!_disposed) + { + _disposed = true; + await Stop(); + _stoppingToken.Dispose(); + } + } +} diff --git a/src/Sa.Schedule/Engine/JobTiming.cs b/src/Sa.Schedule/Engine/JobTiming.cs new file mode 100644 index 0000000..89e9eb3 --- /dev/null +++ b/src/Sa.Schedule/Engine/JobTiming.cs @@ -0,0 +1,12 @@ +namespace Sa.Schedule.Engine; + +public class JobTiming(Func nextTime, string name) : IJobTiming +{ + public string TimingName => name; + public DateTimeOffset? GetNextOccurrence(DateTimeOffset dateTime, IJobContext context) => nextTime(dateTime, context); + + public static IJobTiming EveryTime(TimeSpan timeSpan, string? name = null) => + new JobTiming((dateTime, _) => dateTime.Add(timeSpan), name ?? $"every {timeSpan}"); + + public static IJobTiming Default { get; } = EveryTime(TimeSpan.FromSeconds(1), "default every seconds"); +} diff --git a/src/Sa.Schedule/Engine/ScheduleHost.cs b/src/Sa.Schedule/Engine/ScheduleHost.cs new file mode 100644 index 0000000..0920b6c --- /dev/null +++ b/src/Sa.Schedule/Engine/ScheduleHost.cs @@ -0,0 +1,17 @@ +using Microsoft.Extensions.Hosting; + +namespace Sa.Schedule.Engine; + +internal sealed class ScheduleHost(IScheduler controller) : IHostedService +{ + public Task StartAsync(CancellationToken cancellationToken) + { + controller.Start(cancellationToken); + return Task.CompletedTask; + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + await controller.Stop(); + } +} diff --git a/src/Sa.Schedule/Engine/Scheduler.cs b/src/Sa.Schedule/Engine/Scheduler.cs new file mode 100644 index 0000000..8e94f19 --- /dev/null +++ b/src/Sa.Schedule/Engine/Scheduler.cs @@ -0,0 +1,33 @@ +namespace Sa.Schedule.Engine; + +internal sealed class Scheduler(IScheduleSettings settings, IJobFactory factory) : IScheduler, IDisposable, IAsyncDisposable +{ + private bool _disposed; + + public IScheduleSettings Settings => settings; + + public IReadOnlyCollection Schedules { get; } = settings + .GetJobSettings() + .Select(factory.CreateJobSchedule) + .ToArray(); + + /// + /// Start all jobs + /// + public int Start(CancellationToken cancellationToken) => Schedules.Count(c => c.Start(cancellationToken)); + + public int Restart() => Schedules.Count(c => c.Restart()); + + public async Task Stop() => await Task.WhenAll(Schedules.Select(c => c.Stop())); + + public void Dispose() + { + if (!_disposed) + { + _disposed = true; + _ = Stop(); + } + } + + public async ValueTask DisposeAsync() => await Stop(); +} diff --git a/src/Sa.Schedule/ErrorHandlingAction.cs b/src/Sa.Schedule/ErrorHandlingAction.cs new file mode 100644 index 0000000..cd168a4 --- /dev/null +++ b/src/Sa.Schedule/ErrorHandlingAction.cs @@ -0,0 +1,20 @@ +namespace Sa.Schedule; + +/// +/// Specifies the actions to be taken when an error occurs. +/// +public enum ErrorHandlingAction +{ + /// + /// Closes the entire application. + /// + CloseApplication, + /// + /// Aborts the current job. + /// + AbortJob, + /// + /// Stops all running jobs. + /// + StopAllJobs +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJob.cs b/src/Sa.Schedule/IJob.cs new file mode 100644 index 0000000..b188ac0 --- /dev/null +++ b/src/Sa.Schedule/IJob.cs @@ -0,0 +1,15 @@ +namespace Sa.Schedule; + +/// +/// Represents a job that can be executed. +/// +public interface IJob +{ + /// + /// Executes the job. + /// + /// The job context. + /// The cancellation token. + /// A task representing the execution of the job. + Task Execute(IJobContext context, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobBuilder.cs b/src/Sa.Schedule/IJobBuilder.cs new file mode 100644 index 0000000..396e0ee --- /dev/null +++ b/src/Sa.Schedule/IJobBuilder.cs @@ -0,0 +1,96 @@ +namespace Sa.Schedule; + +/// +/// Defines a builder for creating and configuring jobs. +/// +public interface IJobBuilder +{ + /// + /// Sets the name of the job. + /// + /// The name of the job. + /// The current builder instance. + IJobBuilder WithName(string name); + + /// + /// Starts the job immediately. + /// + /// The current builder instance. + IJobBuilder StartImmediate(); + + /// + /// Configures the job to run once. + /// + /// The current builder instance. + IJobBuilder RunOnce(); + + /// + /// Sets the context stack size for the job. + /// + /// The context stack size. + /// The current builder instance. + IJobBuilder WithContextStackSize(int size); + + /// + /// job schedule delay before start + /// + /// The delay time span. + /// The current builder instance. + IJobBuilder WithInitialDelay(TimeSpan delay); + + /// + /// Sets the timing for the job. + /// + /// The job timing. + /// The current builder instance. + IJobBuilder WithTiming(IJobTiming timing); + + /// + /// Sets a tag for the job. + /// + /// The job tag. + /// The current builder instance. + IJobBuilder WithTag(object tag); + + /// + /// Configures the job to run at the specified time interval. + /// + /// The time interval. + /// The name of the interval (optional). + /// The current builder instance. + IJobBuilder EveryTime(TimeSpan timeSpan, string? name = null); + + /// + /// Configures the job to run every specified number of seconds. + /// + /// The number of seconds (default is 1). + /// The current builder instance. + IJobBuilder EverySeconds(int seconds = 1) => EveryTime(TimeSpan.FromSeconds(seconds), $"every {seconds} seconds"); + + /// + /// Configures the job to run every specified number of minutes. + /// + /// The number of minutes (default is 1). + /// The current builder instance. + IJobBuilder EveryMinutes(int minutes = 1) => EveryTime(TimeSpan.FromMinutes(minutes), $"every {minutes} minutes"); + + /// + /// Merges the specified job properties into the current job configuration. + /// + /// The job properties to merge. + /// The current builder instance. + IJobBuilder Merge(IJobProperties props); + + /// + /// Configures error handling for the job. + /// + /// The error handling configuration action. + /// The current builder instance. + IJobBuilder ConfigureErrorHandling(Action configure); + + /// + /// Disables the job. + /// + /// The current builder instance. + IJobBuilder Disabled(); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobContext.cs b/src/Sa.Schedule/IJobContext.cs new file mode 100644 index 0000000..1fd4346 --- /dev/null +++ b/src/Sa.Schedule/IJobContext.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.Logging; + +namespace Sa.Schedule; + +/// +/// Provides information about the job context. +/// +/// +/// This interface defines the properties and methods that are available for a job context. +/// +/// +/// +public interface IJobContext +{ + + Guid JobId { get; } + string JobName { get; } + JobStatus Status { get; } + IJobSettings Settings { get; } + ulong NumIterations { get; } + ulong FailedIterations { get; } + ulong CompetedIterations { get; } + int FailedRetries { get; } + DateTimeOffset CreatedAt { get; } + DateTimeOffset? ExecuteAt { get; } + JobException? LastError { get; } + IServiceProvider JobServices { get; } + IEnumerable Stack { get; } + ILogger Logger { get; } + + IJobContext Clone(); + bool Active => Status == JobStatus.Running || Status == JobStatus.WaitingToRun; +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobController.cs b/src/Sa.Schedule/IJobController.cs new file mode 100644 index 0000000..9d7ca05 --- /dev/null +++ b/src/Sa.Schedule/IJobController.cs @@ -0,0 +1,29 @@ +namespace Sa.Schedule; + + +public enum CanJobExecuteResult +{ + Ok, + Abort, + Skip +} + +/// +/// Defines the contract for a job controller, responsible for managing the lifecycle of a job. +/// +public interface IJobController +{ + // scope context + public IJobContext Context { get; } + + // scope events + ValueTask WaitToRun(CancellationToken cancellationToken); + void Running(); + void Stopped(TaskStatus status); + + // iteration events + ValueTask CanExecute(CancellationToken cancellationToken); + Task Execute(CancellationToken cancellationToken); + void ExecutionFailed(Exception exception); + void ExecutionCompleted(); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobErrorHandler.cs b/src/Sa.Schedule/IJobErrorHandler.cs new file mode 100644 index 0000000..463b931 --- /dev/null +++ b/src/Sa.Schedule/IJobErrorHandler.cs @@ -0,0 +1,14 @@ +namespace Sa.Schedule; + +/// +/// Defines the contract for handling job errors. +/// +public interface IJobErrorHandler +{ + /// + /// Handles an error that occurred during job execution. + /// + /// The job context. + /// The exception that occurred. + void HandleError(IJobContext context, Exception exception); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobErrorHandling.cs b/src/Sa.Schedule/IJobErrorHandling.cs new file mode 100644 index 0000000..854eca0 --- /dev/null +++ b/src/Sa.Schedule/IJobErrorHandling.cs @@ -0,0 +1,32 @@ +namespace Sa.Schedule; + +/// +/// Defines the error handling behavior for a job. +/// +public interface IJobErrorHandling +{ + /// + /// Gets the action to take after an error occurs. + /// + ErrorHandlingAction ThenAction { get; } + + /// + /// Gets the number of retry attempts. + /// + int RetryCount { get; } + + /// + /// Gets a function that determines whether to suppress an error. + /// + Func? SuppressError { get; } + + /// + /// Gets a value indicating whether an error suppression function is defined. + /// + bool HasSuppressError => SuppressError != null; + + /// + /// Gets a value indicating whether retry attempts are enabled. + /// + bool HasRetryAttempts => RetryCount > 0; +} diff --git a/src/Sa.Schedule/IJobErrorHandlingBuilder.cs b/src/Sa.Schedule/IJobErrorHandlingBuilder.cs new file mode 100644 index 0000000..d1020c4 --- /dev/null +++ b/src/Sa.Schedule/IJobErrorHandlingBuilder.cs @@ -0,0 +1,36 @@ +namespace Sa.Schedule; + +public interface IJobErrorHandlingBuilder +{ + /// + /// Specifies the retry policy for the job in case of an error. + /// + /// The number of times to retry the job. If null, the job will not be retried. + /// The current IJobErrorHandlingBuilder instance. + IJobErrorHandlingBuilder IfErrorRetry(int? count = null); + + /// + /// Specifies that the application should be closed if an error occurs. + /// + /// The current IJobErrorHandlingBuilder instance. + IJobErrorHandlingBuilder ThenCloseApplication(); + + /// + /// Specifies that all jobs should be stopped if an error occurs. + /// + /// The current IJobErrorHandlingBuilder instance. + IJobErrorHandlingBuilder ThenStopAllJobs(); + + /// + /// Specifies that the current job should be stopped if an error occurs. + /// + /// The current IJobErrorHandlingBuilder instance. + IJobErrorHandlingBuilder ThenStopJob(); + + /// + /// Specifies a custom error suppression policy. + /// + /// A function that determines whether an error should be suppressed. + /// The current IJobErrorHandlingBuilder instance. + IJobErrorHandlingBuilder DoSuppressError(Func? suppressError = null); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobFactory.cs b/src/Sa.Schedule/IJobFactory.cs new file mode 100644 index 0000000..057641f --- /dev/null +++ b/src/Sa.Schedule/IJobFactory.cs @@ -0,0 +1,7 @@ +namespace Sa.Schedule; + +public interface IJobFactory +{ + IJobController CreateJobController(IJobSettings settings); + IJobScheduler CreateJobSchedule(IJobSettings settings); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobInterceptor.cs b/src/Sa.Schedule/IJobInterceptor.cs new file mode 100644 index 0000000..3cddffd --- /dev/null +++ b/src/Sa.Schedule/IJobInterceptor.cs @@ -0,0 +1,17 @@ +namespace Sa.Schedule; + +/// +/// Defines an interface for job interceptors, allowing for custom logic to be executed before or after a job is handled. +/// +public interface IJobInterceptor +{ + /// + /// Called when a job is being handled, allowing the interceptor to perform custom logic before or after the job is executed. + /// + /// The context of the job being handled. + /// A function that represents the next step in the job handling pipeline. + /// An optional key associated with the job. + /// A token that can be used to cancel the job handling operation. + /// A task that represents the result of the job handling operation. + Task OnHandle(IJobContext context, Func next, object? key, CancellationToken cancellationToken); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobProperties.cs b/src/Sa.Schedule/IJobProperties.cs new file mode 100644 index 0000000..47cdbce --- /dev/null +++ b/src/Sa.Schedule/IJobProperties.cs @@ -0,0 +1,47 @@ +namespace Sa.Schedule; + +/// +/// Represents the properties of a job. +/// +public interface IJobProperties +{ + /// + /// Gets the name of the job. + /// + string? JobName { get; } + + /// + /// Gets a value indicating whether the job should be executed immediately. + /// + bool? Immediate { get; } + + /// + /// Gets a value indicating whether the job should run only once. + /// + bool? IsRunOnce { get; } + + /// + /// Gets a value indicating whether the job is disabled. + /// + bool? Disabled { get; } + + /// + /// Gets the delay before the job starts. + /// + TimeSpan? InitialDelay { get; } + + /// + /// Gets the timing configuration for the job. + /// + IJobTiming? Timing { get; } + + /// + /// Gets the size of the context stack for the job. + /// + int? ContextStackSize { get; } + + /// + /// Gets an optional tag associated with the job. + /// + object? Tag { get; } +} diff --git a/src/Sa.Schedule/IJobRunner.cs b/src/Sa.Schedule/IJobRunner.cs new file mode 100644 index 0000000..788ee28 --- /dev/null +++ b/src/Sa.Schedule/IJobRunner.cs @@ -0,0 +1,6 @@ +namespace Sa.Schedule; + +public interface IJobRunner +{ + Task Run(IJobController controller, CancellationToken cancellationToken); +} diff --git a/src/Sa.Schedule/IJobScheduler.cs b/src/Sa.Schedule/IJobScheduler.cs new file mode 100644 index 0000000..c917c2f --- /dev/null +++ b/src/Sa.Schedule/IJobScheduler.cs @@ -0,0 +1,41 @@ +using Microsoft.Extensions.Primitives; + +namespace Sa.Schedule; + + +/// +/// This individual task scheduler is responsible for managing specific tasks. +/// +public interface IJobScheduler +{ + /// + /// Gets a value indicating whether the job scheduler is currently active. + /// + bool IsActive { get; } + + /// + /// Gets the context associated with the job scheduler. + /// + IJobContext Context { get; } + + /// + /// Gets a change token that can be used to track changes to the active state of the scheduler. + /// + IChangeToken GetActiveChangeToken(); + + /// + /// Starts the job scheduler asynchronously. + /// + bool Start(CancellationToken cancellationToken); + + /// + /// Restarts the job scheduler asynchronously. + /// + bool Restart(); + + /// + /// Stops the job scheduler asynchronously. + /// + Task Stop(); +} + diff --git a/src/Sa.Schedule/IJobSettings.cs b/src/Sa.Schedule/IJobSettings.cs new file mode 100644 index 0000000..a98427f --- /dev/null +++ b/src/Sa.Schedule/IJobSettings.cs @@ -0,0 +1,24 @@ +namespace Sa.Schedule; + +/// +/// Defines the settings for a job. +/// +public interface IJobSettings +{ + /// + /// Gets the unique identifier of the job. + /// + Guid JobId { get; } + /// + /// Gets the type of the job. + /// + Type JobType { get; } + /// + /// Gets the properties of the job. + /// + IJobProperties Properties { get; } + /// + /// Gets the error handling settings for the job. + /// + IJobErrorHandling ErrorHandling { get; } +} \ No newline at end of file diff --git a/src/Sa.Schedule/IJobTiming.cs b/src/Sa.Schedule/IJobTiming.cs new file mode 100644 index 0000000..54e3056 --- /dev/null +++ b/src/Sa.Schedule/IJobTiming.cs @@ -0,0 +1,20 @@ +namespace Sa.Schedule; + +/// +/// Represents a job timing interface. +/// +public interface IJobTiming +{ + /// + /// Gets the name of the timing. + /// + string TimingName { get; } + + /// + /// Gets the next occurrence of the job timing. + /// + /// The current date and time. + /// The job context. + /// The next occurrence of the job timing, or null if no next occurrence is found. + DateTimeOffset? GetNextOccurrence(DateTimeOffset dateTime, IJobContext context); +} \ No newline at end of file diff --git a/src/Sa.Schedule/IScheduleBuilder.cs b/src/Sa.Schedule/IScheduleBuilder.cs new file mode 100644 index 0000000..936ddb6 --- /dev/null +++ b/src/Sa.Schedule/IScheduleBuilder.cs @@ -0,0 +1,50 @@ +namespace Sa.Schedule; + +public interface IScheduleBuilder +{ + /// + /// Adds a job of type to the schedule. + /// + /// The type of job to add. + /// The ID of the job. If not specified, a new ID will be generated. + /// A builder for the added job. + IJobBuilder AddJob(Guid? jobId = null) where T : class, IJob; + + /// + /// Adds a job with the specified action to the schedule. + /// + /// The action to execute when the job is run. + /// The ID of the job. If not specified, a new ID will be generated. + /// A builder for the added job. + IJobBuilder AddJob(Func action, Guid? jobId = null); + + /// + /// Adds a job of type to the schedule and configures it using the specified action. + /// + /// The type of job to add. + /// An action to configure the job. + /// The ID of the job. If not specified, a new ID will be generated. + /// The schedule builder. + IScheduleBuilder AddJob(Action configure, Guid? jobId = null) where T : class, IJob; + + /// + /// Adds an interceptor of type to the schedule. + /// + /// The type of interceptor to add. + /// The key to use for the interceptor. If not specified, a default key will be used. + /// The schedule builder. + IScheduleBuilder AddInterceptor(object? key = null) where T : class, IJobInterceptor; + + /// + /// Configures the schedule to use a hosted service. + /// + /// The schedule builder. + IScheduleBuilder UseHostedService(); + + /// + /// Adds an error handler to the schedule. + /// + /// A function to handle errors that occur during job execution. + /// The schedule builder. + IScheduleBuilder AddErrorHandler(Func handler); +} diff --git a/src/Sa.Schedule/IScheduleSettings.cs b/src/Sa.Schedule/IScheduleSettings.cs new file mode 100644 index 0000000..6accf9a --- /dev/null +++ b/src/Sa.Schedule/IScheduleSettings.cs @@ -0,0 +1,22 @@ +namespace Sa.Schedule; + +/// +/// Defines the settings for a schedule. +/// +public interface IScheduleSettings +{ + /// + /// Gets a value indicating whether the schedule is hosted as a service. + /// + bool IsHostedService { get; } + + /// + /// Gets a function that handles errors that occur during job execution. + /// + Func? HandleError { get; } + + /// + /// Gets a collection of job settings. + /// + IEnumerable GetJobSettings(); +} diff --git a/src/Sa.Schedule/IScheduler.cs b/src/Sa.Schedule/IScheduler.cs new file mode 100644 index 0000000..5a24d13 --- /dev/null +++ b/src/Sa.Schedule/IScheduler.cs @@ -0,0 +1,36 @@ +namespace Sa.Schedule; + +/// +/// This scheduler that manages multiple job schedulers. +/// +public interface IScheduler +{ + /// + /// Gets the schedule settings. + /// + IScheduleSettings Settings { get; } + + /// + /// Gets the collection of job schedulers. + /// + IReadOnlyCollection Schedules { get; } + + /// + /// Starts the scheduler. + /// + /// The cancellation token. + /// The number of jobs started. + int Start(CancellationToken cancellationToken); + + /// + /// Restarts the scheduler. + /// + /// The number of jobs restarted. + int Restart(); + + /// + /// Stops the scheduler. + /// + /// A task representing the asynchronous operation. + Task Stop(); +} \ No newline at end of file diff --git a/src/Sa.Schedule/JobException.cs b/src/Sa.Schedule/JobException.cs new file mode 100644 index 0000000..eac6df3 --- /dev/null +++ b/src/Sa.Schedule/JobException.cs @@ -0,0 +1,7 @@ +namespace Sa.Schedule; + +public class JobException(IJobContext context, Exception? innerException) + : Exception($"[{context.JobName}] job error", innerException) +{ + public IJobContext JobContext { get; } = context.Clone(); +} diff --git a/src/Sa.Schedule/JobInterceptorSettings.cs b/src/Sa.Schedule/JobInterceptorSettings.cs new file mode 100644 index 0000000..60a03a9 --- /dev/null +++ b/src/Sa.Schedule/JobInterceptorSettings.cs @@ -0,0 +1,3 @@ +namespace Sa.Schedule; + +public record JobInterceptorSettings(Type HandlerType, object? Key = null); diff --git a/src/Sa.Schedule/JobStatus.cs b/src/Sa.Schedule/JobStatus.cs new file mode 100644 index 0000000..bb67c90 --- /dev/null +++ b/src/Sa.Schedule/JobStatus.cs @@ -0,0 +1,10 @@ +namespace Sa.Schedule; + +public enum JobStatus +{ + WaitingToRun = 2, + Running = 3, + Completed = 5, + Cancelled = 6, + Failed = 7 +} diff --git a/src/Sa.Schedule/Readme.md b/src/Sa.Schedule/Readme.md new file mode 100644 index 0000000..cadb6ad --- /dev/null +++ b/src/Sa.Schedule/Readme.md @@ -0,0 +1,113 @@ +# Sa.Schedule + +Библиотека Sa.Schedule предоставляет способ настройки и выполнения задач по расписанию. Позволяет управлять набором задач, которые будут выполняться в определенное время или по определенной периодичности. + + +## Пример использования + +### Конфигурирование расписания + +```csharp +Services.AddSchedule(b => +{ + b.AddJob((sp, builder) => + { + builder + .EveryTime(TimeSpan.FromMilliseconds(100)) + .RunOnce() + .StartImmediate(); + }); +}); +``` + +### Задание (Job) + +Задание реализует интерфейс IJob и метод Execute, который выполняет основную логику + +```csharp +class SomeJob : IJob +{ + // IJobContext предоставляет доступ к контексту выполнения + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + await Task.Delay(10, cancellationToken); // Имитация работы + } +} +``` + + +## Управление расписаниями + +Осуществлеятся посредством интерфейсов IScheduler и IJobScheduler. + +```csharp +/// +/// This scheduler that manages multiple job schedulers. +/// +public interface IScheduler +{ + /// + /// Gets the schedule settings. + /// + IScheduleSettings Settings { get; } + + /// + /// Gets the collection of job schedulers. + /// + IReadOnlyCollection Schedules { get; } + + /// + /// Starts the scheduler. + /// + /// The cancellation token. + /// The number of jobs started. + int Start(CancellationToken cancellationToken); + + /// + /// Restarts the scheduler. + /// + int Restart(); + + /// + /// Stops the scheduler. + /// + Task Stop(); +} + +/// +/// This individual task scheduler is responsible for managing specific tasks. +/// +public interface IJobScheduler +{ + /// + /// Gets a value indicating whether the job scheduler is currently active. + /// + bool IsActive { get; } + + /// + /// Gets the context associated with the job scheduler. + /// + IJobContext Context { get; } + + /// + /// Gets a change token that can be used to track changes to the active state of the scheduler. + /// + IChangeToken GetActiveChangeToken(); + + /// + /// Starts the job scheduler asynchronously. + /// + bool Start(CancellationToken cancellationToken); + + /// + /// Restarts the job scheduler. + /// + bool Restart(); + + /// + /// Stops the job scheduler. + /// + Task Stop(); +} + +``` \ No newline at end of file diff --git a/src/Sa.Schedule/Sa.Schedule.csproj b/src/Sa.Schedule/Sa.Schedule.csproj new file mode 100644 index 0000000..c9a9dd6 --- /dev/null +++ b/src/Sa.Schedule/Sa.Schedule.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.Schedule/Settings/IInterceptorSettings.cs b/src/Sa.Schedule/Settings/IInterceptorSettings.cs new file mode 100644 index 0000000..3561ec5 --- /dev/null +++ b/src/Sa.Schedule/Settings/IInterceptorSettings.cs @@ -0,0 +1,7 @@ + +namespace Sa.Schedule.Settings; + +internal interface IInterceptorSettings +{ + IReadOnlyCollection Interceptors { get; } +} \ No newline at end of file diff --git a/src/Sa.Schedule/Settings/InterceptorSettings.cs b/src/Sa.Schedule/Settings/InterceptorSettings.cs new file mode 100644 index 0000000..c014dc8 --- /dev/null +++ b/src/Sa.Schedule/Settings/InterceptorSettings.cs @@ -0,0 +1,19 @@ +namespace Sa.Schedule.Settings; + +internal class InterceptorSettings : IInterceptorSettings +{ + private readonly List _interceptors = []; + + public IReadOnlyCollection Interceptors => _interceptors; + + public InterceptorSettings(IEnumerable items) + { + foreach (JobInterceptorSettings item in items) + { + if (!_interceptors.Contains(item)) + { + _interceptors.Add(item); + } + } + } +} diff --git a/src/Sa.Schedule/Settings/Job.cs b/src/Sa.Schedule/Settings/Job.cs new file mode 100644 index 0000000..5d0da4b --- /dev/null +++ b/src/Sa.Schedule/Settings/Job.cs @@ -0,0 +1,7 @@ +namespace Sa.Schedule.Settings; + +internal class Job(Func action) : IJob +{ + public Task Execute(IJobContext context, CancellationToken cancellationToken) + => action(context, cancellationToken); +} diff --git a/src/Sa.Schedule/Settings/JobBuilder.cs b/src/Sa.Schedule/Settings/JobBuilder.cs new file mode 100644 index 0000000..10e6f14 --- /dev/null +++ b/src/Sa.Schedule/Settings/JobBuilder.cs @@ -0,0 +1,71 @@ +namespace Sa.Schedule.Settings; + + +internal class JobBuilder(JobSettings settings) : IJobBuilder +{ + public IJobBuilder ConfigureErrorHandling(Action configure) + { + configure.Invoke(settings.ErrorHandling); + return this; + } + + public IJobBuilder EveryTime(TimeSpan timeSpan, string? name = null) + { + settings.Properties.EveryTime(timeSpan, name); + return this; + } + + public IJobBuilder Merge(IJobProperties props) + { + settings.Properties.Merge(props); + return this; + } + + public IJobBuilder RunOnce() + { + settings.Properties.RunOnce(); + return this; + } + + public IJobBuilder StartImmediate() + { + settings.Properties.StartImmediate(); + return this; + } + + public IJobBuilder WithInitialDelay(TimeSpan delay) + { + settings.Properties.WithInitialDelay(delay); + return this; + } + + public IJobBuilder WithName(string name) + { + settings.Properties.WithName(name); + return this; + } + + public IJobBuilder WithTag(object tag) + { + settings.Properties.WithTag(tag); + return this; + } + + public IJobBuilder WithTiming(IJobTiming timing) + { + settings.Properties.WithTiming(timing); + return this; + } + + public IJobBuilder WithContextStackSize(int size) + { + settings.Properties.WithContextStackSize(size); + return this; + } + + public IJobBuilder Disabled() + { + settings.Properties.SetDisabled(); + return this; + } +} diff --git a/src/Sa.Schedule/Settings/JobErrorHandling.cs b/src/Sa.Schedule/Settings/JobErrorHandling.cs new file mode 100644 index 0000000..5da6748 --- /dev/null +++ b/src/Sa.Schedule/Settings/JobErrorHandling.cs @@ -0,0 +1,60 @@ +using Sa.Extensions; + +namespace Sa.Schedule.Settings; + +internal class JobErrorHandling : IJobErrorHandling, IJobErrorHandlingBuilder +{ + public static class Default + { + public const ErrorHandlingAction Action = ErrorHandlingAction.CloseApplication; + public const int RetryCount = 2; + public readonly static Func SuppressError = ex => !ex.IsCritical(); + } + + public ErrorHandlingAction ThenAction { get; private set; } = Default.Action; + + public int RetryCount { get; private set; } + + public Func? SuppressError { get; private set; } + + internal JobErrorHandling Merge(IJobErrorHandling handling) + { + if (handling.ThenAction != Default.Action) { ThenAction = handling.ThenAction; } + if (handling.HasRetryAttempts) { RetryCount = handling.RetryCount; } + if (handling.HasSuppressError) { SuppressError = handling.SuppressError; } + return this; + } + + + public IJobErrorHandlingBuilder IfErrorRetry(int? count = null) + { + RetryCount = count ?? Default.RetryCount; + return this; + } + + public IJobErrorHandlingBuilder ThenCloseApplication() + { + ThenAction = ErrorHandlingAction.CloseApplication; + return this; + } + + public IJobErrorHandlingBuilder ThenStopJob() + { + ThenAction = ErrorHandlingAction.AbortJob; + return this; + } + + public IJobErrorHandlingBuilder ThenStopAllJobs() + { + ThenAction = ErrorHandlingAction.StopAllJobs; + return this; + } + + + public IJobErrorHandlingBuilder DoSuppressError(Func? suppressError = null) + { + SuppressError = suppressError ?? Default.SuppressError; + return this; + } + +} diff --git a/src/Sa.Schedule/Settings/JobProperies.cs b/src/Sa.Schedule/Settings/JobProperies.cs new file mode 100644 index 0000000..ea40607 --- /dev/null +++ b/src/Sa.Schedule/Settings/JobProperies.cs @@ -0,0 +1,40 @@ +using Sa.Schedule.Engine; + +namespace Sa.Schedule.Settings; + +internal class JobProperies : IJobProperties +{ + public string? JobName { get; private set; } + public bool? Immediate { get; private set; } + public bool? IsRunOnce { get; private set; } + public TimeSpan? InitialDelay { get; private set; } + public bool? Disabled { get; private set; } + public IJobTiming? Timing { get; private set; } + public object? Tag { get; private set; } + public int? ContextStackSize { get; private set; } + + public void WithName(string name) => JobName = name; + public void RunOnce() => IsRunOnce = true; + public void StartImmediate() => Immediate = true; + public void WithInitialDelay(TimeSpan time) => InitialDelay = time; + public void WithTiming(IJobTiming timing) => Timing = timing; + public void SetDisabled() => Disabled = true; + public void WithContextStackSize(int size) => ContextStackSize = size; + public void WithTag(object tag) => Tag = tag; + + public void EveryTime(TimeSpan timeSpan, string? name = null) + => Timing = JobTiming.EveryTime(timeSpan, name); + + internal JobProperies Merge(IJobProperties props) + { + JobName ??= props.JobName; + Immediate ??= props.Immediate; + Disabled ??= props.Disabled; + Timing ??= props.Timing; + IsRunOnce ??= props.IsRunOnce; + InitialDelay ??= props.InitialDelay; + ContextStackSize ??= props.ContextStackSize; + Tag ??= props.Tag; + return this; + } +} diff --git a/src/Sa.Schedule/Settings/JobSettings.cs b/src/Sa.Schedule/Settings/JobSettings.cs new file mode 100644 index 0000000..3bd4cdf --- /dev/null +++ b/src/Sa.Schedule/Settings/JobSettings.cs @@ -0,0 +1,33 @@ + +namespace Sa.Schedule.Settings; + +internal class JobSettings(Type jobType, Guid jobId) : IJobSettings +{ + /// + /// handler id + /// + public Guid JobId { get; } = jobId; + public Type JobType => jobType; + + public JobProperies Properties { get; } = new(); + public JobErrorHandling ErrorHandling { get; } = new(); + + IJobProperties IJobSettings.Properties => Properties; + IJobErrorHandling IJobSettings.ErrorHandling => ErrorHandling; + + internal JobSettings Merge(IJobSettings info) + { + Properties.Merge(info.Properties); + ErrorHandling.Merge(info.ErrorHandling); + return this; + } + + + public static JobSettings Create(Guid jobId) + where T : class, IJob => new(typeof(T), jobId); + + public static JobSettings Create(IJobSettings options) + => new JobSettings(options.JobType, options.JobId).Merge(options); + + public IJobSettings Clone() => new JobSettings(JobType, JobId).Merge(this); +} diff --git a/src/Sa.Schedule/Settings/NullJobServices.cs b/src/Sa.Schedule/Settings/NullJobServices.cs new file mode 100644 index 0000000..9a77618 --- /dev/null +++ b/src/Sa.Schedule/Settings/NullJobServices.cs @@ -0,0 +1,8 @@ +namespace Sa.Schedule.Settings; + +internal class NullJobServices : IServiceProvider +{ + public object? GetService(Type serviceType) => null; + + public static IServiceProvider Instance { get; } = new NullJobServices(); +} diff --git a/src/Sa.Schedule/Settings/ScheduleBuilder.cs b/src/Sa.Schedule/Settings/ScheduleBuilder.cs new file mode 100644 index 0000000..d51b877 --- /dev/null +++ b/src/Sa.Schedule/Settings/ScheduleBuilder.cs @@ -0,0 +1,96 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Schedule.Engine; + +namespace Sa.Schedule.Settings; + +internal class ScheduleBuilder : IScheduleBuilder +{ + private readonly IServiceCollection _services; + + private bool _isHostedService; + + private Func? _handleError; + + public ScheduleBuilder(IServiceCollection services) + { + _services = services; + + _services.TryAddSingleton(sp => + { + IEnumerable jobSettings = sp.GetServices(); + ScheduleSettings settings = ScheduleSettings.Create(jobSettings, _isHostedService, _handleError); + return settings; + }); + + _services.TryAddSingleton(sp => + { + IEnumerable jobSettings = sp.GetServices(); + return new InterceptorSettings(jobSettings); + }); + } + + public IJobBuilder AddJob(Guid? jobId = null) + where T : class, IJob + { + Guid id = GetId(jobId); + _services.TryAddKeyedScoped(id); + + JobSettings jobSettings = JobSettings.Create(id); + _services.AddSingleton(jobSettings); + + return new JobBuilder(jobSettings); + } + + public IScheduleBuilder AddJob(Action configure, Guid? jobId = null) + where T : class, IJob + { + Guid id = GetId(jobId); + _services.TryAddKeyedScoped(id); + + _services.AddSingleton(sp => + { + JobSettings jobSettings = JobSettings.Create(id); + configure.Invoke(sp, new JobBuilder(jobSettings)); + return jobSettings; + }); + + return this; + } + + public IJobBuilder AddJob(Func action, Guid? jobId = null) + { + Guid id = GetId(jobId); + _services + .RemoveAllKeyed(jobId) + .AddKeyedScoped(id, (_, __) => new Job(action)); + + JobSettings jobSettings = JobSettings.Create(id); + _services.AddSingleton(jobSettings); + + return new JobBuilder(jobSettings); + } + + public IScheduleBuilder AddErrorHandler(Func handler) + { + _handleError = handler; + return this; + } + + private static Guid GetId(Guid? jobId) => jobId.GetValueOrDefault(Guid.NewGuid()); + + public IScheduleBuilder UseHostedService() + { + _isHostedService = true; + _services.AddHostedService(); + return this; + } + + public IScheduleBuilder AddInterceptor(object? key = null) + where T : class, IJobInterceptor + { + _services.AddSingleton(new JobInterceptorSettings(typeof(T), key)); + _services.TryAddKeyedScoped(typeof(T), key); + return this; + } +} diff --git a/src/Sa.Schedule/Settings/ScheduleSettings.cs b/src/Sa.Schedule/Settings/ScheduleSettings.cs new file mode 100644 index 0000000..fbfc7df --- /dev/null +++ b/src/Sa.Schedule/Settings/ScheduleSettings.cs @@ -0,0 +1,29 @@ +namespace Sa.Schedule.Settings; + +internal class ScheduleSettings : IScheduleSettings +{ + private Dictionary _storage = []; + + public bool IsHostedService { get; private set; } + + public Func? HandleError { get; private set; } + + public virtual IEnumerable GetJobSettings() => _storage.Values.Where(c => c.Properties.Disabled != true); + + public void UseHostedService() => IsHostedService = true; + + internal static ScheduleSettings Create(IEnumerable jobSettings, bool isHostedService, Func? handleError) + { + IEnumerable items = jobSettings.GroupBy( + c => (c.JobId, c.JobType) + , (k, items) => items.Aggregate(seed: new JobSettings(k.JobType, k.JobId), (s1, s2) => s1.Merge(s2)) + ); + + return new ScheduleSettings + { + HandleError = handleError, + IsHostedService = isHostedService, + _storage = items.ToDictionary(c => c.JobId) + }; + } +} diff --git a/src/Sa.Schedule/Setup.cs b/src/Sa.Schedule/Setup.cs new file mode 100644 index 0000000..5d49641 --- /dev/null +++ b/src/Sa.Schedule/Setup.cs @@ -0,0 +1,31 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Sa.Schedule.Engine; +using Sa.Schedule.Settings; +using Sa.Timing.Providers; + +namespace Sa.Schedule; + +/// +/// Provides extension methods for setting up the scheduling system. +/// +public static class Setup +{ + /// + /// Adds the scheduling system to the service collection. + /// + /// The service collection to add the scheduling system to. + /// An action to configure the scheduling system. + /// The service collection with the scheduling system added. + public static IServiceCollection AddSchedule(this IServiceCollection services, Action configure) + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + + configure.Invoke(new ScheduleBuilder(services)); + return services; + } +} \ No newline at end of file diff --git a/src/Sa.StateMachine/ISettingsBuilder.cs b/src/Sa.StateMachine/ISettingsBuilder.cs new file mode 100644 index 0000000..f8ebe4f --- /dev/null +++ b/src/Sa.StateMachine/ISettingsBuilder.cs @@ -0,0 +1,8 @@ +namespace Sa.StateMachine; + +public interface ISettingsBuilder where TState : SmState +{ + ISettingsBuilder Add(ITransition transition); + ISettingsBuilder Add(TState start, TState[] ends, object? tag = null); + ISettingsBuilder Add(TState start, Func ends, object? tag = null) => Add(start, ends(), tag); +} diff --git a/src/Sa.StateMachine/ISmContext.cs b/src/Sa.StateMachine/ISmContext.cs new file mode 100644 index 0000000..340a5ba --- /dev/null +++ b/src/Sa.StateMachine/ISmContext.cs @@ -0,0 +1,9 @@ +namespace Sa.StateMachine; + +public interface ISmContext where TState : IComparable +{ + TState CurrentState { get; } + Exception? Error { get; } + IReadOnlyCollection NextStates { get; } + CancellationToken CancellationToken { get; } +} diff --git a/src/Sa.StateMachine/ISmProcessor.cs b/src/Sa.StateMachine/ISmProcessor.cs new file mode 100644 index 0000000..ff42591 --- /dev/null +++ b/src/Sa.StateMachine/ISmProcessor.cs @@ -0,0 +1,7 @@ +namespace Sa.StateMachine; + +public interface ISmProcessor where TState : IComparable +{ + ValueTask MoveNext(ISmContext context); + ValueTask Finished(ISmContext context); +} diff --git a/src/Sa.StateMachine/ISmSettings.cs b/src/Sa.StateMachine/ISmSettings.cs new file mode 100644 index 0000000..cbfe450 --- /dev/null +++ b/src/Sa.StateMachine/ISmSettings.cs @@ -0,0 +1,9 @@ +namespace Sa.StateMachine; + +public interface ISmSettings where TState : IComparable +{ + TState StartState { get; } + TState ErrorState { get; } + ITransitionGraph Graph { get; } + IReadOnlyDictionary> Transitions { get; } +} diff --git a/src/Sa.StateMachine/ITransition.cs b/src/Sa.StateMachine/ITransition.cs new file mode 100644 index 0000000..224ad7d --- /dev/null +++ b/src/Sa.StateMachine/ITransition.cs @@ -0,0 +1,8 @@ +namespace Sa.StateMachine; + +public interface ITransition where TState : IComparable +{ + TState Start { get; } + TState[] End { get; } + object? Tag { get; } +} diff --git a/src/Sa.StateMachine/ITransitionGraph.cs b/src/Sa.StateMachine/ITransitionGraph.cs new file mode 100644 index 0000000..705c489 --- /dev/null +++ b/src/Sa.StateMachine/ITransitionGraph.cs @@ -0,0 +1,17 @@ +namespace Sa.StateMachine; + +public interface ITransitionGraph where TNode : IComparable +{ + IReadOnlyCollection this[TNode start] { get; } + + IReadOnlyCollection Starts { get; } + IReadOnlyCollection Ends { get; } + + IReadOnlyCollection Roots { get; } + IReadOnlyCollection Leaves { get; } + + IReadOnlyCollection Nodes { get; } + + bool IsRootNode(TNode node); + bool IsLeafNode(TNode node); +} diff --git a/src/Sa.StateMachine/Internal/SettingsBulder.cs b/src/Sa.StateMachine/Internal/SettingsBulder.cs new file mode 100644 index 0000000..f9e6e03 --- /dev/null +++ b/src/Sa.StateMachine/Internal/SettingsBulder.cs @@ -0,0 +1,55 @@ +namespace Sa.StateMachine.Internal; + + +class SettingsBulder() : ISettingsBuilder where TState : SmState +{ + #region ITransition + protected class Transition(TState start, TState[] end, object? tag = null) : ITransition + { + public TState Start => start; + public TState[] End => end; + public object? Tag => tag; + } + #endregion + + private readonly Dictionary> _transitions = []; + + public ISettingsBuilder Add(ITransition transition) + { + _transitions[transition.Start] = transition; + return this; + } + + public ISettingsBuilder Add(TState start, TState[] ends, object? tag = null) + => Add(new Transition(start, ends, tag)); + + private TransitionGraph BuildGraph() + => new(_transitions.Values.SelectMany(c => c.End.Select(end => (c.Start, end)))); + + public SmSettings Build() + { + TransitionGraph graph = BuildGraph(); + + bool reload = false; + // bind transition from start + foreach (var cRoot in graph.Roots.Where(c => c.Kind != StateKind.Start)) + { + reload = true; + Add(SmState.Start, [cRoot]); + } + + TState endState = graph.Leaves.FirstOrDefault(c => c.Kind == StateKind.Finish) ?? SmState.Finish; + + // bind transition to end + IEnumerable noEnds = graph.Leaves.Where(c => c.Kind != StateKind.Finish); + foreach (TState enode in noEnds) + { + Add(enode, [endState]); + reload = true; + } + + if (reload) graph = BuildGraph(); + + return new(SmState.Start, SmState.Error, _transitions, graph); + } +} diff --git a/src/Sa.StateMachine/Internal/SmSettings.cs b/src/Sa.StateMachine/Internal/SmSettings.cs new file mode 100644 index 0000000..99f57f2 --- /dev/null +++ b/src/Sa.StateMachine/Internal/SmSettings.cs @@ -0,0 +1,8 @@ +namespace Sa.StateMachine.Internal; + +record SmSettings( + TState StartState, + TState ErrorState, + IReadOnlyDictionary> Transitions, + ITransitionGraph Graph +) : ISmSettings where TState : IComparable; diff --git a/src/Sa.StateMachine/Internal/TransitionGraph.cs b/src/Sa.StateMachine/Internal/TransitionGraph.cs new file mode 100644 index 0000000..022883d --- /dev/null +++ b/src/Sa.StateMachine/Internal/TransitionGraph.cs @@ -0,0 +1,78 @@ +using Sa.Classes; + +namespace Sa.StateMachine.Internal; + +public class TransitionGraph : ITransitionGraph + where TNode : IComparable +{ + private readonly Dictionary<(TNode start, TNode end), object?> _transitions; + + private readonly ResetLazy _starts; + private readonly ResetLazy _ends; + + private readonly ResetLazy _nodes; + private readonly ResetLazy _leaves; + + private readonly ResetLazy _roots; + + private readonly ResetLazy> _nexts; + + + public TransitionGraph(IEnumerable<(TNode start, TNode end)> transitions) + { + _transitions = new(transitions.Select(t => KeyValuePair.Create((t.start, t.end), default(object)))); + + _starts = new(() => _transitions.Keys.Select(t => t.start).Distinct().ToArray()); + _ends = new(() => _transitions.Keys.Select(t => t.end).Distinct().ToArray()); + _nodes = new(() => _starts.Value.Concat(_ends.Value).Distinct().ToArray()); + _leaves = new(() => _ends.Value.Except(_starts.Value).Distinct().ToArray()); + + _roots = new(() => _starts.Value + .Except(_transitions.Keys + .Where(c => !IsSelfLoop(c)) + .Select(c => c.end)) + .ToArray()); + + _nexts = new(() => _transitions.GroupBy( + t => t.Key.start, + (start, items) => KeyValuePair.Create(start, items.Select(c => c.Key.end).ToArray())) + .ToDictionary()); + } + + public IReadOnlyCollection this[TNode start] => _nexts.Value.GetValueOrDefault(start) ?? []; + + public IReadOnlyCollection Roots => _roots.Value; + public IReadOnlyCollection Ends => _ends.Value; + public IReadOnlyCollection Leaves => _leaves.Value; + public IReadOnlyCollection Nodes => _nodes.Value; + public IReadOnlyCollection Starts => _starts.Value; + + + public TransitionGraph Add(TNode start, TNode[] ends, object? state = null) + { + Reset(); + foreach ((TNode start, TNode end) transit in ends.Select(end => (start, end))) + { + _transitions[transit] = state; + } + return this; + } + + protected void Reset() + { + _starts.Reset(); + _ends.Reset(); + _roots.Reset(); + _nodes.Reset(); + _leaves.Reset(); + _nexts.Reset(); + } + + public static bool IsSelfLoop((TNode start, TNode end) node) => IsEquals(node.start, node.end); + + public static bool IsEquals(TNode start, TNode end) => start.CompareTo(end) == 0; + + + public bool IsRootNode(TNode node) => Roots.Any(c => c.CompareTo(node) == 0); + public bool IsLeafNode(TNode node) => Leaves.Any(c => c.CompareTo(node) == 0); +} diff --git a/src/Sa.StateMachine/Sa.StateMachine.csproj b/src/Sa.StateMachine/Sa.StateMachine.csproj new file mode 100644 index 0000000..c9a9dd6 --- /dev/null +++ b/src/Sa.StateMachine/Sa.StateMachine.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/src/Sa.StateMachine/SmEnumerable.cs b/src/Sa.StateMachine/SmEnumerable.cs new file mode 100644 index 0000000..b9107b7 --- /dev/null +++ b/src/Sa.StateMachine/SmEnumerable.cs @@ -0,0 +1,77 @@ +namespace Sa.StateMachine; + + +public abstract class SmEnumerable(ISmSettings settings) : IAsyncEnumerable> + where TState : SmState +{ + + sealed class SmEnumerator(ISmSettings settings, ISmProcessor processor, CancellationToken cancellationToken) + : IAsyncEnumerator>, ISmContext + { + public TState CurrentState { get; private set; } = settings.StartState; + public Exception? Error { get; private set; } + public IReadOnlyCollection NextStates { get; private set; } = []; + public CancellationToken CancellationToken => cancellationToken; + + ISmContext IAsyncEnumerator>.Current => this; + + public override string ToString() => $"{CurrentState}"; + + async ValueTask IAsyncEnumerator>.MoveNextAsync() + { + if (cancellationToken.IsCancellationRequested) return false; + + try + { + NextStates = settings.Graph[CurrentState]; + + TState nextState = await processor.MoveNext(this); + + if (!NextStates.Contains(nextState)) + throw new ArgumentException($"Expected {NextStates} but found {nextState}"); + + if (nextState.Kind == StateKind.Finish || settings.Graph.IsLeafNode(nextState)) + { + await processor.Finished(this); + return false; + } + + CurrentState = nextState; + return true; + } + catch (Exception error) + { + Error = error; + CurrentState = settings.ErrorState; + } + + return true; + } + + ValueTask IAsyncDisposable.DisposeAsync() => ValueTask.CompletedTask; + } + + protected abstract ISmProcessor CreateProcessor(); + + public virtual IAsyncEnumerator> GetAsyncEnumerator(CancellationToken cancellationToken = default) + => new SmEnumerator(settings, CreateProcessor(), cancellationToken); + + + public async virtual ValueTask<(TState state, Exception? error)> Run(CancellationToken cancellationToken = default) + { + var inumerator = GetAsyncEnumerator(cancellationToken); + try + { + while (await inumerator.MoveNextAsync()) + { + // not used + } + + return (inumerator.Current.CurrentState, inumerator.Current.Error); + } + finally + { + await inumerator.DisposeAsync(); + } + } +} diff --git a/src/Sa.StateMachine/SmLongProcess.cs b/src/Sa.StateMachine/SmLongProcess.cs new file mode 100644 index 0000000..fe3b0b6 --- /dev/null +++ b/src/Sa.StateMachine/SmLongProcess.cs @@ -0,0 +1,52 @@ +namespace Sa.StateMachine; + + +public abstract class SmLongProcess : SmEnumerable +{ + public record State : SmState + { + public static readonly State WaitingToRun = Create(SmStateId.WaitingToRun, nameof(WaitingToRun)); + public static readonly State Running = Create(SmStateId.Running, nameof(Running)); + public static readonly State Succeed = Create(SmStateId.Succeed, nameof(Succeed)); + + + public static readonly ISmSettings Settings = BuildSettings(builder => builder + .Add(Start, [WaitingToRun]) + .Add(WaitingToRun, [WaitingToRun, Running]) + .Add(Running, [Succeed, Error]) + .Add(Succeed, [Finish]) + .Add(Error, [Finish]) + ); + + public State(int id, string name, StateKind state) + : base(id, name, state) + { + } + } + + protected SmLongProcess() : base(State.Settings) + { + } + + protected override ISmProcessor CreateProcessor() => new Processor(); + + public class Processor : ISmProcessor + { + public ValueTask Finished(ISmContext context) + { + return ValueTask.CompletedTask; + } + + public virtual ValueTask MoveNext(ISmContext context) + { + return context.CurrentState.Id switch + { + SmStateId.Start => ValueTask.FromResult(State.WaitingToRun), + SmStateId.WaitingToRun => ValueTask.FromResult(State.Running), + SmStateId.Running => ValueTask.FromResult(State.Succeed), + SmStateId.Succeed => ValueTask.FromResult(State.Finish), + _ => throw new NotImplementedException(), + }; + } + } +} diff --git a/src/Sa.StateMachine/SmState.cs b/src/Sa.StateMachine/SmState.cs new file mode 100644 index 0000000..5d8f8f6 --- /dev/null +++ b/src/Sa.StateMachine/SmState.cs @@ -0,0 +1,45 @@ +using Sa.Classes; +using Sa.StateMachine.Internal; + +namespace Sa.StateMachine; + + +public abstract record SmState : Enumeration + where TState : SmState +{ + + public static readonly TState Start = CreateStart(); + public static readonly TState Error = CreateError(); + public static readonly TState Finish = CreateFinish(); + + protected SmState(int id, string name, StateKind kind = StateKind.Default) + : base(id, name) + { + Kind = kind; + } + + public StateKind Kind { get; } = StateKind.Default; + + public static ISmSettings BuildSettings(Action> configure) + { + SettingsBulder sb = new(); + configure.Invoke(sb); + return sb.Build(); + } + + public static TState Create(int id, string name) + { + id = id < 100 ? throw new ArgumentException("id must be greater than `99`") : id; + name = name ?? throw new ArgumentNullException(nameof(name)); + return (TState)Activator.CreateInstance(typeof(TState), id, name, StateKind.Default)!; + } + + private static TState CreateStart() + => (TState)Activator.CreateInstance(typeof(TState), SmStateId.Start, nameof(StateKind.Start), StateKind.Start)!; + + private static TState CreateFinish() + => (TState)Activator.CreateInstance(typeof(TState), SmStateId.Finish, nameof(StateKind.Finish), StateKind.Finish)!; + + private static TState CreateError() + => (TState)Activator.CreateInstance(typeof(TState), SmStateId.Error, nameof(StateKind.Error), StateKind.Error)!; +} diff --git a/src/Sa.StateMachine/SmStateId.cs b/src/Sa.StateMachine/SmStateId.cs new file mode 100644 index 0000000..e327139 --- /dev/null +++ b/src/Sa.StateMachine/SmStateId.cs @@ -0,0 +1,13 @@ +namespace Sa.StateMachine; + +public static class SmStateId +{ + // sys ids + public const int Start = 1; + public const int Finish = 0; + public const int Error = -1; + // user ids + public const int WaitingToRun = 101; + public const int Running = 102; + public const int Succeed = 200; +} diff --git a/src/Sa.StateMachine/StateKind.cs b/src/Sa.StateMachine/StateKind.cs new file mode 100644 index 0000000..e80545d --- /dev/null +++ b/src/Sa.StateMachine/StateKind.cs @@ -0,0 +1,9 @@ +namespace Sa.StateMachine; + +public enum StateKind +{ + Default, + Start, + Error, + Finish +} diff --git a/src/Sa.sln b/src/Sa.sln new file mode 100644 index 0000000..2a49a71 --- /dev/null +++ b/src/Sa.sln @@ -0,0 +1,201 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35312.102 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa", "Sa\Sa.csproj", "{BB3A8ECF-5D33-4C41-AF4E-BD384528AAC0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Schedule", "Sa.Schedule\Sa.Schedule.csproj", "{D8098DBA-E1D4-4005-A062-541FAC08C5E6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{610D8708-2CB6-403A-B865-3C1FE0115519}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Schedule.Console", "Samples\Schedule.Console\Schedule.Console.csproj", "{175E26B3-95F8-44C5-AE18-F7F310A3D04B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.StateMachine", "Sa.StateMachine\Sa.StateMachine.csproj", "{6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StateMachine.Console", "Samples\StateMachine.Console\StateMachine.Console.csproj", "{F8C07ACF-8036-4045-B429-850A2AF8674D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BDD5208F-0CF4-4C6A-B443-6527514C89E8}" + ProjectSection(SolutionItems) = preProject + Tests\Host.Test.Properties.xml = Tests\Host.Test.Properties.xml + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Outbox", "Sa.Outbox\Sa.Outbox.csproj", "{958CAA75-B8D6-4356-B4AA-B75658C17374}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Outbox.PostgreSql", "Sa.Outbox.PostgreSql\Sa.Outbox.PostgreSql.csproj", "{2EA016FD-E9EA-4231-89F1-63737868EAB2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Outbox", "Outbox", "{6197ECD9-AA02-4EF1-AAD0-D84D428A7352}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Schedule", "Schedule", "{272C3FEB-29B5-4619-8CAC-9A750E55604A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StateMachine", "StateMachine", "{2719F62C-D1D5-469A-BA1D-EB2999244158}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Data", "Data", "{F9621075-6836-47F5-9160-F9C4743F6147}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Data.PostgreSql", "Sa.Data.PostgreSql\Sa.Data.PostgreSql.csproj", "{F899211C-2E6E-4DF8-839A-11D5CB9B04D3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Outbox.Support", "Sa.Outbox.Attributes\Sa.Outbox.Support.csproj", "{CC86704D-43C7-44E7-BCF5-E59140CE41DE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Data.Cache", "Sa.Data.Cache\Sa.Data.Cache.csproj", "{ABE20E99-6F54-4418-8577-E532DCBB462C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cache", "Cache", "{0BF06FFE-437E-4B1F-98C9-9E8D39AE902E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PostgreSql", "PostgreSql", "{96FCE737-A321-445B-8EC1-05D8863461EA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Media", "Media", "{7B85862F-5BDB-43DF-AD55-F850DE04120E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Media", "Sa.Media\Sa.Media.csproj", "{FFA9194D-D6B2-4350-BE28-B2288A26637A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.MediaTests", "Tests\Sa.MediaTests\Sa.MediaTests.csproj", "{F776F33F-E44B-4FF5-BFB6-43C98667FD66}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Data.PostgreSql.Migration", "Sa.Data.PostgreSql.Migration\Sa.Data.PostgreSql.Migration.csproj", "{075F4DEC-4E00-4982-A634-BDEBD7F63A70}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Fixtures", "Fixtures", "{6FAA2520-3F94-4BD7-A67E-87A9961E094E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{161802B9-8D73-45AF-B52B-62A416CD9FBC}" + ProjectSection(SolutionItems) = preProject + Common.Properties.xml = Common.Properties.xml + Tests\Host.Test.Properties.xml = Tests\Host.Test.Properties.xml + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Data.PostgreSqlTests", "Tests\Sa.Data.PostgreSqlTests\Sa.Data.PostgreSqlTests.csproj", "{0A171BD6-3200-4FE8-9C19-B44E3B84529F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Fixture", "Tests\Fixtures\Sa.Fixture\Sa.Fixture.csproj", "{8D998D31-07BA-4185-B273-03EC3C68DA35}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Data.PostgreSql.Fixture", "Tests\Fixtures\Sa.Data.PostgreSql.Fixture\Sa.Data.PostgreSql.Fixture.csproj", "{944004BF-81CA-4953-B482-AAE275CE601D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Outbox.PostgreSqlTests", "Tests\Sa.Outbox.PostgreSqlTests\Sa.Outbox.PostgreSqlTests.csproj", "{52F64196-9FA5-4B50-AE71-CF6C4DF4B23E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SaTests", "Tests\SaTests\SaTests.csproj", "{4C199038-F002-45B6-9158-2FD27A7392DC}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Partitional", "Partitional", "{71B86B2B-03B6-4637-BC64-5E09BAF88192}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Partitional.PostgreSql", "Sa.Partitional.PostgreSql\Sa.Partitional.PostgreSql.csproj", "{23D36989-1D57-40AE-970D-085B18283D44}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.Partitional.PostgreSqlTests", "Tests\Sa.Partitional.PostgreSqlTests\Sa.Partitional.PostgreSqlTests.csproj", "{F35C5D81-7632-46A2-82C0-CAC9AC65AF30}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sa.ScheduleTests", "Tests\Sa.ScheduleTests\Sa.ScheduleTests.csproj", "{4FEF2F15-D4DC-416A-8640-66152F42CDFE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB3A8ECF-5D33-4C41-AF4E-BD384528AAC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB3A8ECF-5D33-4C41-AF4E-BD384528AAC0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB3A8ECF-5D33-4C41-AF4E-BD384528AAC0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB3A8ECF-5D33-4C41-AF4E-BD384528AAC0}.Release|Any CPU.Build.0 = Release|Any CPU + {D8098DBA-E1D4-4005-A062-541FAC08C5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D8098DBA-E1D4-4005-A062-541FAC08C5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D8098DBA-E1D4-4005-A062-541FAC08C5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D8098DBA-E1D4-4005-A062-541FAC08C5E6}.Release|Any CPU.Build.0 = Release|Any CPU + {175E26B3-95F8-44C5-AE18-F7F310A3D04B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {175E26B3-95F8-44C5-AE18-F7F310A3D04B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {175E26B3-95F8-44C5-AE18-F7F310A3D04B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {175E26B3-95F8-44C5-AE18-F7F310A3D04B}.Release|Any CPU.Build.0 = Release|Any CPU + {6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02}.Release|Any CPU.Build.0 = Release|Any CPU + {F8C07ACF-8036-4045-B429-850A2AF8674D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8C07ACF-8036-4045-B429-850A2AF8674D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8C07ACF-8036-4045-B429-850A2AF8674D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8C07ACF-8036-4045-B429-850A2AF8674D}.Release|Any CPU.Build.0 = Release|Any CPU + {958CAA75-B8D6-4356-B4AA-B75658C17374}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {958CAA75-B8D6-4356-B4AA-B75658C17374}.Debug|Any CPU.Build.0 = Debug|Any CPU + {958CAA75-B8D6-4356-B4AA-B75658C17374}.Release|Any CPU.ActiveCfg = Release|Any CPU + {958CAA75-B8D6-4356-B4AA-B75658C17374}.Release|Any CPU.Build.0 = Release|Any CPU + {2EA016FD-E9EA-4231-89F1-63737868EAB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2EA016FD-E9EA-4231-89F1-63737868EAB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2EA016FD-E9EA-4231-89F1-63737868EAB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2EA016FD-E9EA-4231-89F1-63737868EAB2}.Release|Any CPU.Build.0 = Release|Any CPU + {F899211C-2E6E-4DF8-839A-11D5CB9B04D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F899211C-2E6E-4DF8-839A-11D5CB9B04D3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F899211C-2E6E-4DF8-839A-11D5CB9B04D3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F899211C-2E6E-4DF8-839A-11D5CB9B04D3}.Release|Any CPU.Build.0 = Release|Any CPU + {CC86704D-43C7-44E7-BCF5-E59140CE41DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC86704D-43C7-44E7-BCF5-E59140CE41DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC86704D-43C7-44E7-BCF5-E59140CE41DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC86704D-43C7-44E7-BCF5-E59140CE41DE}.Release|Any CPU.Build.0 = Release|Any CPU + {ABE20E99-6F54-4418-8577-E532DCBB462C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABE20E99-6F54-4418-8577-E532DCBB462C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABE20E99-6F54-4418-8577-E532DCBB462C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABE20E99-6F54-4418-8577-E532DCBB462C}.Release|Any CPU.Build.0 = Release|Any CPU + {FFA9194D-D6B2-4350-BE28-B2288A26637A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FFA9194D-D6B2-4350-BE28-B2288A26637A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FFA9194D-D6B2-4350-BE28-B2288A26637A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FFA9194D-D6B2-4350-BE28-B2288A26637A}.Release|Any CPU.Build.0 = Release|Any CPU + {F776F33F-E44B-4FF5-BFB6-43C98667FD66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F776F33F-E44B-4FF5-BFB6-43C98667FD66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F776F33F-E44B-4FF5-BFB6-43C98667FD66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F776F33F-E44B-4FF5-BFB6-43C98667FD66}.Release|Any CPU.Build.0 = Release|Any CPU + {075F4DEC-4E00-4982-A634-BDEBD7F63A70}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {075F4DEC-4E00-4982-A634-BDEBD7F63A70}.Debug|Any CPU.Build.0 = Debug|Any CPU + {075F4DEC-4E00-4982-A634-BDEBD7F63A70}.Release|Any CPU.ActiveCfg = Release|Any CPU + {075F4DEC-4E00-4982-A634-BDEBD7F63A70}.Release|Any CPU.Build.0 = Release|Any CPU + {0A171BD6-3200-4FE8-9C19-B44E3B84529F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0A171BD6-3200-4FE8-9C19-B44E3B84529F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0A171BD6-3200-4FE8-9C19-B44E3B84529F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0A171BD6-3200-4FE8-9C19-B44E3B84529F}.Release|Any CPU.Build.0 = Release|Any CPU + {8D998D31-07BA-4185-B273-03EC3C68DA35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D998D31-07BA-4185-B273-03EC3C68DA35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D998D31-07BA-4185-B273-03EC3C68DA35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D998D31-07BA-4185-B273-03EC3C68DA35}.Release|Any CPU.Build.0 = Release|Any CPU + {944004BF-81CA-4953-B482-AAE275CE601D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {944004BF-81CA-4953-B482-AAE275CE601D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {944004BF-81CA-4953-B482-AAE275CE601D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {944004BF-81CA-4953-B482-AAE275CE601D}.Release|Any CPU.Build.0 = Release|Any CPU + {52F64196-9FA5-4B50-AE71-CF6C4DF4B23E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52F64196-9FA5-4B50-AE71-CF6C4DF4B23E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52F64196-9FA5-4B50-AE71-CF6C4DF4B23E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52F64196-9FA5-4B50-AE71-CF6C4DF4B23E}.Release|Any CPU.Build.0 = Release|Any CPU + {4C199038-F002-45B6-9158-2FD27A7392DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4C199038-F002-45B6-9158-2FD27A7392DC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4C199038-F002-45B6-9158-2FD27A7392DC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4C199038-F002-45B6-9158-2FD27A7392DC}.Release|Any CPU.Build.0 = Release|Any CPU + {23D36989-1D57-40AE-970D-085B18283D44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23D36989-1D57-40AE-970D-085B18283D44}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23D36989-1D57-40AE-970D-085B18283D44}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23D36989-1D57-40AE-970D-085B18283D44}.Release|Any CPU.Build.0 = Release|Any CPU + {F35C5D81-7632-46A2-82C0-CAC9AC65AF30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F35C5D81-7632-46A2-82C0-CAC9AC65AF30}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F35C5D81-7632-46A2-82C0-CAC9AC65AF30}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F35C5D81-7632-46A2-82C0-CAC9AC65AF30}.Release|Any CPU.Build.0 = Release|Any CPU + {4FEF2F15-D4DC-416A-8640-66152F42CDFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FEF2F15-D4DC-416A-8640-66152F42CDFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FEF2F15-D4DC-416A-8640-66152F42CDFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FEF2F15-D4DC-416A-8640-66152F42CDFE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D8098DBA-E1D4-4005-A062-541FAC08C5E6} = {272C3FEB-29B5-4619-8CAC-9A750E55604A} + {175E26B3-95F8-44C5-AE18-F7F310A3D04B} = {610D8708-2CB6-403A-B865-3C1FE0115519} + {6FC2E5C6-41E6-4C64-9BF5-912E40BB8E02} = {2719F62C-D1D5-469A-BA1D-EB2999244158} + {F8C07ACF-8036-4045-B429-850A2AF8674D} = {610D8708-2CB6-403A-B865-3C1FE0115519} + {958CAA75-B8D6-4356-B4AA-B75658C17374} = {6197ECD9-AA02-4EF1-AAD0-D84D428A7352} + {2EA016FD-E9EA-4231-89F1-63737868EAB2} = {6197ECD9-AA02-4EF1-AAD0-D84D428A7352} + {F899211C-2E6E-4DF8-839A-11D5CB9B04D3} = {96FCE737-A321-445B-8EC1-05D8863461EA} + {CC86704D-43C7-44E7-BCF5-E59140CE41DE} = {6197ECD9-AA02-4EF1-AAD0-D84D428A7352} + {ABE20E99-6F54-4418-8577-E532DCBB462C} = {0BF06FFE-437E-4B1F-98C9-9E8D39AE902E} + {0BF06FFE-437E-4B1F-98C9-9E8D39AE902E} = {F9621075-6836-47F5-9160-F9C4743F6147} + {96FCE737-A321-445B-8EC1-05D8863461EA} = {F9621075-6836-47F5-9160-F9C4743F6147} + {FFA9194D-D6B2-4350-BE28-B2288A26637A} = {7B85862F-5BDB-43DF-AD55-F850DE04120E} + {F776F33F-E44B-4FF5-BFB6-43C98667FD66} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {075F4DEC-4E00-4982-A634-BDEBD7F63A70} = {96FCE737-A321-445B-8EC1-05D8863461EA} + {6FAA2520-3F94-4BD7-A67E-87A9961E094E} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {0A171BD6-3200-4FE8-9C19-B44E3B84529F} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {8D998D31-07BA-4185-B273-03EC3C68DA35} = {6FAA2520-3F94-4BD7-A67E-87A9961E094E} + {944004BF-81CA-4953-B482-AAE275CE601D} = {6FAA2520-3F94-4BD7-A67E-87A9961E094E} + {52F64196-9FA5-4B50-AE71-CF6C4DF4B23E} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {4C199038-F002-45B6-9158-2FD27A7392DC} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {23D36989-1D57-40AE-970D-085B18283D44} = {71B86B2B-03B6-4637-BC64-5E09BAF88192} + {F35C5D81-7632-46A2-82C0-CAC9AC65AF30} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + {4FEF2F15-D4DC-416A-8640-66152F42CDFE} = {BDD5208F-0CF4-4C6A-B443-6527514C89E8} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {968372C4-E303-4F1F-A924-7568CCDE3E7C} + EndGlobalSection +EndGlobal diff --git a/src/Sa/Classes/ArrayPooler.cs b/src/Sa/Classes/ArrayPooler.cs new file mode 100644 index 0000000..29500e7 --- /dev/null +++ b/src/Sa/Classes/ArrayPooler.cs @@ -0,0 +1,28 @@ +using System.Buffers; + +namespace Sa.Classes; + + +public interface IArrayPooler +{ + T[] Rent(int minimumLength); + void Return(T[] array, bool clearArray = false); +} + +public interface IArrayPoolFactory +{ + IArrayPooler Create(); +} + + + +internal class ArrayPooler : IArrayPooler +{ + public T[] Rent(int minimumLength) => ArrayPool.Shared.Rent(minimumLength); + public void Return(T[] array, bool clearArray = false) => ArrayPool.Shared.Return(array, clearArray); +} + +internal class ArrayPoolFactory : IArrayPoolFactory +{ + public IArrayPooler Create() => new ArrayPooler(); +} diff --git a/src/Sa/Classes/Enumeration.cs b/src/Sa/Classes/Enumeration.cs new file mode 100644 index 0000000..50eeed8 --- /dev/null +++ b/src/Sa/Classes/Enumeration.cs @@ -0,0 +1,67 @@ +using Sa.Infrastructure; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; + +namespace Sa.Classes; + +/// +/// https://josef.codes/enumeration-class-in-c-sharp-using-records/ +/// +/// +public record Enumeration(int Id, string Name) : IHasId, IComparable + where T : Enumeration +{ + + private static readonly Lazy> AllItems = new(() => + { + return typeof(T) + .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) + .Where(x => x.FieldType == typeof(T)) + .Select(x => x.GetValue(null)) + .Cast() + .ToDictionary(x => x.Id, x => x); + }); + + private static readonly Lazy> AllItemsByName = new(() => + { + Dictionary items = new(AllItems.Value.Count); + foreach (T? value in AllItems.Value.Select(c => c.Value)) + { + items.TryAdd(value.Name, value); + } + return items; + }); + + [DebuggerStepThrough] + public static IEnumerable GetAll() => AllItems.Value.Values; + + [DebuggerStepThrough] + public static int DiffId(Enumeration firstId, Enumeration secondId) + => Math.Abs(firstId.Id - secondId.Id); + + [DebuggerStepThrough] + public static T FromId(int id) + => TryFromId(id, out var matchingItem) + ? matchingItem + : throw new InvalidOperationException($"'{id}' is not a valid value in {typeof(T)}"); + + [DebuggerStepThrough] + public static T FromName(string name) + => (TryFromName(name, out var matchingItem)) + ? matchingItem + : throw new InvalidOperationException($"'{name}' is not a valid display name in {typeof(T)}"); + + [DebuggerStepThrough] + public static bool TryFromName(string name, [MaybeNullWhen(false)] out T item) + => AllItemsByName.Value.TryGetValue(name, out item); + + [DebuggerStepThrough] + public static bool TryFromId(int id, [MaybeNullWhen(false)] out T item) + => AllItems.Value.TryGetValue(id, out item); + + [DebuggerStepThrough] + public int CompareTo(T? other) => Id.CompareTo(other!.Id); + + public override string ToString() => Name; +} diff --git a/src/Sa/Classes/KeepLocker.cs b/src/Sa/Classes/KeepLocker.cs new file mode 100644 index 0000000..1272ebc --- /dev/null +++ b/src/Sa/Classes/KeepLocker.cs @@ -0,0 +1,41 @@ +namespace Sa.Classes; + +public static class KeepLocker +{ + public static IDisposable KeepLocked(TimeSpan lockExpiration, Func extendLocked, bool blockImmediately = false, CancellationToken cancellationToken = default) + { + var timer = new PeriodicTimer(lockExpiration); + var task = Task.Run(async () => + { + try + { + if (blockImmediately) + { + await extendLocked(cancellationToken); + } + + while (await timer.WaitForNextTickAsync(cancellationToken)) + { + await extendLocked(cancellationToken); + } + } + catch + { + // ignore + } + }, cancellationToken); + + IDisposable keeper = new DisposableTimer(timer, task); + + return keeper; + } + + private sealed class DisposableTimer(PeriodicTimer timer, Task task) : IDisposable + { + public void Dispose() + { + timer.Dispose(); + task.Wait(); // Ожидание завершения задачи перед освобождением ресурсов + } + } +} \ No newline at end of file diff --git a/src/Sa/Classes/MurmurHash3.cs b/src/Sa/Classes/MurmurHash3.cs new file mode 100644 index 0000000..cf0a8cc --- /dev/null +++ b/src/Sa/Classes/MurmurHash3.cs @@ -0,0 +1,57 @@ +using System.Runtime.CompilerServices; + +namespace Sa.Classes; + +/// +/// https://github.com/odinmillion/MurmurHash.Net/blob/master/src/MurmurHash.Net/MurmurHash3.cs +/// +public static class MurmurHash3 +{ + [System.Diagnostics.CodeAnalysis.SuppressMessage("Major Code Smell", "S907:\"goto\" statement should not be used", Justification = "")] + public static uint Hash32(ReadOnlySpan bytes, uint seed) + { + var length = bytes.Length; + var h1 = seed; + var remainder = length & 3; + var position = length - remainder; + for (var start = 0; start < position; start += 4) + h1 = (uint)((int)RotateLeft(h1 ^ RotateLeft(BitConverter.ToUInt32(bytes.Slice(start, 4)) * 3432918353U, 15) * 461845907U, 13) * 5 - 430675100); + + if (remainder > 0) + { + uint num = 0; + switch (remainder) + { + case 1: + num ^= (uint)bytes[position]; + break; + case 2: + num ^= (uint)bytes[position + 1] << 8; + goto case 1; + case 3: + num ^= (uint)bytes[position + 2] << 16; + goto case 2; + } + + h1 ^= RotateLeft(num * 3432918353U, 15) * 461845907U; + } + + h1 = FMix(h1 ^ (uint)length); + + return h1; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint RotateLeft(uint x, byte r) + { + return x << (int)r | x >> 32 - (int)r; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static uint FMix(uint h) + { + h = (uint)(((int)h ^ (int)(h >> 16)) * -2048144789); + h = (uint)(((int)h ^ (int)(h >> 13)) * -1028477387); + return h ^ h >> 16; + } +} \ No newline at end of file diff --git a/src/Sa/Classes/Quartz.cs b/src/Sa/Classes/Quartz.cs new file mode 100644 index 0000000..336e9fb --- /dev/null +++ b/src/Sa/Classes/Quartz.cs @@ -0,0 +1,120 @@ +using System.Diagnostics; + +namespace Sa.Classes; + +public static partial class Quartz +{ + private static IEnumerable Empty() => []; + + private static void ValidateParameters(TimeSpan delay, int retryCount, string delayParamName) + { + if (delay < TimeSpan.Zero) throw new ArgumentOutOfRangeException(delayParamName, delay, "should be >= 0ms"); + if (retryCount < 0) throw new ArgumentOutOfRangeException(nameof(retryCount), retryCount, "should be >= 0"); + } + + [DebuggerStepThrough] + public static IEnumerable GenerateConstant(TimeSpan delay, int retryCount, bool fastFirst = false) + { + ValidateParameters(delay, retryCount, nameof(delay)); + return retryCount == 0 ? Empty() : Generator.GenConstant(delay, retryCount, fastFirst); + } + + [DebuggerStepThrough] + public static IEnumerable GenerateLinear(TimeSpan initialDelay, int retryCount, double factor = 1.0, bool fastFirst = true) + { + ValidateParameters(initialDelay, retryCount, nameof(initialDelay)); + if (factor < 0) throw new ArgumentOutOfRangeException(nameof(factor), factor, "should be >= 0"); + + return retryCount == 0 ? Empty() : Generator.GenLinear(initialDelay, retryCount, factor, fastFirst); + } + + [DebuggerStepThrough] + public static IEnumerable GenerateExponential(TimeSpan initialDelay, int retryCount, double factor = 2.0, bool fastFirst = true) + { + ValidateParameters(initialDelay, retryCount, nameof(initialDelay)); + if (factor < 1.0) throw new ArgumentOutOfRangeException(nameof(factor), factor, "should be >= 1.0"); + + return retryCount == 0 ? Empty() : Generator.GenExponential(initialDelay, retryCount, factor, fastFirst); + } + + [DebuggerStepThrough] + public static IEnumerable GenerateJitter(TimeSpan medianFirstRetryDelay, int retryCount, bool fastFirst = true) + { + ValidateParameters(medianFirstRetryDelay, retryCount, nameof(medianFirstRetryDelay)); + return retryCount == 0 ? Empty() : Generator.GenJitter(medianFirstRetryDelay, retryCount, fastFirst); + } + + + static class Generator + { + + public static IEnumerable GenConstant(TimeSpan delay, int retryCount, bool fastFirst) + { + if (fastFirst) + { + yield return TimeSpan.Zero; + } + + for (int i = fastFirst ? 1 : 0; i < retryCount; i++) + { + yield return delay; + } + } + + public static IEnumerable GenLinear(TimeSpan initialDelay, int retryCount, double factor, bool fastFirst) + { + if (fastFirst) + { + yield return TimeSpan.Zero; + } + + double ms = initialDelay.TotalMilliseconds; + double increment = factor * ms; + + for (int i = fastFirst ? 1 : 0; i < retryCount; i++, ms += increment) + { + yield return TimeSpan.FromMilliseconds(ms); + } + } + + public static IEnumerable GenExponential(TimeSpan initialDelay, int retryCount, double factor, bool fastFirst) + { + if (fastFirst) + { + yield return TimeSpan.Zero; + } + + double ms = initialDelay.TotalMilliseconds; + + for (int i = fastFirst ? 1 : 0; i < retryCount; i++, ms *= factor) + { + yield return TimeSpan.FromMilliseconds(ms); + } + } + + public static IEnumerable GenJitter(TimeSpan medianFirstRetryDelay, int retryCount, bool fastFirst) + { + const double pFactor = 4.0; + const double rpScalingFactor = 1 / 1.4d; + double maxTimeSpanDouble = (double)TimeSpan.MaxValue.Ticks - 1000; + + if (fastFirst) + { + yield return TimeSpan.Zero; + } + + long targetTicksFirstDelay = medianFirstRetryDelay.Ticks; + double prev = 0.0; + + for (int i = fastFirst ? 1 : 0; i < retryCount; i++) + { + double t = i + Random.Shared.NextDouble(); + double next = Math.Pow(2, t) * Math.Tanh(Math.Sqrt(pFactor * t)); + double formulaIntrinsicValue = next - prev; + + yield return TimeSpan.FromTicks((long)Math.Min(formulaIntrinsicValue * rpScalingFactor * targetTicksFirstDelay, maxTimeSpanDouble)); + prev = next; + } + } + } +} diff --git a/src/Sa/Classes/ResetLazy.cs b/src/Sa/Classes/ResetLazy.cs new file mode 100644 index 0000000..6514ef0 --- /dev/null +++ b/src/Sa/Classes/ResetLazy.cs @@ -0,0 +1,105 @@ +using System.Diagnostics; + +namespace Sa.Classes; + +public interface IResetLazy +{ + object? Value { get; } + void Reset(); + void Load(); +} + + +/// +/// Provides support for lazy initialization with reset +/// +/// The type of object that is being lazily initialized. +[DebuggerStepThrough] +public sealed class ResetLazy(Func valueFactory, LazyThreadSafetyMode mode = LazyThreadSafetyMode.PublicationOnly, Action? valueReset = null) : IResetLazy +{ + record Box(T Value); + + private readonly Func _valueFactory = valueFactory ?? throw new ArgumentNullException(nameof(valueFactory)); + + private readonly object _syncLock = new(); + + private Box? _box; + + public T Value + { + [DebuggerStepThrough] + get + { + Box? b1 = _box; + if (b1 != null) + return b1.Value; + + if (mode == LazyThreadSafetyMode.ExecutionAndPublication) + { + lock (_syncLock) + { + Box? b2 = _box; + if (b2 != null) + return b2.Value; + + _box = new Box(CreateValue()); + + return _box.Value; + } + } + else if (mode == LazyThreadSafetyMode.PublicationOnly) + { + T newValue = CreateValue(); + + lock (_syncLock) + { + Box? b2 = _box; + if (b2 != null) + return b2.Value; + + _box = new Box(newValue); + + return _box.Value; + } + } + else + { + Box? b = new(CreateValue()); + _box = b; + return b.Value; + } + } + } + + private T CreateValue() => _valueFactory(); + + public void Load() => _ = Value; + + public bool IsValueCreated => _box != null; + + object? IResetLazy.Value => Value; + + public void Reset() + { + if (mode != LazyThreadSafetyMode.None) + { + lock (_syncLock) + { + ResetBox(); + } + } + else + { + ResetBox(); + } + } + + private void ResetBox() + { + if (IsValueCreated) + { + valueReset?.Invoke(_box!.Value); + _box = null; + } + } +} diff --git a/src/Sa/Classes/Retry.cs b/src/Sa/Classes/Retry.cs new file mode 100644 index 0000000..7477e90 --- /dev/null +++ b/src/Sa/Classes/Retry.cs @@ -0,0 +1,227 @@ +using Sa.Extensions; +using System.Diagnostics; + +namespace Sa.Classes; + + + +public static class Retry +{ + /// + /// For example: 500ms, 500ms, 500ms ... + /// + [DebuggerStepThrough] + public static ValueTask Constant( + Func> fun, + I input, + int retryCount = 3, + int waitTime = 500, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateConstant(TimeSpan.FromMilliseconds(waitTime), retryCount, fastFirst: true) + .WaitAndRetry(fun, input, next, cancellationToken: cancellationToken); + } + + [DebuggerStepThrough] + public static ValueTask Constant( + Func> fun, + int retryCount = 3, + int waitTime = 500, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateConstant(TimeSpan.FromMilliseconds(waitTime), retryCount, fastFirst: true) + .WaitAndRetry(fun, next, cancellationToken: cancellationToken); + } + + /// + /// For example: 100ms, 200ms, 400ms, 800ms, ... + /// + [DebuggerStepThrough] + public static ValueTask Exponential( + Func> fun, + I input, + int retryCount = 3, + int initialDelay = 100, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateExponential(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, input, next, cancellationToken: cancellationToken); + } + + /// + /// For example: 100ms, 200ms, 400ms, 800ms, ... + /// + [DebuggerStepThrough] + public static ValueTask Exponential( + Func> fun, + int retryCount = 3, + int initialDelay = 100, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateExponential(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, next, cancellationToken: cancellationToken); + } + + /// + /// For example: 100ms, 200ms, 300ms, 400ms, .. + /// + [DebuggerStepThrough] + public static ValueTask Linear( + Func> fun, + I input, + int retryCount = 3, + int initialDelay = 100, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateLinear(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, input, next, cancellationToken); + } + + + /// + /// For example: 100ms, 200ms, 300ms, 400ms, .. + /// + [DebuggerStepThrough] + public static ValueTask Linear( + Func> fun, + int retryCount = 3, + int initialDelay = 100, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateLinear(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, next, cancellationToken); + } + + + + /// + /// For example: 850ms, 1455ms, 3060ms. + /// + [DebuggerStepThrough] + public static ValueTask Jitter( + Func> fun, + I input, + int retryCount = 3, + int initialDelay = 530, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateJitter(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, input, next, cancellationToken: cancellationToken); + } + + /// + /// For example: 850ms, 1455ms, 3060ms. + /// + [DebuggerStepThrough] + public static ValueTask Jitter( + Func> fun, + int retryCount = 3, + int initialDelay = 530, + Func? next = null, + CancellationToken cancellationToken = default) + { + return Quartz.GenerateJitter(TimeSpan.FromMilliseconds(initialDelay), retryCount, fastFirst: true) + .WaitAndRetry(fun, next, cancellationToken: cancellationToken); + } + + [DebuggerStepThrough] + public static async ValueTask WaitAndRetry( + this IEnumerable timeSpans, + Func> fun, + I input, + Func? next = null, + CancellationToken cancellationToken = default) + { + TimeSpan[] points = timeSpans.ToArray(); + + for (int i = 0; i < points.Length - 1; i++) + { + if (cancellationToken.IsCancellationRequested) break; + + try + { + return await fun(input, cancellationToken); + } + catch (Exception e) + { + if (e is TaskCanceledException) + { + break; + } + else if (e.IsCritical() || next != null && !next(e, i)) + { + throw; + } + + await Wait(points[i], cancellationToken); + } + } + + if (points.Length > 0) + { + await Wait(points[^1], cancellationToken); + } + + return await fun(input, cancellationToken); + } + + [DebuggerStepThrough] + public static async ValueTask WaitAndRetry( + this IEnumerable timeSpans, + Func> fun, + Func? next = null, + CancellationToken cancellationToken = default) + { + TimeSpan[] points = timeSpans.ToArray(); + + for (int i = 0; i < points.Length - 1; i++) + { + if (cancellationToken.IsCancellationRequested) break; + + try + { + return await fun(cancellationToken); + } + catch (Exception e) + { + if (e is TaskCanceledException) + { + break; + } + else if (e.IsCritical() || next != null && !next(e, i)) + { + throw; + } + + await Wait(points[i], cancellationToken); + } + } + + if (points.Length > 0) + { + await Wait(points[^1], cancellationToken); + } + + return await fun(cancellationToken); + } + + private static async Task Wait(TimeSpan delay, CancellationToken cancellationToken) + { + if (cancellationToken.IsCancellationRequested) return; + try + { + await Task.Delay(delay, cancellationToken); + } + catch (TaskCanceledException) + { + // ignore + } + } +} \ No newline at end of file diff --git a/src/Sa/Classes/Section.cs b/src/Sa/Classes/Section.cs new file mode 100644 index 0000000..5ac7bf4 --- /dev/null +++ b/src/Sa/Classes/Section.cs @@ -0,0 +1,239 @@ +using System.Diagnostics; + +namespace Sa.Classes; + +/// +/// line +/// экземпляр с конкретным началом и окончанием +/// +/// +/// начало +/// конец +[DebuggerStepThrough] +public record Section(T Start, T End) where T : IComparable +{ + public static readonly Section Empty = new(default!, default!); +} + +/// +/// line with lim end +/// экземпляр с конкретным началом, окончанием и указанием включен ли конец в диапазон +/// +/// +/// начало +/// конец +/// Indicates whether the value at the end of the range is included + +[DebuggerStepThrough] +public record LimSection(T Start, T End, bool HasEnd = false) + : Section(Start, End) where T : IComparable +{ + public static readonly new LimSection Empty = new(default!, default!, false); +} + +/// +/// half-line or ray +/// экземпляр с конкретным началом, возможным окончанием и указанием включен ли конец в диапазон +/// +/// +/// начало +/// конец или бесконечность +/// Indicates whether the value at the end of the range is included +[DebuggerStepThrough] +public record HalfSection(T Start, T? End, bool HasEnd = false) +{ + public static readonly HalfSection Empty = new(default!, default, false); +} + +[DebuggerStepThrough] +public static class RangeExtensions +{ + public static LimSection RangeTo(Section range, bool hasEnd) where T : IComparable => new(range.Start, range.End, hasEnd); + public static Section RangeTo(this T from, T to) where T : IComparable => new(from, to); + public static Section RangeTo(this T from, Func to) where T : IComparable => new(from, to(from)); + public static LimSection RangeTo(this T from, T to, bool hasEnd) where T : IComparable => new(from, to, hasEnd); + public static LimSection RangeTo(this T from, Func to, bool hasEnd) where T : IComparable => new(from, to(from), hasEnd); + public static bool IsPositive(this Section range) where T : IComparable => range.Start.CompareTo(range.End) <= 0; + public static bool IsPositive(this LimSection range) where T : IComparable => range.Start.CompareTo(range.End) <= 0; + public static Section Reverse(this Section range) where T : IComparable => range.End.RangeTo(range.Start); + public static LimSection Reverse(this LimSection range) where T : IComparable => range.End.RangeTo(range.Start, range.HasEnd); + public static Section Normalize(this Section range) where T : IComparable => range.IsPositive() ? range : Reverse(range); + public static LimSection Normalize(this LimSection range) where T : IComparable => range.IsPositive() ? range : Reverse(range); + public static bool InRange(this Section range, T value) where T : IComparable => range.Start.CompareTo(value) <= 0 && (range.End.CompareTo(value) >= 0); + public static bool InRange(this LimSection range, T value) where T : IComparable + => range.Start.CompareTo(value) <= 0 && (range.HasEnd ? range.End.CompareTo(value) >= 0 : range.End.CompareTo(value) > 0); + + /// + /// >список пустых (незанятых) интервалов + /// + /// + /// интервал + /// список отрезков, которые заняты + /// список пустых (незанятых) интервалов + public static List> FindEmptyIntervals(this Section range, IEnumerable> busyIntervals) + where T : IComparable + { + List> emptyIntervals = []; + + // Сортируем временные отрезки по начальному времени busyIntervals + Section[] sortedBusyIntervals = busyIntervals.ToArray(); + + if (sortedBusyIntervals.Length > 1) + { + Array.Sort(sortedBusyIntervals, (a, b) => a.Start.CompareTo(b.Start)); + } + + T currentStart = range.Start; + foreach (Section interval in sortedBusyIntervals) + { + if (interval.Start.CompareTo(currentStart) > 0) + { + T currentEnd = interval.Start; + emptyIntervals.Add(new Section(currentStart, currentEnd)); + } + currentStart = interval.End; + } + + if (range.End.CompareTo(currentStart) > 0) + { + emptyIntervals.Add(new Section(currentStart, range.End)); + } + + return emptyIntervals; + } + + /// + /// Поиск пересечения + /// + public static Section? FindIntersections(this Section self, Section other) + where T : IComparable + { + if (other.End.CompareTo(self.Start) >= 0 && self.End.CompareTo(other.Start) >= 0) + { + T start = self.Start.CompareTo(other.Start) >= 0 ? self.Start : other.Start; + T end = self.End.CompareTo(other.End) < 0 ? self.End : other.End; + return new Section(start, end); + } + + return null; + } + + /// + /// объединения интервалов + /// + public static List> MergeIntervals(this Section self, IEnumerable> intervals) + where T : IComparable + { + var list = new List>(intervals) + { + self + }; + + return MergeIntervals(list); + } + + /// + /// объединения интервалов + /// + public static List> MergeIntervals(IEnumerable> intervals) + where T : IComparable + { + List> sortedList = new(intervals); + + if (sortedList.Count > 1) + { + sortedList.Sort((a, b) => a.Start.CompareTo(b.Start)); // Сортировка по начальным точкам + } + + List> mergedIntervals = []; + + Section currentInterval = sortedList[0]; + + foreach (Section interval in sortedList) + { + if (currentInterval.End.CompareTo(interval.Start) >= 0) // Пересечение интервалов + { + var currentEnd = currentInterval.End.CompareTo(interval.End) >= 0 + ? currentInterval.End + : interval.End; + + currentInterval = new Section(currentInterval.Start, currentEnd); + } + else + { + mergedIntervals.Add(currentInterval); + currentInterval = interval; + } + } + + mergedIntervals.Add(currentInterval); // Добавление последнего интервала + + return mergedIntervals; + } + + + public static IEnumerable Enumerate(this Section self, Func next) + where T : IComparable + { + T? c = self.Start; + while (c is not null && self.End.CompareTo(c) > 0) + { + yield return c; + c = next(c); + } + } + + + /// + /// разделения интервала + /// + public static List> SplitInterval(this Section self, params T[] points) + where T : IComparable => SplitInterval(self, points.AsEnumerable()); + + public static List> SplitInterval(this Section self, IEnumerable points) + where T : IComparable + { + var sortedPoints = points.ToArray(); + + if (sortedPoints.Length > 1) Array.Sort(sortedPoints); + + List> splitIntervals = []; + + T prevPoint = self.Start; + foreach (T point in sortedPoints) + { + if (point.CompareTo(self.Start) > 0 && self.End.CompareTo(point) > 0) + { + splitIntervals.Add(prevPoint.RangeTo(point)); + prevPoint = point; + } + } + + splitIntervals.Add(prevPoint.RangeTo(self.End)); + return splitIntervals; + } + + /// + /// разбиение интервала + /// + public static List> SplitInterval(this Section self, Func next) + where T : IComparable => SplitInterval(self, Enumerate(self, next).Skip(1)); + + /// + /// проверки включения интервалов + /// + public static bool IsIntervalIncluded(this Section self, Section other) + where T : IComparable => other.Start.CompareTo(self.Start) >= 0 && self.End.CompareTo(other.End) >= 0; + + public static bool IsPoint(this Section self) where T : IComparable => self.Start.CompareTo(self.End) == 0; + + public static bool IsEmpty(this Section self) where T : IComparable => self == Section.Empty; + public static bool IsEmpty(this LimSection self) where T : IComparable => self == LimSection.Empty; + public static bool IsEmpty(this HalfSection self) where T : IComparable => self == HalfSection.Empty; + + public static TimeSpan GetLength(this Section range) => range.End.ToUniversalTime() - range.Start.ToUniversalTime(); + public static int GetLength(this Section range) => range.End - range.Start; + public static long GetLength(this Section range) => range.End - range.Start; + public static float GetLength(this Section range) => range.End - range.Start; + public static double GetLength(this Section range) => range.End - range.Start; +} diff --git a/src/Sa/Classes/StrOrNum.cs b/src/Sa/Classes/StrOrNum.cs new file mode 100644 index 0000000..acfd4aa --- /dev/null +++ b/src/Sa/Classes/StrOrNum.cs @@ -0,0 +1,83 @@ +using Sa.Extensions; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Sa.Classes; + +/// +///StrOrNum +/// +/// +/// StrOrNum val = 10; +/// StrOrNum val_1 = "привет"; +/// string v = val.Match( +/// onChoiceNum: item => $"long: {item}", +/// onChoiceStr: item => $"string: {item}" +/// ); +/// +/// +/// +/// +[JsonConverter(typeof(StrOrNumConverter))] +public abstract record StrOrNum +{ + public record ChoiceStr(string Item) : StrOrNum + { + public override string ToString() => Item; + } + + public record ChoiceNum(long Item) : StrOrNum + { + public override string ToString() => Item.ToString(); + } + + public U Match(Func onChoiceStr, Func onChoiceNum) + => Match(onChoiceStr, onChoiceNum, this); + + + public static implicit operator StrOrNum(string item) => new ChoiceStr(item); + + public static implicit operator StrOrNum(int item) => new ChoiceNum(item); + public static implicit operator StrOrNum(long item) => new ChoiceNum(item); + public static implicit operator StrOrNum(short item) => new ChoiceNum(item); + + public static explicit operator string(StrOrNum choice) => choice.Match(c1 => c1, c2 => c2.ToString()); + public static explicit operator long(StrOrNum choice) => choice.Match(c1 => c1.StrToLong() ?? 0, c2 => c2); + public static explicit operator int(StrOrNum choice) => choice.Match(c1 => c1.StrToInt() ?? 0, c2 => (int)c2); + public static explicit operator short(StrOrNum choice) => choice.Match(c1 => c1.StrToShort() ?? 0, c2 => (short)c2); + + private static U Match(Func onChoiceStr, Func onChoiceNum, StrOrNum choice) + { + U result = choice switch + { + ChoiceStr c => onChoiceStr(c.Item), + ChoiceNum c => onChoiceNum(c.Item), + _ => throw new ArgumentOutOfRangeException(nameof(choice)) + }; + + return result; + } + + public override string ToString() => Match(str => str, num => num.ToString()); + + private StrOrNum() { } +} + + + +public class StrOrNumConverter : JsonConverter +{ + public override StrOrNum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string? str = reader.GetString(); + + if (str == null) return new StrOrNum.ChoiceStr(string.Empty); + + return str[0] == 'n' + ? new StrOrNum.ChoiceNum(str[2..].StrToLong() ?? 0) + : new StrOrNum.ChoiceStr(str[2..]); + } + + public override void Write(Utf8JsonWriter writer, StrOrNum value, JsonSerializerOptions options) + => writer.WriteStringValue(value.Match(s => $"s:{s}", n => $"n:{n}")); +} diff --git a/src/Sa/Classes/WorkQueue.cs b/src/Sa/Classes/WorkQueue.cs new file mode 100644 index 0000000..6a8cbb1 --- /dev/null +++ b/src/Sa/Classes/WorkQueue.cs @@ -0,0 +1,150 @@ +using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Channels; + +namespace Sa.Classes; + + +public interface IWork +{ + Task Execute(TModel model, CancellationToken cancellationToken); +} + + +public interface IWorkWithHandleError : IWork +{ + Task HandelError(Exception exception, TModel model, CancellationToken cancellationToken); +} + +public interface IWorkQueue : IAsyncDisposable + where TModel : notnull + where TWork : IWork +{ + WorkQueue Enqueue([NotNull] TModel model, TWork work, CancellationToken cancellationToken = default); + Task Stop(TModel model); +} + + +/// +/// +/// +/// +/// +/// +public sealed class WorkQueue : IWorkQueue where TModel : notnull + where TWork : IWork +{ + private readonly ConcurrentDictionary _workPools = new(); + + + public WorkQueue Enqueue([NotNull] TModel model, TWork work, CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(model); + _workPools.GetOrAdd(model, WorkQueue.StartNewWorkPool(model, cancellationToken)).Enqueue(work); + return this; + } + + private static WorkPool StartNewWorkPool(TModel model, CancellationToken cancellationToken) + { + var newWorkPool = new WorkPool(model); + newWorkPool.Start(cancellationToken); + return newWorkPool; + } + + public async Task Stop(TModel model) + { + if (_workPools.TryRemove(model, out WorkPool? workPool)) + { + await workPool.DisposeAsync(); + } + } + + public async ValueTask DisposeAsync() + { + foreach (TModel model in _workPools.Keys) + { + await Stop(model); + } + } + + private sealed class WorkPool : IAsyncDisposable + { + private readonly Channel _channel; + private readonly TModel _model; + private Task? _worker; + private readonly CancellationTokenSource _stoppedTokenSource = new(); + + public WorkPool([NotNullWhen(true)] TModel model) + { + _model = model; + _channel = Channel.CreateUnbounded(new UnboundedChannelOptions + { + SingleReader = true, + SingleWriter = false, + AllowSynchronousContinuations = false + }); + } + + public void Start(CancellationToken cancellationToken) + { + _worker = Task.Run(() => Loop(cancellationToken), cancellationToken); + } + + public void Enqueue(TWork work) + { + _channel.Writer.TryWrite(work); + } + + private async Task Loop(CancellationToken cancellationToken) + { + while (!cancellationToken.IsCancellationRequested && await _channel.Reader.WaitToReadAsync(cancellationToken).ConfigureAwait(false)) + { + while (_channel.Reader.TryRead(out TWork? work)) + { + using var stoppingTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_stoppedTokenSource.Token, cancellationToken); + CancellationToken token = stoppingTokenSource.Token; + try + { + Task task = work.Execute(_model, token); + if (!task.IsCompleted) + { + await task.ConfigureAwait(false); + } + } + catch (OperationCanceledException ex) when (ex.CancellationToken == token) + { + // ignore + } + catch (Exception error) + { + if (work is IWorkWithHandleError handler) + { + await handler.HandelError(error, _model, CancellationToken.None); + } + } + } + } + } + + public async ValueTask DisposeAsync() + { + _channel.Writer.Complete(); + await _stoppedTokenSource.CancelAsync(); + + if (_worker != null) + { + try + { + await _worker; + } + catch (OperationCanceledException) + { + // ignore + } + } + + _stoppedTokenSource.Dispose(); + } + } +} + diff --git a/src/Sa/Extensions/DateTimeExtensions.cs b/src/Sa/Extensions/DateTimeExtensions.cs new file mode 100644 index 0000000..15957c9 --- /dev/null +++ b/src/Sa/Extensions/DateTimeExtensions.cs @@ -0,0 +1,29 @@ +using System.Diagnostics; + +namespace Sa.Extensions; + +public static class DateTimeExtensions +{ + /// + /// unix timestamp + /// + [DebuggerStepThrough] + public static long ToUnixTimestamp(this DateTime dateTime, bool isInMilliseconds = false) + { + TimeSpan ts = dateTime.ToUniversalTime().Subtract(DateTime.UnixEpoch); + return isInMilliseconds ? (long)ts.TotalMilliseconds : (long)ts.TotalSeconds; + } + + [DebuggerStepThrough] + public static DateTimeOffset StartOfDay(this DateTimeOffset dateTime) => new(dateTime.Year, dateTime.Month, dateTime.Day, 0, 0, 0, 0, dateTime.Offset); + [DebuggerStepThrough] + public static DateTimeOffset EndOfDay(this DateTimeOffset dateTime) => dateTime.StartOfDay().AddDays(1); + [DebuggerStepThrough] + public static DateTimeOffset StartOfMonth(this DateTimeOffset dateTime) => new(dateTime.Year, dateTime.Month, 1, 0, 0, 0, 0, dateTime.Offset); + [DebuggerStepThrough] + public static DateTimeOffset EndOfMonth(this DateTimeOffset dateTime) => dateTime.StartOfMonth().AddMonths(1); + [DebuggerStepThrough] + public static DateTimeOffset StartOfYear(this DateTimeOffset dateTime) => new(dateTime.Year, 1, 1, 0, 0, 0, 0, dateTime.Offset); + [DebuggerStepThrough] + public static DateTimeOffset EndOfYear(this DateTimeOffset dateTime) => dateTime.StartOfYear().AddYears(1); +} diff --git a/src/Sa/Extensions/EnumerableExtensions.cs b/src/Sa/Extensions/EnumerableExtensions.cs new file mode 100644 index 0000000..94ddd21 --- /dev/null +++ b/src/Sa/Extensions/EnumerableExtensions.cs @@ -0,0 +1,29 @@ +using System.Diagnostics; + +namespace Sa.Extensions; + + +public static class EnumerableExtensions +{ + [DebuggerStepThrough] + public static string JoinByString(this IEnumerable source, string? joinWith = null) + { + if (source == null) return default!; + return string.Join(joinWith, source); + } + + [DebuggerStepThrough] + public static string JoinByString(this IEnumerable source, Func map, string? joinWith = null) + { + if (source == null) return default!; + return string.Join(joinWith, source.Select(map)); + } + + [DebuggerStepThrough] + public static string JoinByString(this IEnumerable source, Func map, string? joinWith = null) + { + if (source == null) return default!; + return string.Join(joinWith, source.Select(map)); + } +} + diff --git a/src/Sa/Extensions/ExceptionExtensions.cs b/src/Sa/Extensions/ExceptionExtensions.cs new file mode 100644 index 0000000..015e4bf --- /dev/null +++ b/src/Sa/Extensions/ExceptionExtensions.cs @@ -0,0 +1,33 @@ +using System.Diagnostics; +using System.Text; + +namespace Sa.Extensions; + +public static class ExceptionExtensions +{ + [DebuggerStepThrough] + public static bool IsCritical(this Exception ex) + { + if (ex is OutOfMemoryException) return true; + if (ex is StackOverflowException) return true; + if (ex is AppDomainUnloadedException) return true; + if (ex is BadImageFormatException) return true; + if (ex is CannotUnloadAppDomainException) return true; + if (ex is InvalidProgramException) return true; + if (ex is ThreadAbortException) return true; + + return false; + } + + [DebuggerStepThrough] + public static string GetErrorMessages(this Exception exception) + { + StringBuilder sb = new(); + sb.AppendLine(exception.Message); + if (exception.InnerException != null) + { + sb.AppendLine(GetErrorMessages(exception.InnerException)); + } + return sb.ToString(); + } +} diff --git a/src/Sa/Extensions/JsonExtensions.cs b/src/Sa/Extensions/JsonExtensions.cs new file mode 100644 index 0000000..3b93efa --- /dev/null +++ b/src/Sa/Extensions/JsonExtensions.cs @@ -0,0 +1,20 @@ +using System.Diagnostics; +using System.Text.Json; + +namespace Sa.Extensions; + +public static class JsonExtensions +{ + [DebuggerStepThrough] + public static string ToJson(this T value, JsonSerializerOptions? options = null) + { + return JsonSerializer.Serialize(value, options); + } + + + [DebuggerStepThrough] + public static T? FromJson(this string value, JsonSerializerOptions? options = null) + { + return JsonSerializer.Deserialize(value, options); + } +} diff --git a/src/Sa/Extensions/NumericExtensions.cs b/src/Sa/Extensions/NumericExtensions.cs new file mode 100644 index 0000000..a782b7a --- /dev/null +++ b/src/Sa/Extensions/NumericExtensions.cs @@ -0,0 +1,50 @@ +using System.Diagnostics; + +namespace Sa.Extensions; + +public static class NumericExtensions +{ + private static readonly DateTime UnixEpoch = DateTime.UnixEpoch; + private static readonly double MaxUnixSeconds = (DateTime.MaxValue - UnixEpoch).TotalSeconds; + + [DebuggerStepThrough] + public static DateTime ToDateTimeFromUnixTimestamp(this uint timestamp) + => (timestamp > MaxUnixSeconds + ? UnixEpoch.AddMilliseconds(timestamp) + : UnixEpoch.AddSeconds(timestamp)).ToUniversalTime(); + + + [DebuggerStepThrough] + public static DateTime? ToDateTimeFromUnixTimestamp(this string timestampString) + => long.TryParse(timestampString, out var result) ? result.ToDateTimeFromUnixTimestamp() : null; + + [DebuggerStepThrough] + public static DateTime ToDateTimeFromUnixTimestamp(this long timestamp) + => (timestamp > MaxUnixSeconds + ? UnixEpoch.AddMilliseconds(timestamp) + : UnixEpoch.AddSeconds(timestamp)).ToUniversalTime(); + + [DebuggerStepThrough] + public static DateTime ToDateTimeFromUnixTimestamp(this ulong timestamp) + => ToDateTimeFromUnixTimestamp((long)timestamp); + + [DebuggerStepThrough] + public static DateTime ToDateTimeFromUnixTimestamp(this double timestamp) + => ToDateTimeFromUnixTimestamp((long)timestamp); + + [DebuggerStepThrough] + public static DateTime? ToDateTimeFromUnixTimestamp(this long? ts) + => ts.HasValue ? ts.Value.ToDateTimeFromUnixTimestamp() : null; + + [DebuggerStepThrough] + public static DateTime? ToDateTimeFromUnixTimestamp(this ulong? ts) + => ts.HasValue ? ts.Value.ToDateTimeFromUnixTimestamp() : null; + + [DebuggerStepThrough] + public static DateTime? ToDateTimeFromUnixTimestamp(this double? ts) + => ts.HasValue ? ts.Value.ToDateTimeFromUnixTimestamp() : null; + + [DebuggerStepThrough] + public static DateTimeOffset ToDateTimeOffsetFromUnixTimestamp(this long timestamp) + => ToDateTimeFromUnixTimestamp(timestamp); +} diff --git a/src/Sa/Extensions/SpanExtensions.cs b/src/Sa/Extensions/SpanExtensions.cs new file mode 100644 index 0000000..5437b09 --- /dev/null +++ b/src/Sa/Extensions/SpanExtensions.cs @@ -0,0 +1,126 @@ +using System.Diagnostics; + +namespace Sa.Extensions; + +public static class SpanExtensions +{ + + [DebuggerStepThrough] + public static int Count(this Span items, Func func) + { + int count = 0; + foreach (T message in items) + { + if (func(message)) count++; + } + + return count; + } + + [DebuggerStepThrough] + public static IEnumerable> GetChunks(this Memory arr, int chunkSize) + { + for (int i = 0; i < arr.Length; i += chunkSize) + { + // by slice + Memory chunk = arr[i..Math.Min(i + chunkSize, arr.Length)]; + yield return chunk; + } + } + + /// + /// Combines Select and Where with indexes into a single call for optimal + /// performance. + /// + /// + /// The input sequence to filter and select + /// The transformation with index to apply before filtering. + /// The predicate with index with which to filter result. + /// A sequence transformed and then filtered by selector and predicate with indexes. + public static TResult[] SelectWhere(this Span source, Func selector, Func? predicate = null) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + + + TResult[] result = new TResult[source.Length]; + int idx = 0; + for (int i = 0; i < source.Length; i++) + { + TResult? s = selector(source[i], i); + if (predicate == null || predicate(s, i)) + { + result[idx] = s; + idx++; + } + } + Array.Resize(ref result, idx); + return result; + } + + /// + /// + /// + public static TResult[] SelectWhere(this Span source, Func selector, Func? predicate = null) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + + + TResult[] result = new TResult[source.Length]; + int idx = 0; + for (int i = 0; i < source.Length; i++) + { + TResult? s = selector(source[i]); + if (predicate == null || predicate(s)) + { + result[idx] = s; + idx++; + } + } + Array.Resize(ref result, idx); + return result; + } + + + public static TResult[] SelectWhere(this ReadOnlySpan source, Func selector, Func? predicate = null) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + + + TResult[] result = new TResult[source.Length]; + int idx = 0; + for (int i = 0; i < source.Length; i++) + { + TResult? s = selector(source[i], i); + if (predicate == null || predicate(s, i)) + { + result[idx] = s; + idx++; + } + } + Array.Resize(ref result, idx); + return result; + } + + /// + /// + /// + public static TResult[] SelectWhere(this ReadOnlySpan source, Func selector, Func? predicate = null) + { + if (source == null) throw new ArgumentNullException(nameof(source)); + + + TResult[] result = new TResult[source.Length]; + int idx = 0; + for (int i = 0; i < source.Length; i++) + { + TResult? s = selector(source[i]); + if (predicate == null || predicate(s)) + { + result[idx] = s; + idx++; + } + } + Array.Resize(ref result, idx); + return result; + } +} \ No newline at end of file diff --git a/src/Sa/Extensions/StrToExtensions.cs b/src/Sa/Extensions/StrToExtensions.cs new file mode 100644 index 0000000..28c9bb8 --- /dev/null +++ b/src/Sa/Extensions/StrToExtensions.cs @@ -0,0 +1,158 @@ +using System.Diagnostics; +using System.Globalization; +using System.Text; + +namespace Sa.Extensions; + +public static class StrToExtensions +{ + + [DebuggerStepThrough] + public static bool? StrToBool(this string? str) => bool.TryParse(str, out bool result) ? result : null; + + [DebuggerStepThrough] + public static bool? StrToBool(this ReadOnlySpan str) => bool.TryParse(str, out bool result) ? result : null; + + + [DebuggerStepThrough] + public static int? StrToInt(this string? str) => int.TryParse(str, out int result) ? result : null; + [DebuggerStepThrough] + public static int? StrToInt(this ReadOnlySpan str) => int.TryParse(str, out int result) ? result : null; + + + [DebuggerStepThrough] + public static short? StrToShort(this string? str) => short.TryParse(str, out short result) ? result : null; + [DebuggerStepThrough] + public static short? StrToShort(this ReadOnlySpan str) => short.TryParse(str, out short result) ? result : null; + + + [DebuggerStepThrough] + public static ushort? StrToUShort(this string? str) => ushort.TryParse(str, out ushort result) ? result : null; + + [DebuggerStepThrough] + public static ushort? StrToUShort(this ReadOnlySpan str) => ushort.TryParse(str, out ushort result) ? result : null; + + + [DebuggerStepThrough] + public static long? StrToLong(this string? str) => long.TryParse(str, out long result) ? result : null; + [DebuggerStepThrough] + public static long? StrToLong(this ReadOnlySpan str) => long.TryParse(str, out long result) ? result : null; + + + [DebuggerStepThrough] + public static ulong? StrToULong(this string? str) => ulong.TryParse(str, out ulong result) ? result : null; + + [DebuggerStepThrough] + public static ulong? StrToULong(this ReadOnlySpan str) => ulong.TryParse(str, out ulong result) ? result : null; + + + [DebuggerStepThrough] + public static byte[] StrToBytes(this string str, Encoding? encoding = null) => (encoding ?? Encoding.UTF8).GetBytes(str); + + + [DebuggerStepThrough] + public static Guid? StrToGuid(this string? str) => Guid.TryParse(str, out Guid result) ? result : null; + [DebuggerStepThrough] + public static Guid? StrToGuid(this ReadOnlySpan str) => Guid.TryParse(str, out Guid result) ? result : null; + + + [DebuggerStepThrough] + public static T StrToEnum(this string? str, T defaultValue) where T : struct => (Enum.TryParse(str, true, out T result)) ? result : defaultValue; + + + [DebuggerStepThrough] + public static DateTime? StrToDate(this string? str, IFormatProvider? provider = null, DateTimeStyles style = DateTimeStyles.None) + => DateTime.TryParseExact(str, DateFmt.Formats, provider ?? CultureInfo.InvariantCulture, style, out DateTime result) + ? result + : null; + + [DebuggerStepThrough] + public static DateTime? StrToDate(this ReadOnlySpan str, IFormatProvider? provider = null, DateTimeStyles style = DateTimeStyles.None) + => DateTime.TryParseExact(str, DateFmt.Formats, provider ?? CultureInfo.InvariantCulture, style, out DateTime result) + ? result + : null; + +} + +#region Date Fmts +static class DateFmt +{ + public static readonly string[] Formats = + [ + "yyyyMMdd", + "dd.MM.yyyy", + "dd-MM-yyyy", + "yyyy-MM-dd", + "MM/dd/yyyy HH:mm:ss", + "MM/dd/yyyy", + "dd.MM.yy", + "yyyy-MM-dd HH:mm", + "yyyy-MM-dd HH:mm:ss", + "dd.MM.yyyy HH:mm", + "dd-MM-yyyy HH:mm", + "yyyy-MM-ddTHH:mm:ss", + "dd.MM.yyyy HH:mm:ss", + "yyyy-MM-ddK", + "yyyyMMddK", + "yyyy-MM-ddTHH:mm:ss.fffffffK", + "yyyyMMddTHH:mm:ss.fffffffK", + "yyyy-MM-ddTHH:mm:ss,fffffffK", + "yyyyMMddTHH:mm:ss,fffffffK", + "yyyy-MM-ddTHH:mm:ss.ffffffK", + "yyyyMMddTHH:mm:ss.ffffffK", + "yyyy-MM-ddTHH:mm:ss,ffffffK", + "yyyyMMddTHH:mm:ss,ffffffK", + "yyyy-MM-ddTHH:mm:ss.fffffK", + "yyyyMMddTHH:mm:ss.fffffK", + "yyyy-MM-ddTHH:mm:ss,fffffK", + "yyyyMMddTHH:mm:ss,fffffK", + "yyyy-MM-ddTHH:mm:ss.ffffK", + "yyyyMMddTHH:mm:ss.ffffK", + "yyyy-MM-ddTHH:mm:ss,ffffK", + "yyyyMMddTHH:mm:ss,ffffK", + "yyyy-MM-ddTHH:mm:ss.fffK", + "yyyyMMddTHH:mm:ss.fffK", + "yyyy-MM-ddTHH:mm:ss.ffK", + "yyyyMMddTHH:mm:ss.ffK", + "yyyy-MM-ddTHH:mm:ss,ffK", + "yyyyMMddTHH:mm:ss,ffK", + "yyyy-MM-ddTHH:mm:ss.fK", + "yyyyMMddTHH:mm:ss.fK", + "yyyy-MM-ddTHH:mm:ss,fK", + "yyyyMMddTHH:mm:ss,fK", + "yyyy-MM-ddTHH:mm:ssK", + "yyyyMMddTHH:mm:ssK", + "yyyy-MM-ddTHHmmss.fffffffK", + "yyyyMMddTHHmmss.fffffffK", + "yyyy-MM-ddTHHmmss,fffffffK", + "yyyyMMddTHHmmss,fffffffK", + "yyyy-MM-ddTHHmmss.ffffffK", + "yyyyMMddTHHmmss.ffffffK", + "yyyy-MM-ddTHHmmss,ffffffK", + "yyyyMMddTHHmmss,ffffffK", + "yyyy-MM-ddTHHmmss.fffffK", + "yyyyMMddTHHmmss.fffffK", + "yyyy-MM-ddTHHmmss,fffffK", + "yyyyMMddTHHmmss,fffffK", + "yyyy-MM-ddTHHmmss.ffffK", + "yyyyMMddTHHmmss.ffffK", + "yyyy-MM-ddTHHmmss,ffffK", + "yyyyMMddTHHmmss,ffffK", + "yyyy-MM-ddTHHmmss.ffK", + "yyyyMMddTHHmmss.ffK", + "yyyy-MM-ddTHHmmss,ffK", + "yyyyMMddTHHmmss,ffK", + "yyyy-MM-ddTHHmmss.fK", + "yyyyMMddTHHmmss.fK", + "yyyy-MM-ddTHHmmss,fK", + "yyyyMMddTHHmmss,fK", + "yyyy-MM-ddTHHmmssK", + "yyyyMMddTHHmmssK", + "yyyy-MM-ddTHH:mmK", + "yyyyMMddTHH:mmK", + "yyyy-MM-ddTHHK", + "yyyyMMddTHHK", + "o" + ]; +} +#endregion \ No newline at end of file diff --git a/src/Sa/Extensions/StringExtensions.cs b/src/Sa/Extensions/StringExtensions.cs new file mode 100644 index 0000000..040dc4d --- /dev/null +++ b/src/Sa/Extensions/StringExtensions.cs @@ -0,0 +1,14 @@ +using Sa.Classes; +using System.Diagnostics; + +namespace Sa.Extensions; + +public static class StringExtensions +{ + [DebuggerStepThrough] + public static string? NullIfEmpty(this string? str) => string.IsNullOrWhiteSpace(str) ? default : str; + + + [DebuggerStepThrough] + public static uint GetMurmurHash3(this string str, uint seed = 0) => MurmurHash3.Hash32(str.StrToBytes(), seed); +} diff --git a/src/Sa/GlobalSuppressions.cs b/src/Sa/GlobalSuppressions.cs new file mode 100644 index 0000000..36a73cd --- /dev/null +++ b/src/Sa/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Minor Code Smell", "S3267:Loops should be simplified with \"LINQ\" expressions", Justification = "")] diff --git a/src/Sa/Host/InstanceIdProvider.cs b/src/Sa/Host/InstanceIdProvider.cs new file mode 100644 index 0000000..614e2be --- /dev/null +++ b/src/Sa/Host/InstanceIdProvider.cs @@ -0,0 +1,16 @@ +namespace Sa.Host; + + +public interface IInstanceIdProvider +{ + string GetInstanceId(); +} + + + +public class DefaultInstanceIdProvider : IInstanceIdProvider +{ + private readonly string _instanceId = $"{Environment.MachineName}-{Guid.NewGuid():N}"; + + public string GetInstanceId() => _instanceId; +} diff --git a/src/Sa/Host/MessageTypeResolver/AssemblyQualifiedNameMessageTypeResolver.cs b/src/Sa/Host/MessageTypeResolver/AssemblyQualifiedNameMessageTypeResolver.cs new file mode 100644 index 0000000..73ceb3d --- /dev/null +++ b/src/Sa/Host/MessageTypeResolver/AssemblyQualifiedNameMessageTypeResolver.cs @@ -0,0 +1,71 @@ +namespace Sa.Host.MessageTypeResolver; + +using System.Collections.Concurrent; +using System.Text.RegularExpressions; + +/// +/// that uses the for the message type string passed in the message header. +/// +public class AssemblyQualifiedNameMessageTypeResolver : IMessageTypeResolver +{ + private static readonly Regex s_RedundantAssemblyTokens = new(@"\, (Version|Culture|PublicKeyToken)\=([\w\d.]+)", RegexOptions.None, TimeSpan.FromSeconds(2)); + + /// + /// Determines whether to emit the Version, Culture and PublicKeyToken along with the Assembly name (for strong assembly naming). + /// + public bool EmitAssemblyStrongName { get; set; } = false; + + private readonly ConcurrentDictionary _toNameCache = []; + private readonly ConcurrentDictionary _toTypeCache = []; + + + + private string ToNameInternal(Type messageType) + { + string assemblyQualifiedName = messageType?.AssemblyQualifiedName ?? throw new ArgumentNullException(nameof(messageType)); + + if (EmitAssemblyStrongName) + { + return assemblyQualifiedName; + } + + var reducedName = s_RedundantAssemblyTokens.Replace(assemblyQualifiedName, string.Empty); + + return reducedName; + } + + private static Type ToTypeInternal(string name) + => Type.GetType(name ?? throw new ArgumentNullException(nameof(name))) ?? throw new ArgumentException(null, nameof(name)); + + public string ToName(Type messageType) + { + if (!_toNameCache.TryGetValue(messageType, out _)) + { + string typeName = ToNameInternal(messageType); + + if (_toNameCache.TryAdd(messageType, typeName)) + { + _toTypeCache.TryAdd(typeName, messageType); + } + } + + return _toNameCache.GetValueOrDefault(messageType) ?? throw new ArgumentException(null, nameof(messageType)); + } + + public Type ToType(string name) + { + if (!_toTypeCache.TryGetValue(name, out _)) + { + Type? messageType = ToTypeInternal(name); + + if (_toTypeCache.TryAdd(name, messageType)) + { + _toNameCache.TryAdd(messageType, name); + } + + return messageType; + } + + return _toTypeCache.GetValueOrDefault(name) ?? throw new ArgumentException(null, nameof(name)); + } +} \ No newline at end of file diff --git a/src/Sa/Host/MessageTypeResolver/IMessageTypeResolver.cs b/src/Sa/Host/MessageTypeResolver/IMessageTypeResolver.cs new file mode 100644 index 0000000..0d2c891 --- /dev/null +++ b/src/Sa/Host/MessageTypeResolver/IMessageTypeResolver.cs @@ -0,0 +1,8 @@ +namespace Sa.Host.MessageTypeResolver; + +public interface IMessageTypeResolver +{ + Type? ToType(string name); + string ToName(Type messageType); + string ToName() => ToName(typeof(T)); +} diff --git a/src/Sa/Infrastructure/IHasId.cs b/src/Sa/Infrastructure/IHasId.cs new file mode 100644 index 0000000..bb8c848 --- /dev/null +++ b/src/Sa/Infrastructure/IHasId.cs @@ -0,0 +1,12 @@ +namespace Sa.Infrastructure; + + +public interface IHasId +{ + object Id { get; } +} + +public interface IHasId +{ + T Id { get; } +} diff --git a/src/Sa/Sa.csproj b/src/Sa/Sa.csproj new file mode 100644 index 0000000..c508489 --- /dev/null +++ b/src/Sa/Sa.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + enable + enable + + + + + + + + + diff --git a/src/Sa/Serialization/Converter/ObjectToInferredTypesConverter.cs b/src/Sa/Serialization/Converter/ObjectToInferredTypesConverter.cs new file mode 100644 index 0000000..1a449e0 --- /dev/null +++ b/src/Sa/Serialization/Converter/ObjectToInferredTypesConverter.cs @@ -0,0 +1,42 @@ +namespace Sa.Serialization.Converter; + +using System.Text.Json; +using System.Text.Json.Serialization; + +/// +/// Converter that infers object to primitive types. See +/// +/// +public class ObjectToInferredTypesConverter : JsonConverter +{ + public override object? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + => ReadValue(ref reader, options); + + + private static object? ReadValue(ref Utf8JsonReader reader, JsonSerializerOptions options) => + reader.TokenType switch + { + JsonTokenType.Null => null, + JsonTokenType.True => true, + JsonTokenType.False => false, + JsonTokenType.Number when reader.TryGetInt64(out var l) => l, + JsonTokenType.Number => reader.GetDouble(), + JsonTokenType.String when reader.TryGetDateTime(out var datetime) => datetime, + JsonTokenType.String => reader.GetString()!, + JsonTokenType.StartArray => ParseList(ref reader, options), + _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() + }; + + private static List ParseList(ref Utf8JsonReader reader, JsonSerializerOptions options) + { + List list = []; + while (reader.Read() && reader.TokenType != JsonTokenType.EndArray) + { + list.Add(ReadValue(ref reader, options)); + } + return list; + } + + public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options) => + JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options); +} \ No newline at end of file diff --git a/src/Sa/Setup.cs b/src/Sa/Setup.cs new file mode 100644 index 0000000..53b4eaf --- /dev/null +++ b/src/Sa/Setup.cs @@ -0,0 +1,28 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.ObjectPool; +using Microsoft.IO; +using Sa.Classes; +using Sa.Host; +using Sa.Host.MessageTypeResolver; +using Sa.Timing.Providers; + +namespace Sa; + +public static class Setup +{ + public static IServiceCollection AddSaInfrastructure(this IServiceCollection services) + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + + services.TryAddSingleton(); + + + services.TryAddSingleton(); + services.TryAddSingleton(typeof(IArrayPooler<>), typeof(ArrayPooler<>)); + return services; + } +} diff --git a/src/Sa/Timing/Providers/CurrentTimeProvider.cs b/src/Sa/Timing/Providers/CurrentTimeProvider.cs new file mode 100644 index 0000000..1245d90 --- /dev/null +++ b/src/Sa/Timing/Providers/CurrentTimeProvider.cs @@ -0,0 +1,11 @@ +using System.Diagnostics; + +namespace Sa.Timing.Providers; + +public class CurrentTimeProvider : ICurrentTimeProvider +{ + [DebuggerStepThrough] + public DateTimeOffset GetUtcNow() => DateTimeOffset.UtcNow; + + public override string ToString() => $"current time: {GetUtcNow()}"; +} diff --git a/src/Sa/Timing/Providers/ICurrentTimeProvider.cs b/src/Sa/Timing/Providers/ICurrentTimeProvider.cs new file mode 100644 index 0000000..f9472f3 --- /dev/null +++ b/src/Sa/Timing/Providers/ICurrentTimeProvider.cs @@ -0,0 +1,6 @@ +namespace Sa.Timing.Providers; + +public interface ICurrentTimeProvider +{ + DateTimeOffset GetUtcNow(); +} diff --git a/src/Samples/Schedule.Console/GlobalSuppressions.cs b/src/Samples/Schedule.Console/GlobalSuppressions.cs new file mode 100644 index 0000000..c47cb56 --- /dev/null +++ b/src/Samples/Schedule.Console/GlobalSuppressions.cs @@ -0,0 +1,9 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Major Code Smell", "S1118:Utility classes should not have public constructors", Justification = "")] +[assembly: SuppressMessage("Major Bug", "S3903:Types should be defined in named namespaces", Justification = "")] diff --git a/src/Samples/Schedule.Console/Program.cs b/src/Samples/Schedule.Console/Program.cs new file mode 100644 index 0000000..555069d --- /dev/null +++ b/src/Samples/Schedule.Console/Program.cs @@ -0,0 +1,109 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Sa.Schedule; +using Sa.Timing.Providers; +using Schedule.Console; + +internal class Program +{ + static async Task Main() + { + Console.Write("As host service (Y/n): "); + + bool isHostService = Console.ReadKey().Key == ConsoleKey.Y; + + Console.WriteLine(); + + // default configure... + IHostBuilder builder = Host.CreateDefaultBuilder(); + + builder.ConfigureServices(services => + { + services.AddSchedule(builder => + { + if (isHostService) builder.UseHostedService(); + + builder.AddJob() + .WithContextStackSize(3) + .EverySeconds(2) + .WithName("Some 2") + .ConfigureErrorHandling(c => c.IfErrorRetry(2).ThenStopJob()) + ; + + builder.AddInterceptor(); + }); + + services.AddLogging(builder => builder.AddConsole()); + }); + + builder.UseConsoleLifetime(); + + var host = builder.Build(); + + var controller = host.Services.GetRequiredService(); + + + if (isHostService) + { + _ = host.RunAsync(); + } + else + { + var cts = new CancellationTokenSource(); + controller.Start(cts.Token); + + _ = Task.Run(async () => + { + await Task.Delay(30000); + await cts.CancelAsync(); + cts.Dispose(); + Console.WriteLine($"cancelled on timeout"); + }); + } + + _ = Task.Run(async () => + { + await Task.Delay(5000); + await controller.Stop(); + Console.WriteLine($"*** stopped & restart after 2 sec"); + await Task.Delay(2000); + controller.Restart(); + }); + + + IHostApplicationLifetime applicationLifetime = host.Services.GetRequiredService(); + await host.WaitForShutdownAsync(applicationLifetime.ApplicationStopping); + + Console.WriteLine("*** THE END ***"); + } +} + + +namespace Schedule.Console +{ + public class SomeJob(ICurrentTimeProvider currentTime) : IJob + { + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + await Task.Delay(100, cancellationToken); + if (context.NumIterations >= 4 && context.NumIterations < 6) + { + System.Console.WriteLine($"err {context.FailedIterations}"); + throw new ArgumentException("test"); + } + + System.Console.WriteLine($"{currentTime.GetUtcNow()} {context.NumIterations}: {context.JobName}"); + } + } + + public class SomeInterceptor : IJobInterceptor + { + public async Task OnHandle(IJobContext context, Func next, object? key, CancellationToken cancellationToken) + { + System.Console.WriteLine($"<"); + await next(); + System.Console.WriteLine($">"); + } + } +} \ No newline at end of file diff --git a/src/Samples/Schedule.Console/Properties/launchSettings.json b/src/Samples/Schedule.Console/Properties/launchSettings.json new file mode 100644 index 0000000..a6fa13f --- /dev/null +++ b/src/Samples/Schedule.Console/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "Skit.Console": { + "commandName": "Project" + }, + "Container (Dockerfile)": { + "commandName": "Docker" + }, + "WSL": { + "commandName": "WSL2", + "distributionName": "" + } + } +} \ No newline at end of file diff --git a/src/Samples/Schedule.Console/Schedule.Console.csproj b/src/Samples/Schedule.Console/Schedule.Console.csproj new file mode 100644 index 0000000..8e1b33e --- /dev/null +++ b/src/Samples/Schedule.Console/Schedule.Console.csproj @@ -0,0 +1,28 @@ + + + + Exe + net8.0 + enable + enable + true + true + Linux + true + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/src/Samples/Schedule.Console/appsettings.json b/src/Samples/Schedule.Console/appsettings.json new file mode 100644 index 0000000..45fe774 --- /dev/null +++ b/src/Samples/Schedule.Console/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} \ No newline at end of file diff --git a/src/Samples/StateMachine.Console/LongProcess.cs b/src/Samples/StateMachine.Console/LongProcess.cs new file mode 100644 index 0000000..7c8684d --- /dev/null +++ b/src/Samples/StateMachine.Console/LongProcess.cs @@ -0,0 +1,22 @@ +using Sa.StateMachine; + +namespace StateMachine.Console; + +class LongProcess : SmLongProcess +{ + protected override ISmProcessor CreateProcessor() + { + return new MyProcessor(); + } + + class MyProcessor : Processor + { + public async override ValueTask MoveNext(ISmContext context) + { + // some work + await Task.Delay(1000, context.CancellationToken); + System.Console.WriteLine($"process #{context}"); + return await base.MoveNext(context); + } + } +} diff --git a/src/Samples/StateMachine.Console/Program.cs b/src/Samples/StateMachine.Console/Program.cs new file mode 100644 index 0000000..66ca2df --- /dev/null +++ b/src/Samples/StateMachine.Console/Program.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using StateMachine.Console; + + +Console.WriteLine("Hello, World!"); + +LongProcess lp = new(); + +var i = 0; +await foreach (var c in lp) +{ + Console.WriteLine($"{i++}. {c.CurrentState}"); +} + +// default configure... +IHostBuilder builder = Host.CreateDefaultBuilder(); + +builder.ConfigureServices(services => +{ + services.AddLogging(builder => builder.AddConsole()); +}); + +builder.UseConsoleLifetime(); + +var host = builder.Build(); + + +IHostApplicationLifetime applicationLifetime = host.Services.GetRequiredService(); +await host.WaitForShutdownAsync(applicationLifetime.ApplicationStopping); + +Console.WriteLine("*** THE END ***"); diff --git a/src/Samples/StateMachine.Console/StateMachine.Console.csproj b/src/Samples/StateMachine.Console/StateMachine.Console.csproj new file mode 100644 index 0000000..8703ff5 --- /dev/null +++ b/src/Samples/StateMachine.Console/StateMachine.Console.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceCollection.cs b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceCollection.cs new file mode 100644 index 0000000..f7fef5a --- /dev/null +++ b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceCollection.cs @@ -0,0 +1,7 @@ +namespace Sa.Data.PostgreSql.Fixture; + +/// +/// +/// +[CollectionDefinition(nameof(PgDataSourceFixture))] +public class PgDataSourceCollection : ICollectionFixture; diff --git a/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceFixture.cs b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceFixture.cs new file mode 100644 index 0000000..43680a8 --- /dev/null +++ b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PgDataSourceFixture.cs @@ -0,0 +1,38 @@ +namespace Sa.Data.PostgreSql.Fixture; + + +public class PgDataSourceFixture : PostgreSqlFixture + where TSub : notnull +{ + private readonly Lazy _dataSource; + + protected PgDataSourceFixture(PostgreSqlFixtureSettings? settings) + : base(settings ?? PostgreSqlFixtureSettings.Instance) + => _dataSource = new(() + => IPgDataSource.Create(this.ConnectionString)); + + public PgDataSourceFixture() : this(null) { } + + public IPgDataSource DataSource => _dataSource.Value; + + public async override Task DisposeAsync() + { + if (_dataSource.IsValueCreated && _dataSource.Value is IAsyncDisposable disposable) + { + await disposable.DisposeAsync(); + } + + await base.DisposeAsync(); + } + + public async Task CheckTable(string tablename) + { + await DataSource.ExecuteNonQuery($"SELECT '{tablename}'::regclass;"); + } +} + + +public class PgDataSourceFixture : PgDataSourceFixture +{ + +} \ No newline at end of file diff --git a/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixture.cs b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixture.cs new file mode 100644 index 0000000..3c3941e --- /dev/null +++ b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixture.cs @@ -0,0 +1,42 @@ +using Sa.Fixture; +using Testcontainers.PostgreSql; + +namespace Sa.Data.PostgreSql.Fixture; + + +/// +/// +/// +public abstract class PostgreSqlFixture : SaFixture + where TSettings : PostgreSqlFixtureSettings + where TSub : notnull +{ + private readonly PostgreSqlContainer container; + + protected PostgreSqlFixture(TSettings settings) + : base(settings) + { + var builder = new PostgreSqlBuilder() + .WithImage(settings.DockerImage) + ; + + settings.Configure?.Invoke(builder); + container = builder.Build(); + } + + public virtual string ConnectionString => container.GetConnectionString(); + + public string ContainerId => $"{container.Id}"; + + public override async Task InitializeAsync() + { + await base.InitializeAsync(); + await container.StartAsync(); + } + + public override async Task DisposeAsync() + { + await container.DisposeAsync(); + await base.DisposeAsync(); + } +} diff --git a/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixtureSettings.cs b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixtureSettings.cs new file mode 100644 index 0000000..8098ba9 --- /dev/null +++ b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/PostgreSqlFixtureSettings.cs @@ -0,0 +1,11 @@ +using Testcontainers.PostgreSql; + +namespace Sa.Data.PostgreSql.Fixture; + +public record PostgreSqlFixtureSettings +{ + public string DockerImage { get; set; } = "postgres:15-alpine"; + public Action? Configure { get; set; } + + public readonly static PostgreSqlFixtureSettings Instance = new(); +} diff --git a/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/Sa.Data.PostgreSql.Fixture.csproj b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/Sa.Data.PostgreSql.Fixture.csproj new file mode 100644 index 0000000..ffb4708 --- /dev/null +++ b/src/Tests/Fixtures/Sa.Data.PostgreSql.Fixture/Sa.Data.PostgreSql.Fixture.csproj @@ -0,0 +1,16 @@ + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/src/Tests/Fixtures/Sa.Fixture/Sa.Fixture.csproj b/src/Tests/Fixtures/Sa.Fixture/Sa.Fixture.csproj new file mode 100644 index 0000000..0e15e2f --- /dev/null +++ b/src/Tests/Fixtures/Sa.Fixture/Sa.Fixture.csproj @@ -0,0 +1,3 @@ + + + diff --git a/src/Tests/Fixtures/Sa.Fixture/SaFixture.cs b/src/Tests/Fixtures/Sa.Fixture/SaFixture.cs new file mode 100644 index 0000000..015c5a0 --- /dev/null +++ b/src/Tests/Fixtures/Sa.Fixture/SaFixture.cs @@ -0,0 +1,63 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; + +namespace Sa.Fixture; + + +public abstract class SaFixture : IAsyncLifetime +{ + private readonly Lazy _serviceProvider; + + protected IServiceCollection Services { get; } + = new ServiceCollection() + .AddSingleton(typeof(ILogger<>), typeof(NullLogger<>)) + .AddSingleton(); + + protected IConfigurationRoot Configuration { get; } + = new ConfigurationBuilder().AddJsonFile("appsettings.json", true).Build(); + + public Action? SetupServices { get; set; } + + protected SaFixture(TSettings settings) + { + Settings = settings; + _serviceProvider = new Lazy(() => + { + SetupServices?.Invoke(Services, Configuration); + return Services.BuildServiceProvider(); + }); + } + + public TSettings Settings { get; } + + public IServiceProvider ServiceProvider => _serviceProvider.Value; + + public virtual Task InitializeAsync() => Task.CompletedTask; + + public async virtual Task DisposeAsync() + { + if (_serviceProvider.IsValueCreated) await _serviceProvider.Value.DisposeAsync(); + } +} + + +public abstract class SaFixture : SaFixture + where TSub : notnull +{ + private readonly Lazy sub; + + protected SaFixture(TSettings settings) : base(settings) + { + sub = new Lazy(() => ServiceProvider.GetRequiredService()); + } + + public TSub Sub => sub.Value; +} + + +public abstract class SaSubFixture() : SaFixture(new()) + where TSub : notnull +{ +} \ No newline at end of file diff --git a/src/Tests/Host.Test.Properties.xml b/src/Tests/Host.Test.Properties.xml new file mode 100644 index 0000000..1533971 --- /dev/null +++ b/src/Tests/Host.Test.Properties.xml @@ -0,0 +1,34 @@ + + + + + + + net8.0 + enable + enable + + false + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/src/Tests/Sa.Data.PostgreSqlTests/PgDataSourceTests.cs b/src/Tests/Sa.Data.PostgreSqlTests/PgDataSourceTests.cs new file mode 100644 index 0000000..719f009 --- /dev/null +++ b/src/Tests/Sa.Data.PostgreSqlTests/PgDataSourceTests.cs @@ -0,0 +1,68 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql; +using Sa.Data.PostgreSql.Fixture; + +namespace Sa.Data.PostgreSqlTests; + +public class PgDataSourceTests(PgDataSourceFixture fixture) : IClassFixture +{ + [Fact()] + public async Task ExecuteNonQueryTest() + { + const int expected = -1; + var actual = await fixture.DataSource.ExecuteNonQuery("SELECT 2"); + Assert.Equal(expected, actual); + } + + [Fact()] + public async Task ExecuteNonQueryWithParamsTest() + { + const int expected = 1; + var actual = await fixture.DataSource.ExecuteNonQuery(""" + CREATE TABLE IF NOT EXISTS users ( + name text, + age int + ); + + INSERT INTO users (name, age) VALUES (@p1, @p2); + """, + [ + new("p1", "Tom"), + new("p2", 18) + ]) + ; + Assert.Equal(expected, actual); + } + + + [Fact()] + public async Task ExecuteReaderTest() + { + Console.WriteLine(fixture.ConnectionString); + + const int expected = 1; + int actual = 0; + + await fixture.DataSource.ExecuteReader("SELECT 1", (reader, i) => actual = reader.GetInt32(0)); + + Assert.Equal(expected, actual); + } + + + [Fact()] + public async Task DiDataSourceTest() + { + ServiceCollection services = new(); + services.AddPgDataSource(b => b.WithConnectionString(fixture.ConnectionString)); + using var serviceProvider = services.BuildServiceProvider(); + + IPgDataSource dataSource = serviceProvider.GetRequiredService(); + + const int expected = 1; + int actual = 0; + + await dataSource.ExecuteReader("SELECT 1", (reader, i) => actual = reader.GetInt32(0)); + + Assert.Equal(expected, actual); + } +} diff --git a/src/Tests/Sa.Data.PostgreSqlTests/Sa.Data.PostgreSqlTests.csproj b/src/Tests/Sa.Data.PostgreSqlTests/Sa.Data.PostgreSqlTests.csproj new file mode 100644 index 0000000..2988071 --- /dev/null +++ b/src/Tests/Sa.Data.PostgreSqlTests/Sa.Data.PostgreSqlTests.csproj @@ -0,0 +1,14 @@ + + + + + + true + + + + + + + + diff --git a/src/Tests/Sa.MediaTests/Data/m1.wav b/src/Tests/Sa.MediaTests/Data/m1.wav new file mode 100644 index 0000000000000000000000000000000000000000..453a854efec332bee4b087c18257c9da282ae782 GIT binary patch literal 1455404 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%0Ab67Kc`j`VX4I2sN(~_c z^vs5W(cJfjwr*S+s;O2f zl|m(JAf28Hj;fR~<97r<^MFscm@z@UNF78|ohPZQCD(GM7Qa2_{WABRrH2m~<4fAk zV5X{|nViTin0u*Dn9FZ*d@tu;OAX_AewQjyQhBVJ@8yJUsl}DcOiC@+C*1QNf8VFw zXIvwFkT&qv*WkW{wo+kA>O6^mQS66zykZ$sCi9TXZ<^1!T#*B{;<@e#pKme_sb?#B zCvs0VpJSN^!Inz(L^+pQs*p*&GgA#Ikn|;yzmsSqpT3yJfzOCBCURd4eV2Tz7_N)wZ;7pl zFFy&INbW`g-wP@@uIAYeHSMMRA8iFKCx6G&KAsWAA{-zHInFucUFs@I9*fk$Oyf7H zGn>LZ%6uflLmA+8vfv@9EGjjj3iwVkdn89g@>(Q^B#V0lk0v-_sb|)RxeJG4-pF}R zzSs22NFRzAnee`#YK^QpsWT@lRBF*x(XzCVz$>|iKLjCYK?@u)#??VwzkYo5JX;*3m;u+;B zoDo59C4WQOm-=r~`_2`)>BMNI4M%3qi94jPQu|DD+bVe$l^T$#Qo~HLcLaa!jFcs3 z5&3DyUk=iL2`LrjMN~Id0aC9(Nn-JjX^uLs7 zejyS|WL^jEI|8qH(!QXi3-n0Z^JC@J14|_>$02*KBag$GEoZd}jrcJVxC@duSs%7K zt7}_&aV~RDRaAXhpT{=6Y1T)5XqJL*dqGVKC+cPqnll_j4BgzxbXxFB{BTQFXlD zV2smw#xdkV7|HeAtGi);)G~ggzBaaIEHU~M;|cv0_S7JryO?LBVf$QU{wJ!bYCIY* z3T$ats1d3E)VGYQ)g>?&4~+j&qko86W}HXu_z~dz8maGS`(gDc_UAufAA;?w>c|<( zOSQLgxcb$2Tkkfm;r#X4svV~e3?~}+2{zgq!%47f_UaQxnyYt^%Mhd6lflsd`UG$i zc(!qav8gfK?nL!j^G~Zg7p$yaXKrh>wtQWEsx-*h#In6{kMT$29m6~{`y|z~dW~VZ zq0I1W)c`X`>nUd6RIM=c)~RMmhFxZTt9{HCn|)>&ZX9m7h)o#DSey$l9(d-r|+EwA-xzbc)vZUF&d`NF&bq-Kl$8$Dp-Z zt4@`Tb-juON>%rxe$n@8g;kgiu)3+2tNkjkw7+)AZKZTNS#jw*)v3&lI;Wti+Fb>H z%w~`7I;DY&USXN^{dbO+^@aYm2GsjapY_W)IXT)(h;q}zC`Qf|KE zz>jp-9o>G{wzi8|^<&kxip8Acmrc$%2ySwTqO9LnuGss5HaB%+>(hFoMPIJ!rlQz0 zWaWCO&Kbkhxa3UmUeC2L6Vx;Q#O{Xv%HR2w{?5-;Z4Qc19sS?w2JES}m?!I@$g z`UaiLZ(_YRRlnmO9zqS77u4%HZSACDEnTV4k)}IhU%xDFsJ_Z{P~DT>X`ciy^(pc7 z#<}*YJ!@yNLzIs2YpE`V5W@^Ar8<-=^@9EI-`-_j+4vH>;`lP z75FW~I1@0DJov5DPU+!LjsJ~UI(t4nA z`Y`^38Ss)9d3PRmpo1L>^b1F7>)<0>kH7X~V!v-WGuA8GPE|(Pt4Fa0)jZux<>BwJ zVvH|5iCNS#sI0I`z1|NW6Mm#q_zi}DT{7S&S|k2r^j2SRTbrnplf$@oaQ;>){^b?a zaXL?oAsWBvvP5hXVph4(=|g<+9_;%aXvditz&Gsm-{PO`5l-y{?_&LcGsxCc-|YfE zvtz^ya_}e2L?azFCw@SjbRBbigxUsQ!gu-9%lL&{ytnw4vSK(-?M<;>77q>~l~^z_ z=yAjvyog(Ntc4Fal3Fey;PvF22#l_y^zObM(Tmu^AlTln6T&7s)x|e&k)@L%++} zHTS70IFGp7BKYYo>thHpM=P^Ty__=;gTaxFp_Wp2;yz38q5YU&q7P96rvf}jf8rns z@2E!*%h@S83YO6dxtEcpg#v?G(P&)%a{T5U(DNuhbIXj}>u~RCwu6 zZ)`QsG+j+>(T4cjSwpeD$o1WbwOx(j45nwLxYQq?T=64)fN$HwuUMZB0rwNk z`NLk+k+3V!yV2wp)E}9KpUHyu_pm-Dp;y=8OHbhZtPXDY9o(vQ40SbTn^oz5^9yu6 z;@l11<0rlk?kAji zPRH-x5scPtVp>h{CvIXKlkxYtA_E2%;@@LlBB;MH0j%aK&SorOUHpk3>pHcWRznXP zV&e~xO$9NP`gAfiNx+&U;k)|8krE4c}s*B7VRWP+GeTducKoQJ--+pZW>@HJsR=r1KjZ45}S(0UnVuz+Tw$Y zW-Pt&9j`|go@K3;!n-}GhZO}T;574PASTrrzqc2%Y&STU(^Z58xdQvMMcH#LhN|#M8$3lL@W#}5b5re-tXso_Vc^`?{%*G-21MzX3fl+HEY(a znTl(RH&?4)sK@quqF7p|*0wXergaqYR_9uK-Ii^x8a{s1+-JP`(FEn5ZvEkIcDBuZ ze=J|1N!Bm+gRk}S-ga2Fuy_j@_{q|F#m4OY8~E8IkHY)x+}GGoeG;Fz0eoX_WN#nl zn8J^3FaFr4kQML2QPx|&QpbMA#iPv^_Qwx(`B2oi&R9o3drjr8QsPS2ox^?>xu(J>x+u zec~1Klv~O5>Ton)oo&dIpx|V^*2AJkBtTU!Eq~i zowmsw$@Rm|4awR|@X`Q0^NGGO$NJ{}^!NM0ce$C>A?A5^kx!$IBiS$fHrV$q!;9)T z1U|pB#4CA4_hYHqSvwv#&#Xxv47UfpuKnm6;INAGXU>E1df z;;(;`c3wv|-fC`ki@Drr*KfI>_z?r#%iijuImT#x=O;K=0G|Hzk6X>`W0yEg|GGna z-&Ni}bb%lAg~$C)ypqIY*hPE#pu>4)rq{s9LiZ9EuAcVZ=DV(rE%4VNXm*hLD=Tvk z^&SC+o@jD8*ly9jZ`E1DJh!KB6VroLR-48A^8R=hfb4Zm{FLnX{oL=l&h50dtW4}1 z?`~<{xe-si5ANhEy2f{Vp;>?T?s1*i@|m|M=4|XGi3!nKInSzp5jgGx!%<-TQ7IE$ z?+Vu=v~`4bU1vsqJ-D*BdP|TbKFPPrc-qldnS*^hK)Hz{aXwfs^xhEg?T8* zksKq*i&thr$8-8N1=?bQ_^$2hu>RbyPXQ-n-+&1^_+4z1nnRp-GFH`T4 zc{Z=dJI`q6IJlYzjuXJWy*~1Q8e8ahLn`nG#GA

f#zOX0JoxSaj?oE*j9DEYG5h_Rb}Xpe#ARORf0M-J3SR_Px{ zE9+@G{Qm0iru>`8xsQ!AOURJ?9_98MR^6DJ( zh`RhU6RSBng?}&>zl+94)4AJPw@!@a@pRiZn=KQ&XMOQNd8>Pfads-*>=SErA6t`a zN4Bj|#=-ovj;kxC0^gqg*9i8J4egvEQZUR2o()!Pab?kKF7I!8$ zk_o2|p7{no?=bG)h@aczyItXCkny0OzBGr`ZKAR46YHM`_~uglb|D!#+8X73=(9UM z9E=|Z7=zkWtdDMDtIP9vIi33q?{7mcAHv^cs`2(6bB4<5NzQ@f3w+4EarBFx{LKE; zFLpQAc#a-brmm~OTSijo-37{9V7wbfAAA>Yy@ba`!r3p@zOF%!1+I70=F`+O4Q#iVBfLvr zS(JK}{Wu?-+G~~--!wK{hDIyEInWsTmh<_p?{$A9T7RRC-RNkq@?+?WZfC0dTKd8p z*0*=?-miFa5BDC&_fNWhLVxK%7EVTkqqMggz2hV6%EREP3VGCUtys&I>J|>-XZ`ZJ z<;8aNsKel`p>_8vY()2&L;Q*lURU=$_~k$r!gs8H-;3_ox_23!=NY(Is|`Qmi2=@g zl1mTJU6!b4lK%YzigecYq4bH-aFg5ucj}vm`}PZTS;Cgba#V~z;Y9E@fU^bq)v5II z=6v3h*KdV&_I28M6Rx_*-0EKKyi+|RH!hb`VMFnTGL}eV=9Qb|tKoywOIyF8FJG6*&ME%o28uFui$4s)p5bds8AAGsYFxF@)tMyKETGh{t2GVw<8 zX$-v9pxxtzhdj*FXN93^u<5O?Q`*Af4rAi4h{9&6SeOon0?xf7!>px?!c| z#ldvVIpj@EFmC|+m2mYL|D>kM>_DGO+`10rc?VZLiG1P3kc6e@EqIjrn-;YZjQk0NWLK>u9j=f&K@o zV>uYc>x;wa00sQfjgEB!JiX>weSP9&eR?ilT;<-L{1}>$i}x6JCXi3#!1RlLlvrVN z`Io$}{~oSS{{WZ&l8Fz3^(B4wMRI*O`A`o{A0)@0(*AMg*JI#jG#zZ2vFr=&e1YD6 zocgBgpIy;(s6A2@=-ON2)A9K9RC4bR^lE~CH_2zwoQz+@$K#dFmK5i%*(k1SrNS=g zGmMVD6W*JGKL2P>a$Qd_c6_QI3?W-?!ry)Avva_IHywB~x=y#3rn&w%8a`IiN?*5< z^q{_#xZyQD+gzPL(KDtPuTO@9b=vfsa*kBSHybt1!U?@z+d^Kklt=U>3X-{^TE{5K?@9&!Ih_#f%m-I%{G{2$?+d+}!C z+uesQ<7r%tzm@xW_nKN}yu zskFpk*~{1w7$5g+iZSCR<(}f+%lN!9zUk(=2R^#WIP($t^r_$9kc~g;i@7%gy>|xJ z-T3TH?Vk(oH^9+XnPbSKmpscl)D!fKGxbP*C4C+(xbN_JG16_rnZa* z>yDoH_dM%wUn#qnd;2-Y;E$o6ErEm0oufO>bB@k;vTyJ7&H;Wup{(ny@SIM+{0E=* zH#UYoSCDhxD=+yx6Gulx1@gS6wNyGb7~(6L$Tg>{J8|qTasFQUcdBQKwzmcAKFS~C z{e9?-$pyEMd)*yvy^}b7+d8&ZN{8Ui@5Fgbe7#fs?&KW3eqT69{J7}sJ1V1t>&`UV z9h{RBHL-Hqd%vGDlkev+=fjn`2@L=7eh+1D=X!6yw<)jBzEIz8r_7zSt&4MDP0XNO zy_e`Jb)64)j=yPg)utVZy|*QtL|0FYpzf}dgE!s^i6hj}y(2wKMzl`u@9J0&Z#%i) z+;>K0?V-y!vU=JYPh}pI9IacG-?s-33|qOESXRMDOK@ZiZKT|+$0c4~;>zr(%)}_l zTxt(T;`bzOS4-#MwuvLLiaIGfkquK<;+dvjv~nayPjD4|zq#MZ6Pnz+iIvn)eTm=K z*mZIPB@0w%_tUaQ;7*$pfhq9}1N)ZYFYh!4YfCG}TezRthsj}@czKP=-%Ugl`-a_5 z)~>|pY3P2kLN#z?4pY%l&yiK&)kcowKTKT4q)1-OWR**~c{lNs0yoQ|Bk>ahyZGeg z?2mM0q=s>nxehk_{^{;<75tOPF6k z&LuyGczVQtA~E8YmH$s}X0}QtEZ64~X>pY@lXWS64auQa@^46tM{yaz7px`kSo&!4 zdzEqpCZ}SqV`oT~#8U3S_(_DmSp#38>_C?|r^)M8@@FW`<>R{$h(m{DnawO96pcTG z>=B;T@_wRjg;vSR70Al)yExt8NG{$o_%Eutls_!8uoQtY-Xm#KT9Z71%e6i24L2{< zx|A88mFQb(OY9_x?6}0+c{5l|>#Zm#A$iKeF@Y|)Ozt#s6g^Gewhz2F!kw{TOFXvy z)OxtmQbuFvi$HQXznGV-z8|O+``^LXXPaXl_&i->f&B%&tV>PHJkEURb?=RIe$-fc5&dbTHMtgGTWnr+t+Ervw3lZslz*dn z=xL#fb}pp@UZhP=!^P`#x_`a%GX3F8INS)H(>=e<-jjL8@O$Wk!|5xhm$4Oi|3P|B ze`D}2^qt3ywHep1XZLG`=BLt`?o{VDzFX%06KLB(o#&(IiSX8#4%Lv}@E^9t+kD^K z-1Pxtei?iBT+d&C-)&JkIo96w%}lz$7RstbmwK2@`v&&^zHHGi@qeEIuGmsCV~gp0i>Jz)u#)}9y2%C2^oqvTEA1b9oKNy@{AHUe<7WFW&b0p15`AXl ztE1>wd*O*O=+~o(d3FOdGJja3p3CWy+k>G#7`m(aPd^4ObU$u;z3!`^q!+GJik2N@0Kd*l&T8uI4B2nQN}K-ZZPF zoCmG=4_Tjkz&hsX_~#G!OzxqP3ylMO;z!OQBWCis|3{v)Nvn#_TU!~sQmzsFx2V27 zAY0N2+QgUJ9t~@V$(}t<42$E%e!t(|_V3uUYoOU#VtssWExN6}v8OgMFR?~)i5L=h zSK=#g&%;1I@2l8z4q}_R!a8TOdE(&Bs#KV&?)R;2-)b%7R(rGdXJ43U&FGHi;IZEP z$`+Lhr?bbG5Y0nx_D*t z=Xv%;950s2K)AhQ+P}qtQ_*Rbve=;-vBgi@qC(-&E!P!yX|>#b>9xhCauf8`7bciz z++$tp7(8$x+`Wx|pR@k-vAtM*(f>SqN~hX~I>7$yar*fT>mwgoN8MJPZQ1d5C0E|C zU#a$@wZ)xh$eI3+ea2JxNn3krYklQSbBc=A+t;-+zij<)u^WH-OYCnrSq!A-SIJkh zT>dt3gYGm>xoI;owi+%kwr{qvxUvBsx4P_$_M{|^e&UFK$bb56aZGM7cQ{jD?TS7# z_=4|b&)^PIs}+92Ur$f3QFzUI(PH+zZS=bfo9H|3(6f~|!(!1ShUYovm>sMKc4Q;G zY?ZyL?z3NLwRv8Ag1%!ER_`81%I(kA-`swP@5Ix% zX7bA7(UUh6Z=GTPio8YR_+9Ks=FGO&W#6sz?KTw({p-~z3?!GnWS{K0a&_@xd#zU} zFELs^wO09I{k6qo?7i6oKUTGF*2R9%Ni?Wu$=%b<(W_|lp=A6BcGC0hL%!kPdBtNF z&nj-Rj`-d`tBO0|w@>Gr!;n?A!MmMx(3&m8C~qU{CR*NsU!OF0y2X0e;rM%o_3&@3 z@%_yf^Q`r)&BPt)-b6fkYv8@>$XN*Iv((!jpPgy1+b-(tNe+J!n-9KQr<_CVZ|bIh zovZFOGwqjKX#CI*53ncZs|Fj2SG45M(gF|GvsPJIZUyr5Wb*VT{dqC`KL>{ctfQS> z%e+U7h#rmP{ITccirRDeg{)*pn^!EeH|WhZH4B}MB`evw&NPp%XwS^XCGscP57F0t zlOyF{=ri9Qk|lD`djB;0k``H`E^B68rdgH3@B9HCW}DhveNUp<7_w=xx$p7D%V)@f zlhA(eS~N@Y>^XZR?_jH)&(2oaSkv5C_ywEHICh0;;Mi5$7vq_hY8Crq{my>bh-GV8_nSu=lGUWG~QZzGMhXX!WBZ;~6wd$E0YCNn$e z*Pj_r9<}cG1bA*^Z|sMMt_R}<#_tP^!w0ZywMK(y;9?n=3T(ftj03wlcCo+lKK*So z_jmMeV|=rX@$(q?ZA-?iv&J}%EoiiTH(QhG^_}lAHjI+L?kaf**RmC?G)_FiW>MKV zc{d&83-V!S=iAKTcd_pJC7q}R{iVL~wu~+8WwxB=>(>|OvtLYQ^QnY4me6A^vQPVE zygko4ZU;1Pz<##UygRvJzccQ4x9)HW8$nyLrfL)g^SUS6Rkro0N>GIdy!527h`yQx4V-MZRrRL*;Xp(qwU2o7`bkJ@jLYR zoIP%peM^s7cRdT=eGSI<$*&d0&93SwYTushL(7!^D*MK>aCQNDjB>n$my*kII(ySg zZ10GvCketI~$me(1u13Jm*=Y9&Ti~PQ&8{-_y;OQRw$&UB#!i^i*p;nZ~F@8x|tI=eCw0T6_nqTN?*?WEqJl&5sk43}d zoHujt1G?Tx^o!HMy)z!0!Pf91TArnC*>7A1p3(a9FgCF>(P)zPPr}EiTR+*656lbT zd5?W@5*&RBSDT{C>F;~M&+BAtE%tyT(CtU?3=A%;+5QVRzl4wYKun+$o`H7D+4)~2 zPi}>yZ6jCMtiGbJ+(bug!e;d&cz#E#kJ(5b(biM&a$mgMjNW(>nfwn}2Ej)oc)H8_ z^_^gP7;LwYLEGTzFW7Ad)6IS~*2X?^AsiLTX(l%dUcM6?o9XAB>0+;frw9Ce1&)Ww zvf8AF<{v~H$ z2e6)nmKR6%d#?|E`U*_ZgS*q=GskaloT)+A`VyYD#;+sM?FaNZ34T_Kv#}>1+V57I zM_I30Vq9q@#?UHz|0dEOZlYgygQpAWpev0#chf_!MZ3N6%24*<0er-EBNP6?KbL^< z2(-Kc&Rz%KV&{v%HV7S;8$6iZ*Uu(v>kj(Z4PvkF4oBV4Z8lmRVSHY1 z-tdUMklo4HgB;@>J;{Mr*H{8WYh6@9Y+g3h#Tk(YxqK~hp#{M%VWJeo$NS@9GR$X*Mckd_6~gbe!#;E&?dQt zueDF?SbWtL3|F~MZo3}%tqWhi>-;{&So|Qk8t8-1lkI2Vh2yQz?t(Y!p~VzB!G~l* zC1dML_^Xd&f&SJ9ZXSoDH{fjK>S~4O{7yd@Y8_=g9pp&!v$Nt6gB*W$<9(6KcQM~ttpSi5;zzy6%Q*VsIH z2s`~VXgZASUIBk&99J4^hLB~K_x7W4?X>_#TUez+8KP zb)(lJW$6}i~~%n#ES&qc%C!FwxyJQR;@a(|Zb>1Si}GiaKe zEa&Lw7wKEqtLHLf+b;I$-l9LeXD##r__@;We&p4T&PRZ0SL4kZo0S_-8SoFp4Zd2 zU(k=vArA+`U*ga2L8iS-R&Hm$exR}CdgtNh)9t|3(0KEc--8@akbBn~M^84sxAnUo zp3A!EbYpmOt#t!qSMc@L_Ac~?{nXV@n_r_FP6Fc)H2gL3Gw|1i_zZ ze%t2OsD41(=iq-K9vQ6PPhnFz-+EmKYudH4&Y|83)}ihsvu<(!WO~M2w5?!0dXeXs zfU{zSWyPV|bP4_8LbizO={V1T?;J8IJ~q>|{Ytvx%W!wUI(H)9hOS&w+{IjF;4=EZ z9B#YQxela9_vRn@rFmx^?K*&rINO}=!3Of~(4lMan@e7yldOjxg;!tDjzR1V{o$yO zaq%tm9fPhrk;%Jx_cH#J%gpi~DdipWd^~ zfhwcNVb)hKgsXPoim%^D{*j&ec)qF~1H~G6yxRI=JM>#@eA${m@+LAW^Ux{$$_`53 zXJPALop`CZf8!!gV$TtXAmON&c2* zD~r9WR4*LBu5l8-#RKN^yOz`Xe7ew9Wd7sqSm%iic{Klv+5CmCVh3m_Cu~>u?nA%X z=G`xmn+Nm1xC*}vM(2OYz>AEzGqmRi_PQZ>`!znTN6N+g8hyPA-_CEQSc92jEtWt1 zO8WBvHh`Vm@YU>Yy(-u7jXt)_{zWG$u znPk#beQP>(%DL8DbV_S$s9o%s>>&1C9sB0QcNjf`9g59p#^M@sBvdZ^jkf>t zL-~sj?LdB~kMle3&aRW3$jMuOgu14q-LB;OQTp}2#;?v`YQbOg8hxaJ^}!>+bS9mC zf3kgn^{VZ>e=)!6zu1l%OyjcyZ$FspAB%5B(XCEvy1MvWhqcAG#R+Ls-xz5;9mH02 z^R!Z)=ftpl#Tsz&>DWWsUrO{M5!6cAq{xTK{^}8uc&a`qkvYSNugc=bQUH zd(y|`b8_@lH8zjpC%Y9HcPzQv4_>P-X5+B0<6Zmhm+?Wpg>Uxt>_xTpiG^h2RboSp zZ?mr0p^ZL|U$%kc2dB#`4aZ&0m5wtXx|J`_3ixcGu94P_?^gE};?lG-_P2(w?qa9x z@7-GZ-#KC`9cZq6ub5JY8OzQzH%M;Z!OQt^vpcl~WBXO&5SUZm#9w;AN^uz3wRVAv!yC!9*<@|;yxJ>_ zBkPMx%)Lh~o?pC){`nzU*3mnsf$=zd4sK;H+Xh~fbADGk!v5wIf7tVWrMce<@u^=C zFYa>wN*#@@Yqjxc@^CwHXB9d>MRxz!xUiJ2zlE{$3gh~<>;)spsh`B|>18j)^YoJI z;C3^8>uT|aHW`1fwZEZ9GwY{pCpXc@zCg3X7VuMBZcikeRb_h=-ZrP6MHUP-pE_!@ z8in)OLwc!m0vaD|Z~k3y_zK-^I^C|Hv0|7$e2Q^(q%mX!8c#PyEi(Qd%if;VhW6xe zU1R!qG~O3qO$4&e8XO4&pieH8-Vi(wxyx$c!#U!T65;F z`SAC$SEx1p{v5V|iG1LHMB}531E15AzJs45=nRLDLwhQBu5qe0c+RB*d`Iqn$kzOc zxx*Xa+aLbsSi#uRcy^h#Oa^~H{WyN%i^-9z=pi3E#-aNkeD8bc-*e3+o@2M@%Qvl| zIIE56^H1@~StGXFQ|xwc@x}j1dBe1=jW#Cs)gU-~hCQ|topTpF`U+d(Ui9JQ^Qu91 z{EokNr-R&!PY1G%*TD~;%R`m5$W!#+=H@s%^7$S}C%n)YxSw&iD_yib8Z4rVRHP@( zqt^{r=gD9_-de(yzWbBS<~n1}J=%htD=NVwy7@Z0X*Xy&>tRuwNavGc-Qng~?Dfk?%-(29{i)7KQ;CsYe z?m=V9`*fek?#tNPm$9ji($4$9`H^|oNce3`M?IBpcP{>TlpGz(26?rZD5tVT--_2q zlXnGnpl9@xiGIJV-GkBf3p(~Dd^C(cbO*hq3=gz}(-Swdwx@4AZ{9pyER5aY;U&7) zN`0;=-aSh`uG;j$+H~70^sKY^A2dg+?dahz(q#wIt+zB^>rd}ks84m)ADe*h2IF%R z*8|P%2cXGEV0}zXy2lr>wUVLFYu9`BaLq98Z*IT9aQg6P-ap#jf`7>UOX+5((K~Oj zSL$$Mz(#Yn5qRNC_|*ER_igBY$xFNoSa&D0elkD#9ld%O%O|g`P&fr{4;7#HS$%9QJKEjG zzP+|sSvi+#5>Iev>Tgq8;aY)?dH+!g&6QqpSY)m3DT}C#TaH|J2WZGq%Q7Fcj=# z@ZL*!;cKx2Kc_!-Un(E77}Is=C>P_m5&Zlw(?709x82Q=KVh5viu`D*+~@FGd<2%6 ztJOrumg=uzy<|IdKNJi@D%1os-wbo|SB)M2(6uX)PhZo=A2oJ$c1$BrDuHcB<(zIj zI24Ze(~q7;qlb;VWAxEY#(|Oa$XnDs)_h_jclSkv>JM_k9$&EM7 z!Jeg`ttV%`p@%#Qho@>|Gq%VtwR0P7AMW08FyEn^tjzYqtE0j3HXr59$iV~5^)6>O z`ULzV=mQJMwR6m+t6PicM)ua_dwQHXRde(ktj~5Nf6s=8yU6XcjGb9ScpNUyRo{MS zQ3mJZ_0fT7aY%gY@bjVgHFSN=yz~lu+uZdad=wkcB=22ruDim!I~pqzk3D|R=bCSh zA+s+ach80AMSjPJxh9+rq2IiMH)@h`JCdRGUH`+rHOu_rKI2*=yg11k=tpGvGwSNc zKA(0q0&7FCZGx-#H|>b-*H)@on2H}-;>lWI*-F3o6poMf-D%o%IUFw3<_F?IiT)Bg^<1GEB4Y~LlJg=hzjE3vJ;JBEqN872QT62^Q`q$!zVS-F>xElv-`I2ek=8E1;0nZ|GQxN3Cs_(mz+kf zbOYbL+EvT_MUI~2+sj}&&$%Z)Tc$lb&=uF0)(+2x``YqgY=H-kCGU>n({?4>;dr`2ZE*G>?|Q<0eRA$7vgS?v^Q&)mL965= ztEW%RMfbk$RWje-g=8A8zI`)p!Rzf{d)3jLd|)hKFX9vB7>3W^0sGbHv7>dPo8jYQ z{9fPnI9&WQJg-8dKgxN&Qo^;Xv)xX-?eEB$^84fgbVE?oD< z6GhL)I4%Qc1^1e<5pC;S-M#hRpY8o)!T+>-TfxB!aQ4MNL%sh2yZN8)e+U2XlP#zF z-NX0GeRHCIaEI}Ej`n<|?>5GF(FbqG4{O*SULhab;HzuU;&Nk4W&Po2*EehDOf)*z z7;~0y65}HKc1~2^b?6&8J{>;~qw5TCZb9ZX#ZPaMbtf4IcX!Otu9MKIntnf8I}Y{j z2(*p=$8*NRi^-F&`14Tn>Fhh11P=uUpL-YsVIhqG3y?Ebffk(aKs*aIa+_N++&P0@kWX- z(5a4HTwUN8=YCauQITx<91M@ZYt|-K`~8Ze4D8d`gih7ZpK<>Q*C(;X4A&?2H6Pp; z?OsHOM8dfYUcw8L;3YXj`{Mb7^noUH;(O(bx*Wb&xjzLToPoz?dp9ws-o+L=}d`zm;DGDo3;##>J(}Fv1>XNci=SP;NS1Xp#($_C3-ztB=98m%3AKd7THreazYKI_ z-o6i9e~u0h{gM3;_aPkS<`w{@4NTtDf0M?Swh&>MQW zuFDtxecx5omJ#5+9jw_e*U>q-dgI5p5&sHHs(Vod?n2 zez^SzJq|&aJGE&t*#97>enXf2wP&p{?{nivD{Z+sG8r8%^Zrz0%@*1duf_1iVdTi` zjw;&GMSC`(OLcwW3w&Q$-=5(9ANZ}F-|w^khi+@NVI+QgTYGw0^ZXcI_BA#nHc&F) z%_oPle=d7Rp477M=_LhiNp4_4Ecu01wb#(vv;K3tw$#zD=jj83^^ZgKiS3+E(w21@ zx3%SEzYjN_--aIPQ#X6RhBl<0_|>;J2Al+*nc!LsrUT*obN%FW{o@GmALiWBd3X2M zc>bV%avWLk4_NO**Wu24;Q2(8*%qb;vT?rP>MgLo2Jd(AlzRZ3#-Y=2ZA~ubgS6pq zxX+%zd*JnW{9Xx5I1$`WO*vEXdKSHtf?;L4u6{gioD z^kBTQ1fCZA9Xa)m<3mUMRQqVxP&7Nt@AzZJYxF0-enP{d?|uMZ;-ID9j4%#I31cGJ9e( z2PtD8=uRhUXihSayuA_sjq=UcX8dRB8;O7vU-X{Fjs3xryzI~TJp%9i2NjO+?0DBV z!s9r+@Q!N{MfeHvH%F7z;2wk?2jiP(jqC5zp})dMBf)zoIy_#^Q`TF^;6~{9Uq?0N z?B)CGl{Hg+2kDRFwdElE@-Enl?5}Il>0|5jAEVE2a6iX&9dfM&_$%VGkI>~hbUXna z577Pty|bh1tzop#lpGq$Kx72l?Ik_AK>c=WWn=TX@U8J3UL@`LEnFa`7?X2c-Oy{T`t1>}^Xwf5dsXd&Av( z16-dvXU_PJ_lJZ1bZzRat*l*S7XLc*xDfe*+8`d-riAcOt9)(6-umF|mfT58x?p?FNpl{d@q2y`tZ$ z`&M#t3Lfr*FMEOQQ7}EOtU7+ravXz4_aGY=!9~_nlN&bcm&rwZ9(bbhJm8!CmA$R< zwk@aCy5a)-_=o=1P*YfKvEBvZ|{D3dMF*YyI2dctp74X#c{u$u= z8E)FD_fRn3pqz=$+o&fx(nZFr{?2_IyZBwxIelVxkba{*cc|wqWgO|)M|*qWt>o-( z?%YnhYk8-s`-h|374ZAMcK)eenbNIU+LMdN5{KqpI7^QCADqX6zDcFm*rW{3ZCNx*wU{hM!3GGxSkzKRAwV zdX@T*Q~!bLOm6iXQ0;v6?Csp#{f7G7POf_@VI#baRo>gmdt1Hnq5aP9=-lsnHb%Rr zkt6XRU##vG{>)P7Ru#potWmxfqdVO7@cSU`ITS1hI(Bm}*=0L{D|%Y;3|I6!F$U); zJHEe(w----87tK*$GnnLf8yk&AFNdWayTyocP(YrQ*Ud1praiT9sXDLw%XBAdpkI{ za?W0fMt(Q;ypgu@;)9{kCcgcNB}i5~rmJU4`S1AA+asqQS`ElnI@XqdmmLqye4jXb zZIzpR@7cebbCdFCi8d!cPkCM08De2=_q4oJd#C+2Ytf<=$$U)qoeXfGV-6VlX{bjxi(m`qagbrlCk#$-|k$Fsl;2%E&{#+ z>e^gc9UaM6ot*WF4Vt|pwUw5=35!6J*autry{kIvImcf=T4wfxL~bQ|WiYwn z6UQJCE=4RUkJ;GNuk0NPoY}eYr^Cu-xgSka?IWPy`#Mo;A>B^Y-KrL*|QIq+k0o8eTF}gm4AYB4I9q) z6^q68eA^n)Cy!FsVZI-4jqfk8{z}(Am=3Yl+-n3smfn?D*q3Ua%s=3GYf#^4+Z9ze z6kl_GMVtGvL%nTn_Ix_c05<%p+Sico_b%PH1_;-KbBQ_759SMP!1y3N@dYqdQ+HLe z_0V2WpO+~Ae0=a48}GZ;vxeile~hW~98W8MUv%nDSNoS; zx3Be_3*9@<`)BgQ8Nwdg0W8mfsW}~ZsW!d?XBW|@>#(PGG>0ApKQ9{#zr*J>;V`-1 znkn-FwulaFpcj7x7-!E)()`2=yxq18f*S>touu} z@o9Q#_5&?d*VlM5I{uyJuRZbD{p?onu{&gc-dg=~u=6dX$Z2r4132!*OW9{U58aRV z>@{=!)#|(potm(XpTHh85zOcEw`vHsN7WU3M1S}g!w$1XzisN?g~~oto4!+LV}0oG ze1o2E!fj7F^LN@b+WcZ$df#Y$d^d21hJT~yT5Zjq->Ujn1-7Rp+B(|%Z#W*)*6c}* zY^#9YJG<^`?p_tYOvjU3;j6#!`C_)AF=&vz6Nbc#*a^<#{qC$A8xv`xi93q_pkaZ@Jl)gzZ`{M?kAV} zdOx`u?q@eS3v3tbC+qP=Z#3PD{o!tNt&hPsLfnb*>uVM+*4|t6&-mGunMZtQ-t&NW z{$sr*I`dQL_6c5zjd5$X-_6xuK|lFbKOV1*UztbOcl@e-W7M^|b{y=x``vp}zuDgX z#OXiY{R`ZyPA=Z3tf$Pk{^j@dEbnU}Um}BU zaK9sXPxO7}06p>L>z;+S-{QC5$hXC;{`;ywdc$At-++#nxqpy0e}qqJxj$K3Z-Ape z;bbh@o~^9RQFex}_sGI?z>&SvM|!@&yWi{2i}n53w@y&zuK4kA-#0|hMZWKC3|flL zb)0wc-C+26$-B`*E_MGSyfXlu*>1)$okfvMgRGoTWpt}d|T(?k8{C2!Z&Tp>w ztHVL|Wq(30?nNF9#Or4%^EmkZo~-{0FYU*k(@}5PS0B9qPdumY)5zt?+MYai1GH_n zvd$)xepl{2+W3b0cZcJXXdp|;fydFvP6s&=DzWj%djwzG;o;a5=7FKDaxQ|`Vfu0Q zId8wOI4>+%OT?aiDg7seG*Y0S%Ufo$Ux*Gl#duNq! zn&TFDI??@%uMfG-e(dYfXu0oSK%>iP%vZu&{F{z;|8w7;3!dovC#feo%c11dtN7tE z_lJT%mAa>Tcec74`+Yfh zWGkR+h!5cVU$m!-<1Y7Ne@tADUf#b{nQyA=V(os;{r1{)y?b~1ep}Z!EAJRJB_`B! z+SE+F_q$&%Z-clmagM!VXZQDX-iM}|^P#TK z1@m3nbTf$eQAPu8&ED+3%1=yIXrX|*J;l!VBKEbTe&{n^|0`mdOG^u#P`vW z4|LwsAu6+d<^R%iOS*3Q#VPKe?Yxg?nYYANa*KH*MQp89mh>y(M@~#Q2WRJ

Z(LV*9esUg=N`Um<=jAd^^~`@b9?tP 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

  • 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 z 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 y1wdJ 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 z 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%0AN)*xtn>Iqkq4gFd|juX@qD*wXmE&+ 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

    ZA;_33nH5?$9~=hZiOq2c0+E3_7O-a?)^cBxmy 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%0D!Uwka<|IB!O94y0UpM@h<*?L2~O^<^;6 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 + + + + + true + + + + + + + + + + + PreserveNewest + + + + diff --git a/src/Tests/Sa.MediaTests/WavFileTests.cs b/src/Tests/Sa.MediaTests/WavFileTests.cs new file mode 100644 index 0000000..9e68e54 --- /dev/null +++ b/src/Tests/Sa.MediaTests/WavFileTests.cs @@ -0,0 +1,34 @@ +using Sa.Media.Wav; + +namespace Sa.MediaTests; + +public class WavFileTests +{ + [Theory] + [InlineData("Data/m1.wav")] + public void ReadHeaderTest(string filename) + { + using WavFile wavFile = new WavFile() + .WithFileName(filename) + .ReadHeader(); + + Assert.NotNull(wavFile); + Assert.True(wavFile.IsPcmWave); + } + + + [Theory] + [InlineData("Data/m1.wav")] + public void WriteChannelTest(string filename) + { + using WavFile wavFile = new WavFile().WithFileName(filename); + + var file = Path.Combine(Path.GetDirectoryName(filename)!, Path.GetFileNameWithoutExtension(filename) + "_02.wav"); + + long len = wavFile.WriteChannel(file, 1); + + Assert.True(len > 0); + + File.Delete(file); + } +} \ No newline at end of file diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryLongProcessorTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryLongProcessorTests.cs new file mode 100644 index 0000000..1bdef35 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryLongProcessorTests.cs @@ -0,0 +1,68 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Delivery; + +namespace Sa.Outbox.PostgreSqlTests.Delivery; + +public class DeliveryLongProcessorTests(DeliveryLongProcessorTests.Fixture fixture) : IClassFixture +{ + public class TestMessageConsumer : IConsumer + { + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + Console.WriteLine(outboxMessages.Count); + await Task.Delay(1000, cancellationToken); + } + } + + + public class Fixture : OutboxPostgreSqlFixture + { + public Fixture() : base() + { + Services.AddOutbox(builder + => builder + .WithPartitioningSupport((_, sp) + => sp.GetTenantIds = t => Task.FromResult([1, 2]) + ) + .WithDeliveries(builder + => builder.AddDelivery() + ) + ) + ; + } + + public IOutboxMessagePublisher Publisher => ServiceProvider.GetRequiredService(); + } + + + private IDeliveryProcessor Sub => fixture.Sub; + + + [Fact] + public async Task Deliver_LongProcess_MustBe_Work() + { + Console.Write(fixture.ConnectionString); + + List messages = + [ + new TestMessage { PayloadId = "11", Content = "Message 1", TenantId = 1}, + new TestMessage { PayloadId = "12", Content = "Message 2", TenantId = 2} + ]; + + var cnt = await fixture.Publisher.Publish(messages); + Assert.True(cnt > 0); + + var settings = new OutboxDeliverySettings(Guid.NewGuid()) + { + ExtractSettings = + { + LockDuration = TimeSpan.FromMilliseconds(300), + LockRenewal = TimeSpan.FromMilliseconds(100), + ForEachTenant = true, + } + }; + + var result = await Sub.ProcessMessages(settings, CancellationToken.None); + Assert.True(result > 0); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryPermanentErrorTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryPermanentErrorTests.cs new file mode 100644 index 0000000..3d93407 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryPermanentErrorTests.cs @@ -0,0 +1,82 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Delivery; + +namespace Sa.Outbox.PostgreSqlTests.Delivery; + +public class DeliveryPermanentErrorTests(DeliveryPermanentErrorTests.Fixture fixture) : IClassFixture +{ + + public class TestException(string message) : Exception(message) + { + } + + + public class TestMessageConsumer : IConsumer + { + private static readonly TestException s_err = new("test permanent error"); + + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + await Task.Delay(100, cancellationToken); + foreach (IOutboxContext msg in outboxMessages) + { + msg.PermanentError(s_err, "test"); + } + } + } + + + public class Fixture : OutboxPostgreSqlFixture + { + public Fixture() : base() + { + Services + .AddOutbox(builder + => builder.WithPartitioningSupport((_, sp) + => sp.GetTenantIds = t => Task.FromResult([1, 2]) + ) + .WithDeliveries(builder + => builder.AddDelivery() + ) + ); + } + + public IOutboxMessagePublisher Publisher => ServiceProvider.GetRequiredService(); + } + + + private IDeliveryProcessor Sub => fixture.Sub; + + + [Fact] + public async Task Deliver_ErrorProcess_MustBe_Logged() + { + Console.Write(fixture.ConnectionString); + + List messages = + [ + new TestMessage { PayloadId = "11", Content = "Message 1", TenantId = 1}, + new TestMessage { PayloadId = "12", Content = "Message 2", TenantId = 2} + ]; + + var cnt = await fixture.Publisher.Publish(messages); + Assert.True(cnt > 0); + + var settings = new OutboxDeliverySettings(Guid.NewGuid()) + { + ExtractSettings = + { + ForEachTenant = true, + } + }; + + var result = await Sub.ProcessMessages(settings, CancellationToken.None); + + Assert.Equal(0, result); + + + int errCount = await fixture.DataSource.ExecuteReaderFirst("select count(error_id) from outbox__$error"); + + Assert.Equal(1, errCount); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryProcessorTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryProcessorTests.cs new file mode 100644 index 0000000..2a33338 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryProcessorTests.cs @@ -0,0 +1,65 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Delivery; + +namespace Sa.Outbox.PostgreSqlTests.Delivery; + +public class DeliveryProcessorTests(DeliveryProcessorTests.Fixture fixture) : IClassFixture +{ + public class TestMessageConsumer : IConsumer + { + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + Console.WriteLine(outboxMessages.Count); + await Task.Delay(100, cancellationToken); + } + } + + + public class Fixture : OutboxPostgreSqlFixture + { + public Fixture() : base() + { + Services + .AddOutbox(builder + => builder.WithPartitioningSupport((_, ps) + => ps.GetTenantIds = t => Task.FromResult([1, 2]) + ) + .WithDeliveries(builder + => builder.AddDelivery(null, instanceCount: 0) + ) + ); + } + + public IOutboxMessagePublisher Publisher => ServiceProvider.GetRequiredService(); + } + + + private IDeliveryProcessor Sub => fixture.Sub; + + + [Fact] + public async Task Deliver_Process_MustBe_Work() + { + Console.Write(fixture.ConnectionString); + + List messages = + [ + new TestMessage { PayloadId = "11", Content = "Message 1", TenantId = 1}, + new TestMessage { PayloadId = "12", Content = "Message 2", TenantId = 2} + ]; + + var cnt = await fixture.Publisher.Publish(messages); + Assert.True(cnt > 0); + + var settings = new OutboxDeliverySettings(Guid.NewGuid()) + { + ExtractSettings = + { + ForEachTenant = true, + } + }; + + var result = await Sub.ProcessMessages(settings, CancellationToken.None); + Assert.True(result > 0); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryRetryErrorTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryRetryErrorTests.cs new file mode 100644 index 0000000..37bb6f6 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Delivery/DeliveryRetryErrorTests.cs @@ -0,0 +1,101 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Outbox.Delivery; + +namespace Sa.Outbox.PostgreSqlTests.Delivery; + +public class DeliveryRetryErrorTests(DeliveryRetryErrorTests.Fixture fixture) : IClassFixture +{ + + public class TestException(string message) : Exception(message) + { + } + + + public class TestMessageConsumer : IConsumer + { + private static readonly TestException s_err = new("test same error"); + + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + await Task.Delay(100, cancellationToken); + foreach (IOutboxContext msg in outboxMessages) + { + msg.Error(s_err, "test"); + } + } + } + + + public class Fixture : OutboxPostgreSqlFixture + { + public Fixture() : base() + { + Services + .AddOutbox(builder => builder + .WithPartitioningSupport((_, sp) + => sp.GetTenantIds = t => Task.FromResult([1, 2]) + ) + .WithDeliveries(builder + => builder.AddDelivery() + ) + ); + } + + public IOutboxMessagePublisher Publisher => ServiceProvider.GetRequiredService(); + } + + + private IDeliveryProcessor Sub => fixture.Sub; + + + [Fact] + public async Task Deliver_RetriesOnErrorProcess_MustBe_Logged_501() + { + Console.Write(fixture.ConnectionString); + + List messages = [new TestMessage { PayloadId = "11", Content = "Message 1", TenantId = 1 }]; + + ulong cnt = await fixture.Publisher.Publish(messages); + Assert.True(cnt > 0); + + const int MaxDeliveryAttempts = 2; + + var settings = new OutboxDeliverySettings(Guid.NewGuid()) + { + ExtractSettings = + { + ForEachTenant = true, + LockDuration = TimeSpan.FromMilliseconds(0), + LockRenewal = TimeSpan.FromMinutes(10) + }, + ConsumeSettings = + { + MaxDeliveryAttempts = MaxDeliveryAttempts + } + }; + + cnt = 0; + while (cnt < MaxDeliveryAttempts) + { + await Task.Delay(300); + + await Sub.ProcessMessages(settings, CancellationToken.None); + int attempt = await GetDeliveries(); + if (attempt > MaxDeliveryAttempts) + { + cnt++; + } + } + + int errCount = await fixture.DataSource.ExecuteReaderFirst("select count(error_id) from outbox__$error"); + Assert.Equal(1, errCount); + + string delivery_id = await fixture.DataSource.ExecuteReaderFirst("select delivery_id from outbox__$delivery where delivery_status_code = 501"); + Assert.NotEmpty(delivery_id); + + string outbox_delivery_id = await fixture.DataSource.ExecuteReaderFirst("SELECT outbox_delivery_id FROM public.outbox WHERE outbox_delivery_status_code = 501"); + Assert.Equal(delivery_id, outbox_delivery_id); + } + + private Task GetDeliveries() => fixture.DataSource.ExecuteReaderFirst("select count(delivery_id) from outbox__$delivery"); +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxParallelMessagingTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxParallelMessagingTests.cs new file mode 100644 index 0000000..e638ac1 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxParallelMessagingTests.cs @@ -0,0 +1,178 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql.Fixture; +using Sa.Outbox.PostgreSql; +using Sa.Outbox.Support; +using Sa.Partitional.PostgreSql; +using Sa.Schedule; + +namespace Sa.Outbox.PostgreSqlTests; + +public class OutboxParallelMessagingTests(OutboxParallelMessagingTests.Fixture fixture) : IClassFixture +{ + static class GenMessageRange + { + + public const int Threads = 5; + const int From = 100; + const int To = 1000; + + public static int GetMessageCount() => Random.Shared.Next(From, To); + } + + + [OutboxMessage(part: "multi_1")] + public class SomeMessage1 : IOutboxPayloadMessage + { + public string PayloadId { get; set; } = Guid.NewGuid().ToString(); + public int TenantId { get; set; } = Random.Shared.Next(1, 2); + } + + [OutboxMessage(part: "multi_2")] + public class SomeMessage2 : IOutboxPayloadMessage + { + public string PayloadId { get; set; } = Guid.NewGuid().ToString(); + public int TenantId { get; set; } = Random.Shared.Next(1, 2); + } + + + public static class CommonCounter + { + internal static int Counter = 0; + + public static void Add(int count) + { + Interlocked.Add(ref Counter, count); + } + } + + public class SomeMessageConsumer1 : IConsumer + { + public ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + CommonCounter.Add(outboxMessages.Count); + return ValueTask.CompletedTask; + } + } + + + public class SomeMessageConsumer2 : IConsumer + { + public ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + CommonCounter.Add(outboxMessages.Count); + return ValueTask.CompletedTask; + } + } + + public class Fixture : PgDataSourceFixture + { + public Fixture() : base() + { + Services + .AddOutbox(builder => + { + builder + .WithPartitioningSupport((_, sp) => + { + sp.ForEachTenant = true; + sp.GetTenantIds = t => Task.FromResult([1, 2]); + }) + .WithDeliveries(builder => builder + .AddDelivery((_, settings) => + { + settings.ScheduleSettings.ExecutionInterval = TimeSpan.FromMilliseconds(500); + settings.ScheduleSettings.InitialDelay = TimeSpan.Zero; + settings.ExtractSettings.MaxBatchSize = 1024; + }) + .AddDelivery((_, settings) => + { + settings.ScheduleSettings.ExecutionInterval = TimeSpan.FromMilliseconds(500); + settings.ScheduleSettings.InitialDelay = TimeSpan.Zero; + settings.ExtractSettings.MaxBatchSize = 1024; + }) + ); + builder.PublishSettings.MaxBatchSize = 1024; + }) + .AddOutboxUsingPostgreSql(cfg => + { + cfg.AddDataSource(c => c.WithConnectionString(_ => this.ConnectionString)); + cfg.WithPgOutboxSettings((_, settings) => + { + settings.TableSettings.DatabaseSchemaName = "parallel"; + settings.CleanupSettings.DropPartsAfterRetention = TimeSpan.FromDays(1); + }); + }); + } + } + + IServiceProvider ServiceProvider => fixture.ServiceProvider; + + [Fact] + public async Task ParallelMessaging_MustBeProcessed() + { + Console.WriteLine(fixture.ConnectionString); + + // start cron schedules + IScheduler scheduler = ServiceProvider.GetRequiredService(); + int i = scheduler.Start(CancellationToken.None); + Assert.True(i > 0); + + // start delivery message + var publisher = ServiceProvider.GetRequiredService(); + + List> tasks = [ + RunPublish(publisher) + , RunPublish(publisher) + ]; + + + await Task.WhenAll(tasks); + + long total = tasks.Select(c => c.Result) + .DefaultIfEmpty() + .Aggregate((t1, t2) => t1 + t2); + + var migrationService = ServiceProvider.GetRequiredService(); + + bool r = await migrationService.WaitMigration(TimeSpan.FromSeconds(3)); + Assert.True(r, "none migration"); + + // delay for consume + while (CommonCounter.Counter < (int)total) + { + // delay for consume + await Task.Delay(300); + } + + await scheduler.Stop(); + + Assert.True(CommonCounter.Counter > 0); + } + + private static async Task RunPublish(IOutboxMessagePublisher publisher) + where T : IOutboxPayloadMessage, new() + { + long total = 0; + List nodes = Enumerable.Range(1, GenMessageRange.Threads).ToList(); + ParallelLoopResult loop = Parallel.ForEach(nodes, async node => + { + List messages = []; + int messageCount = GenMessageRange.GetMessageCount(); + for (int j = 0; j < messageCount; j++) + { + Interlocked.Increment(ref total); + messages.Add(new T()); + } + + await publisher.Publish(messages); + }); + + + while (!loop.IsCompleted) + { + await Task.Delay(300); + } + + return total; + } +} \ No newline at end of file diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxPostgreSqlFixture.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxPostgreSqlFixture.cs new file mode 100644 index 0000000..5f3287f --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxPostgreSqlFixture.cs @@ -0,0 +1,15 @@ +using Sa.Data.PostgreSql.Fixture; +using Sa.Outbox.PostgreSql; + +namespace Sa.Outbox.PostgreSqlTests; + +public class OutboxPostgreSqlFixture : PgDataSourceFixture + where TSub : notnull +{ + public OutboxPostgreSqlFixture() + { + Services.AddOutboxUsingPostgreSql(builder + => builder.AddDataSource(b + => b.WithConnectionString(sp => ConnectionString))); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxTests.cs new file mode 100644 index 0000000..f239f44 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/OutboxTests.cs @@ -0,0 +1,105 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql.Fixture; +using Sa.Outbox.PostgreSql; +using Sa.Outbox.Support; +using Sa.Partitional.PostgreSql; +using Sa.Schedule; + +namespace Sa.Outbox.PostgreSqlTests; + +public class OutBoxTests(OutBoxTests.Fixture fixture) : IClassFixture +{ + + [OutboxMessage(part: "some")] + public class SomeMessage : IOutboxPayloadMessage + { + public string PayloadId { get; set; } = default!; + public int TenantId { get; set; } + } + + public class SomeMessageConsumer : IConsumer + { + internal static int Counter = 0; + + public async ValueTask Consume(IReadOnlyCollection> outboxMessages, CancellationToken cancellationToken) + { + Interlocked.Add(ref Counter, outboxMessages.Count); + await Task.Delay(100, cancellationToken); + } + } + + public class Fixture : PgDataSourceFixture + { + public Fixture() : base() + { + Services + .AddOutbox(builder => builder + .WithPartitioningSupport((_, sp) => + { + sp.ForEachTenant = true; + sp.GetTenantIds = t => Task.FromResult([1, 2]); + }) + .WithDeliveries(builder => builder + .AddDelivery((_, settings) => + { + settings.ScheduleSettings.ExecutionInterval = TimeSpan.FromMilliseconds(100); + settings.ScheduleSettings.InitialDelay = TimeSpan.Zero; + settings.ExtractSettings.MaxBatchSize = 1; + }) + ) + ) + .AddOutboxUsingPostgreSql(cfg => + { + cfg.AddDataSource(c => c.WithConnectionString(_ => this.ConnectionString)); + cfg.WithPgOutboxSettings((_, settings) => + { + settings.TableSettings.DatabaseSchemaName = "test"; + settings.CleanupSettings.DropPartsAfterRetention = TimeSpan.FromDays(1); + }); + }) + ; + } + } + + + IServiceProvider ServiceProvider => fixture.ServiceProvider; + + + [Fact] + public async Task OutBoxTest() + { + Console.WriteLine(fixture.ConnectionString); + + // start cron schedules + var scheduler = ServiceProvider.GetRequiredService(); + int i = scheduler.Start(CancellationToken.None); + Assert.True(i > 0); + + // start delivery message + var publisher = ServiceProvider.GetRequiredService(); + + ulong total = await publisher.Publish([ + new SomeMessage { TenantId = 1 } + , new SomeMessage { TenantId = 1 } + , new SomeMessage { TenantId = 1 } + , new SomeMessage { TenantId = 1 } + ]); + + var migrationService = ServiceProvider.GetRequiredService(); + + bool r = await migrationService.WaitMigration(TimeSpan.FromSeconds(3)); + Assert.True(r, "none migration"); + + // delay for consume + int j = 0; + while (SomeMessageConsumer.Counter < (int)total && j++ < 10) + { + // delay for consume + await Task.Delay(300); + } + + await scheduler.Stop(); + + Assert.True(SomeMessageConsumer.Counter > 0); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Publisher/OutboxPublisherTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Publisher/OutboxPublisherTests.cs new file mode 100644 index 0000000..8cb79c2 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Publisher/OutboxPublisherTests.cs @@ -0,0 +1,34 @@ +namespace Sa.Outbox.PostgreSqlTests.Publisher; + + +public class OutboxPublisherTests(OutboxPublisherTests.Fixture fixture) : IClassFixture +{ + public class Fixture : OutboxPostgreSqlFixture + { + } + + private IOutboxMessagePublisher Sub => fixture.Sub; + + + [Fact] + public async Task Publish_MultipleMessages_ReturnsExpectedResult() + { + Console.Write(fixture.ConnectionString); + + // Arrange + List messages = + [ + new TestMessage { PayloadId = "1", Content = "Message 1", TenantId = 1}, + new TestMessage { PayloadId = "2", Content = "Message 2", TenantId = 2} + ]; + + // Act + ulong result = await Sub.Publish(messages); + + // Assert + Assert.Equal(2, (int)result); + + int count = await fixture.DataSource.ExecuteReaderFirst("select count(*) from outbox"); + Assert.Equal(2, count); + } +} diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Sa.Outbox.PostgreSqlTests.csproj b/src/Tests/Sa.Outbox.PostgreSqlTests/Sa.Outbox.PostgreSqlTests.csproj new file mode 100644 index 0000000..34c5ac6 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Sa.Outbox.PostgreSqlTests.csproj @@ -0,0 +1,16 @@ + + + + + + true + true + 1 + + + + + + + + diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/Serialization/OutboxMessageSerializerTests.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/Serialization/OutboxMessageSerializerTests.cs new file mode 100644 index 0000000..089e206 --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/Serialization/OutboxMessageSerializerTests.cs @@ -0,0 +1,93 @@ +using Sa.Extensions; +using Sa.Fixture; +using Sa.Outbox.PostgreSql.Serialization; +using System.Text.Json; + +namespace Sa.Outbox.PostgreSqlTests.Serialization; + + +public class OutboxMessageSerializerTests(OutboxMessageSerializerTests.Fixture fixture) : IClassFixture +{ + + public class Fixture : SaSubFixture + { + public Fixture() : base() + { + Services.AddOutboxMessageSerializer(new()); + } + } + + + private readonly IOutboxMessageSerializer sub = fixture.Sub; + + + [Fact] + public async Task Serialize_WithValidObject() + { + // Arrange + var obj = new TestMessage { Id = 1, Content = "Test" }; + + using var stream = new MemoryStream(); + // Act + await sub.SerializeAsync(stream, obj); + + // Assert + Assert.True(stream.Length > 0); + } + + [Fact] + public async Task Serialize_WithNullObject_ThrowsArgumentNullException() + { + using var stream = new MemoryStream(); + // Act & Assert + await Assert.ThrowsAsync(() + => sub.SerializeAsync(stream, default!)); + } + + [Fact] + public async Task Deserialize_WithValid_JsonReturnsObject() + { + // Arrange + var json = "{\"Id\":1,\"Content\":\"Test\"}"; + + // Act + using var stream = new MemoryStream(); + stream.Write(json.StrToBytes()); + stream.Position = 0; + + TestMessage? message = await sub.DeserializeAsync(stream); + + // Assert + Assert.NotNull(message); + Assert.Equal(1, message.Id); + Assert.Equal("Test", message.Content); + } + + [Fact] + public async Task Deserialize_WithInvalidJson_ThrowsJsonException() + { + // Arrange + var invalidJson = "invalid json"; + + using var stream = new MemoryStream(); + stream.Write(invalidJson.StrToBytes()); + stream.Position = 0; + + // Act & Assert + await Assert.ThrowsAsync(() => sub.DeserializeAsync(stream)); + } + + [Fact] + public async Task Deserialize_WithNullJson_ThrowsArgumentNullException() + { + // Act & Assert + await Assert.ThrowsAsync(() => sub.DeserializeAsync(default!)); + } + + + private class TestMessage + { + public int Id { get; set; } + public string? Content { get; set; } + } +} \ No newline at end of file diff --git a/src/Tests/Sa.Outbox.PostgreSqlTests/TestMessage.cs b/src/Tests/Sa.Outbox.PostgreSqlTests/TestMessage.cs new file mode 100644 index 0000000..ac5885b --- /dev/null +++ b/src/Tests/Sa.Outbox.PostgreSqlTests/TestMessage.cs @@ -0,0 +1,12 @@ +using Sa.Outbox.Support; + +namespace Sa.Outbox.PostgreSqlTests; + +[OutboxMessage] + +public class TestMessage : IOutboxPayloadMessage +{ + public string PayloadId { get; set; } = default!; + public string? Content { get; set; } + public int TenantId { get; set; } +} \ No newline at end of file diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Cache/PartCacheTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/Cache/PartCacheTests.cs new file mode 100644 index 0000000..398185b --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Cache/PartCacheTests.cs @@ -0,0 +1,169 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Classes; +using Sa.Data.PostgreSql.Fixture; +using Sa.Partitional.PostgreSql; +using Sa.Partitional.PostgreSql.Cache; + +namespace Sa.Partitional.PostgreSqlTests.Cache; + + +public class PartCacheTests(PartCacheTests.Fixture fixture) : IClassFixture +{ + + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_20", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part") + ; + + schema.AddTable("test_21", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part") + ; + + schema.AddTable("test_22", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part") + ; + + + schema.AddTable("test_23", + "id INT NOT NULL" + ) + ; + + schema.AddTable("test_24", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part") + ; + + }); + }) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + ; + } + + public IPartRepository PartRepository => ServiceProvider.GetRequiredService(); + } + + + private IPartCache Sub => fixture.Sub; + + + [Fact] + public async Task InCache_TableNotExists_ReturnsFalse() + { + Console.WriteLine(fixture.ConnectionString); + + bool actual = await Sub.InCache("different_table", DateTimeOffset.Now, ["p1", 145]); + // Assert + Assert.False(actual); + } + + [Fact] + public async Task InCache_PartExistsInCache_ReturnsTrue() + { + var date = DateTimeOffset.Now; + + await fixture.PartRepository.CreatePart("test_20", date, [1, "some"]); + + // Act + bool result = await Sub.InCache("test_20", date, [1, "some"]); + + // Assert + Assert.True(result); + } + + [Fact] + public async Task InCache_DateNotInCache_ReturnsFalse() + { + await fixture.PartRepository.CreatePart("test_21", DateTimeOffset.Now, [1, "some"]); + + // Act + bool result = await Sub.InCache("test_21", DateTimeOffset.Now.AddDays(1), [1, "some"]); + + // Assert + Assert.False(result); + } + + [Fact] + public async Task InCache_EnsureCache_ReturnsTrue() + { + DateTimeOffset date = DateTimeOffset.Now; + StrOrNum[] parValues = [1, "some1"]; + + // Act + bool result = await Sub.InCache("test_22", date, parValues); + + // Assert + Assert.False(result); + + result = await Sub.EnsureCache("test_22", date, parValues); + + Assert.True(result); + + result = await Sub.InCache("test_22", date, parValues); + + Assert.True(result); + } + + [Fact] + public async Task InCache_RemoveCache() + { + DateTimeOffset date = DateTimeOffset.Now; + + bool result = await Sub.EnsureCache("test_23", date, []); + + Assert.True(result); + + await Sub.RemoveCache("test_23"); + + result = await Sub.InCache("test_23", date, []); + + Assert.True(result); + } + + + [Fact] + public async Task InCache_EnsureCache_DifferentParts() + { + DateTimeOffset date = DateTimeOffset.Now; + StrOrNum[] partValues_1 = [1, "some1"]; + StrOrNum[] partValues_2 = [2, "some1"]; + + var result = await Sub.EnsureCache("test_24", date, partValues_1); + + Assert.True(result); + + result = await Sub.InCache("test_24", date, partValues_2); + + Assert.False(result); + + result = await Sub.EnsureCache("test_24", date, partValues_2); + + Assert.True(result); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Cleaning/PartCleanupServiceTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/Cleaning/PartCleanupServiceTests.cs new file mode 100644 index 0000000..f3b871b --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Cleaning/PartCleanupServiceTests.cs @@ -0,0 +1,71 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql.Fixture; +using Sa.Extensions; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests.Cleaning; + +public class PartCleanupServiceTests(PartCleanupServiceTests.Fixture fixture) : IClassFixture +{ + + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_70", + "id INT NOT NULL", + "city TEXT NOT NULL", + "tenant_id INT NOT NULL", + "payload_id TEXT NOT NULL" + ) + .PartByList("tenant_id", "city") + .AddMigration(1, ["New York", "London"]) + .AddMigration(2, ["Moscow", "Kazan", "Yekaterinburg"]) + ; + + }); + }) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + .AddPartCleanupSchedule() + ; + } + } + + + private IPartCleanupService Sub => fixture.Sub; + + private Task> GetParts() + => GetPartRep().GetPartsFromDate("test_70", DateTimeOffset.Now.StartOfDay()); + + private IPartRepository GetPartRep() => fixture.ServiceProvider.GetRequiredService(); + + private async Task MigrateTest() + { + await GetPartRep().Migrate([DateTimeOffset.Now], CancellationToken.None); + } + + [Fact()] + public async Task CleanTest() + { + Console.WriteLine(fixture.ConnectionString); + + await MigrateTest(); + + List list = await GetParts(); + Assert.NotEmpty(list); + + DateTimeOffset toDate = DateTimeOffset.UtcNow.AddDays(1); + + int i = await Sub.Clean(toDate, CancellationToken.None); + Assert.Equal(5, i); + + int expected = list.Count - i; + + list = await GetParts(); + Assert.Equal(expected, list.Count); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/ConfigurationPartTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/ConfigurationPartTests.cs new file mode 100644 index 0000000..b8da7fb --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/ConfigurationPartTests.cs @@ -0,0 +1,67 @@ +using Sa.Fixture; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests.Configuration; + + + + +public class ConfigurationPartTests(ConfigurationPartTests.Fixture fixture) : IClassFixture +{ + public class Fixture : SaSubFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => builder.AddSchema(schema => + { + + schema + .AddTable("test_1", + "part TEXT NOT NULL", + "lock_instance_id TEXT NOT NULL", + "lock_expires_on bigint NOT NULL", + "payload_id TEXT NOT NULL" + ) + .PartByList("part", "lock_instance_id") + .TimestampAs("date") + ; + + schema + .AddTable("test_2", + "name TEXT NOT NULL" + ) + .PartByList("name") + ; + + })); + + Services.AddPartitional((_, builder) => builder.AddSchema(schema => + { + schema + .AddTable("test_3", + "text TEXT NOT NULL" + ) + ; + })); + } + } + + [Fact] + public void PartitionalPostgreSql_SettingsBuiling() + { + ISettingsBuilder builder = fixture.Sub; + ITableSettingsStorage settings = builder.Build(); + Assert.Equal(3, settings.Tables.Count); + } + + [Fact] + public void PartitionalPostgreSql_CheckIdName_Test() + { + ISettingsBuilder builder = fixture.Sub; + ITableSettingsStorage storage = builder.Build(); + ITableSettings? settings = storage.Tables.FirstOrDefault(c => c.FullName == "public.test_1"); + Assert.NotNull(settings); + Assert.NotNull(builder); + Assert.Equal("part", settings.IdFieldName); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/SqlBuilderTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/SqlBuilderTests.cs new file mode 100644 index 0000000..83e3f85 --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Configuration/SqlBuilderTests.cs @@ -0,0 +1,196 @@ +using Sa.Fixture; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests.Configuration; + + + +public class SqlBuilderTests(SqlBuilderTests.Fixture fixture) : IClassFixture +{ + public class Fixture : SaSubFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_0", + "id CHAR(26) NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "part_1 TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part", "part_1") + .TimestampAs("date") + ; + + schema.AddTable("test_1", + "id INT NOT NULL", + "part TEXT NOT NULL", + "tenant_id INT NOT NULL", + "lock_expires_on BIGINT NOT NULL", + "payload_id TEXT NOT NULL" + ) + .PartByList("part", "tenant_id") + .TimestampAs("date") + ; + + schema.AddTable("test_2", + "id INT NOT NULL", + "name TEXT NOT NULL" + ) + .PartByList("name") + ; + + }); + }); + + Services.AddPartitional((_, builder) => + { + builder.AddSchema("public", schema => + { + schema.AddTable("test_3", + "id INT NOT NULL", + "text TEXT NOT NULL" + ); + }); + + builder.AddSchema(schema => + { + schema + .CreateTable("test_4"); + + schema + .AddTable("test_5", + "pk_id INT NOT NULL", + "p0 TEXT NOT NULL", + "p1 TEXT NOT NULL", + "p2 TEXT NOT NULL", + "p3 TEXT NOT NULL", + "p4 TEXT NOT NULL", + "p5 TEXT NOT NULL", + "tid INT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tid", "p0", "p1", "p2", "p3", "p4", "p5") + .TimestampAs("dt") + ; + + }); + }); + } + } + + + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_0() + { + ISqlBuilder sqlbuilder = fixture.Sub; + + ISqlTableBuilder? build = sqlbuilder["public.test_0"]; + Assert.NotNull(build); + + var expected = ("tenant_id", "part", "part_1"); + var actual = + ( + build.Settings.PartByListFieldNames[0], + build.Settings.PartByListFieldNames[1], + build.Settings.PartByListFieldNames[2] + ); + + Assert.Equal(expected, actual); + + string sql = build.CreateSql(DateTimeOffset.Now, 29, "part1", "part2"); + Assert.NotEmpty(sql); + } + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_1() + { + ISqlBuilder sqlbuilder = fixture.Sub; + + ISqlTableBuilder? tblBuilder = sqlbuilder["public.test_1"]; + Assert.NotNull(tblBuilder); + + string sql = tblBuilder.CreateSql(DateTimeOffset.Now, "some", 27); + Assert.NotEmpty(sql); + } + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_2() + { + ISqlBuilder sqlbuilder = fixture.Sub; + ISqlTableBuilder? tblBuilder = sqlbuilder["test_2"]; + + Assert.NotNull(tblBuilder); + + string sql = tblBuilder.CreateSql(DateTimeOffset.Now, "some_2"); + Assert.NotEmpty(sql); + } + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_3() + { + ISqlBuilder sqlbuilder = fixture.Sub; + ISqlTableBuilder? tblBuilder = sqlbuilder["public.test_3"]; + + Assert.NotNull(tblBuilder); + + ISqlTableBuilder? tblBuilder1 = sqlbuilder["public.\"test_3\""]; + + Assert.NotNull(tblBuilder1); + + Assert.Equal(tblBuilder1, tblBuilder); + + var now = DateTimeOffset.Now; + + string sqlTest = tblBuilder.CreateSql(now); + Assert.NotEmpty(sqlTest); + + string sqlTest1 = tblBuilder1.CreateSql(now); + Assert.Equal(sqlTest, sqlTest1); + } + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_4() + { + ISqlBuilder sqlbuilder = fixture.Sub; + + ISqlTableBuilder? builder = sqlbuilder["test_4"]; + Assert.NotNull(builder); + + var now = DateTimeOffset.Now; + string sql = builder.CreateSql(now); + Assert.NotEmpty(sql); + } + + + [Fact] + public void PartitionalPostgreSql_SqlBuiling_Test_5() + { + ISqlBuilder sqlbuilder = fixture.Sub; + + ISqlTableBuilder? builder = sqlbuilder["test_5"]; + + Assert.NotNull(builder); + Assert.Equal(7, builder.Settings.PartByListFieldNames.Length); + + var now = DateTimeOffset.Now; + string sql = builder.CreateSql(now, 7, "s0", "s1", "s2", "s3", "s4", "s5"); + Assert.NotEmpty(sql); + } + + [Fact] + public void PartitionalPostgreSql_CheckIdName_Test() + { + ISqlBuilder sqlbuilder = fixture.Sub; + + ISqlTableBuilder? builder = sqlbuilder["test_5"]; + + Assert.NotNull(builder); + Assert.Equal("pk_id", builder.Settings.IdFieldName); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionAsJobTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionAsJobTests.cs new file mode 100644 index 0000000..7ecf1fa --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionAsJobTests.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.DependencyInjection; +using Sa.Data.PostgreSql.Fixture; +using Sa.Extensions; +using Sa.Partitional.PostgreSql; +using Sa.Schedule; + +namespace Sa.Partitional.PostgreSqlTests; + + +public class PartitionAsJobTests(PartitionAsJobTests.Fixture fixture) : IClassFixture +{ + + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + // Настройка таблицы customers + schema.AddTable("customer", + "id INT NOT NULL", + "country TEXT NOT NULL", + "city TEXT NOT NULL" + ) + // разделить в таблицах меж партиций + .WithPartSeparator("_") + // Партиционирование по country и city (если не задан PartByRange то по дням) + .PartByList("country", "city") + // Миграция партиций каждого тенанта по city + .AddMigration("RU", ["Moscow", "Samara"]) + .AddMigration("USA", ["Alabama", "New York"]) + .AddMigration("FR", ["Paris", "Lyon", "Bordeaux"]); + + }); + } + , asJob: true + ) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + ; + } + } + + + private IPartRepository Sub => fixture.Sub; + + [Fact] + public async Task MigrateAsJobTest() + { + Console.WriteLine(fixture.ConnectionString); + + int i = fixture.ServiceProvider.GetRequiredService().Start(CancellationToken.None); + Assert.True(i > 0); + + Console.WriteLine(fixture.ConnectionString); + await Task.Delay(800); + + var list = await Sub.GetPartsFromDate("customer", DateTimeOffset.Now.StartOfDay()); + Assert.NotEmpty(list); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionIndexTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionIndexTests.cs new file mode 100644 index 0000000..11aa43e --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionIndexTests.cs @@ -0,0 +1,61 @@ +using Sa.Data.PostgreSql.Fixture; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests; + + +public class PartitionIndexTests(PartitionIndexTests.Fixture fixture) : IClassFixture +{ + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_61", + "id INT NOT NULL" + ) + ; + + }); + }) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + ; + } + } + + + private IPartitionManager Sub => fixture.Sub; + + + + [Fact] + public async Task InsertingDoubleParts() + { + Console.WriteLine(fixture.ConnectionString); + + DateTimeOffset today = DateTimeOffset.Now; + DateTimeOffset tomorrow = today.AddDays(1); + + // Act + int i = await Sub.Migrate([today, tomorrow]); + + Assert.Equal(2, i); + + long unixTime = today.ToUnixTimeSeconds(); + + i = await fixture.DataSource.ExecuteNonQuery( +$""" +INSERT INTO test_61 + (id,created_at) +VALUES + (1,{unixTime}), + (1,{unixTime + 1}) +ON CONFLICT DO NOTHING +"""); + + Assert.Equal(2, i); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionManagerTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionManagerTests.cs new file mode 100644 index 0000000..f58c06e --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/PartitionManagerTests.cs @@ -0,0 +1,78 @@ +using Sa.Data.PostgreSql.Fixture; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests; + + +public class PartitionManagerTests(PartitionManagerTests.Fixture fixture) : IClassFixture +{ + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_41", + "id INT NOT NULL", + "gender TEXT NOT NULL", + "tenant_id INT NOT NULL", + "payload_id TEXT NOT NULL" + ) + .WithPartSeparator("_") + .PartByList("tenant_id", "gender") + .AddMigration(1, ["male", "female"]) + .AddMigration(2, "male") + .AddMigration(2, "female") + .PartByRange(PgPartBy.Day, "created_at") + ; + + schema.AddTable("test_empty", + "id INT NOT NULL" + ) + .AddMigration() + // double check + .AddMigration() + ; + }); + }) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + ; + } + } + + + private IPartitionManager Sub => fixture.Sub; + + [Fact] + public async Task MigrateTest() + { + Console.WriteLine(fixture.ConnectionString); + // Act + int i = await Sub.Migrate(); + Assert.True(i > 0); + } + + + [Fact] + public async Task Migrate_WithDates() + { + + DateTimeOffset today = DateTimeOffset.Now.AddDays(7); + DateTimeOffset tomorrow = today.AddDays(1); + + // Act + int i = await Sub.Migrate([today, tomorrow]); + + Assert.NotEqual(0, i); + + string postfix = PgPartBy.Day.Fmt(tomorrow); + + string table = $"public.test_41_1_male_{postfix}"; + + await fixture.CheckTable(table); + + Assert.True(true); + } +} diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/PgPartByTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/PgPartByTests.cs new file mode 100644 index 0000000..3414713 --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/PgPartByTests.cs @@ -0,0 +1,170 @@ +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests; + +public class PgPartByTests +{ + + [Fact] + public void Day_Fmt_ReturnsCorrectFormat() + { + // Arrange + var testDate = new DateTimeOffset(2023, 12, 25, 14, 30, 23, TimeSpan.Zero); + + // Act + var name = PgPartBy.Day.Fmt(testDate); + + // Assert + Assert.Equal("y2023m12d25", name); + } + + [Theory] + [InlineData("y2023m12d25", 2023, 12, 25)] + [InlineData("y2024m01d01", 2024, 1, 1)] + [InlineData("_outbox_root__y2021m12d30", 2021, 12, 30)] + public void Day_ParseFmt_ValidStrings(string input, int expectedYear, int expectedMonth, int expectedDay) + { + + // Act + var result = PgPartBy.Day.ParseFmt(input); + + // Assert + Assert.NotNull(result); + Assert.Equal(expectedYear, result.Value.Year); + Assert.Equal(expectedMonth, result.Value.Month); + Assert.Equal(expectedDay, result.Value.Day); + Assert.Equal(0, result.Value.Hour); + Assert.Equal(0, result.Value.Minute); + Assert.Equal(0, result.Value.Second); + Assert.Equal(TimeSpan.Zero, result.Value.Offset); + } + + [Theory] + [InlineData("invalid")] + [InlineData("y2023m13d32")] + [InlineData("")] + public void Day_ParseFmt_ReturnsNull_ForInvalidStrings(string input) + { + try + { + // Act + var result = PgPartBy.Day.ParseFmt(input); + + // Assert + Assert.Null(result); + } + catch + { + Assert.True(true); + } + } + + + [Fact] + public void Month_Fmt_ReturnsCorrectFormat() + { + // Arrange + var testDate = new DateTimeOffset(2023, 12, 25, 14, 30, 23, TimeSpan.Zero); + + // Act + var name = PgPartBy.Month.Fmt(testDate); + + // Assert + Assert.Equal("y2023m12", name); + } + + [Theory] + [InlineData("y2023m12", 2023, 12)] + [InlineData("y2024m01", 2024, 1)] + [InlineData("_outbox_root__y2021m06", 2021, 6)] + public void Month_ParseFmt_ValidStrings(string input, int expectedYear, int expectedMonth) + { + + // Act + var result = PgPartBy.Month.ParseFmt(input); + + // Assert + Assert.NotNull(result); + Assert.Equal(expectedYear, result.Value.Year); + Assert.Equal(expectedMonth, result.Value.Month); + Assert.Equal(1, result.Value.Day); + Assert.Equal(0, result.Value.Hour); + Assert.Equal(0, result.Value.Minute); + Assert.Equal(0, result.Value.Second); + Assert.Equal(TimeSpan.Zero, result.Value.Offset); + } + + [Theory] + [InlineData("invalid")] + [InlineData("y2023m13")] + [InlineData("")] + public void Month_ParseFmt_ReturnsNull_ForInvalidStrings(string input) + { + try + { + // Act + var result = PgPartBy.Month.ParseFmt(input); + + // Assert + Assert.Null(result); + } + catch + { + Assert.True(true); + } + } + + [Fact] + public void Year_Fmt_ReturnsCorrectFormat() + { + // Arrange + var testDate = new DateTimeOffset(2023, 12, 25, 14, 30, 23, TimeSpan.Zero); + + // Act + var name = PgPartBy.Year.Fmt(testDate); + + // Assert + Assert.Equal("y2023", name); + } + + [Theory] + [InlineData("y2023", 2023)] + [InlineData("y2024", 2024)] + [InlineData("_outbox_root__y2021", 2021)] + public void Year_Parse_FmtValidStrings(string input, int expectedYear) + { + + // Act + var result = PgPartBy.Year.ParseFmt(input); + + // Assert + Assert.NotNull(result); + Assert.Equal(expectedYear, result.Value.Year); + Assert.Equal(1, result.Value.Month); + Assert.Equal(1, result.Value.Day); + Assert.Equal(0, result.Value.Hour); + Assert.Equal(0, result.Value.Minute); + Assert.Equal(0, result.Value.Second); + Assert.Equal(TimeSpan.Zero, result.Value.Offset); + } + + [Theory] + [InlineData("invalid")] + [InlineData("y202")] + [InlineData("")] + public void Year_ParseFmt_ReturnsNull_ForInvalidStrings(string input) + { + try + { + // Act + var result = PgPartBy.Year.ParseFmt(input); + + // Assert + Assert.Null(result); + } + catch + { + Assert.True(true); + } + } +} \ No newline at end of file diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Repositories/PgRepositoryTests.cs b/src/Tests/Sa.Partitional.PostgreSqlTests/Repositories/PgRepositoryTests.cs new file mode 100644 index 0000000..f1858d5 --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Repositories/PgRepositoryTests.cs @@ -0,0 +1,103 @@ +using Sa.Classes; +using Sa.Data.PostgreSql.Fixture; +using Sa.Partitional.PostgreSql; + +namespace Sa.Partitional.PostgreSqlTests.Repositories; + + +public class PgRepositoryTests(PgRepositoryTests.Fixture fixture) : IClassFixture +{ + public class Fixture : PgDataSourceFixture + { + public Fixture() + { + Services.AddPartitional((_, builder) => + { + builder.AddSchema(schema => + { + schema.AddTable("test_10", + "id INT NOT NULL", + "tenant_id INT NOT NULL", + "part TEXT NOT NULL", + "part_1 TEXT NOT NULL", + "payload_id TEXT" + ) + .PartByList("tenant_id", "part", "part_1") + .TimestampAs("date") + ; + + schema.AddTable("test_11", + "id INT NOT NULL", + "part_str TEXT NOT NULL", + "tenant_id INT NOT NULL", + "payload_id TEXT NOT NULL" + ) + .PartByList("part_str", "tenant_id") + ; + + schema.AddTable("test_12", + "id INT NOT NULL" + ) + ; + + }); + }) + .AddDataSource(configure => configure.WithConnectionString(_ => this.ConnectionString)) + ; + } + } + + + + [Fact()] + public async Task CreatePartTest() + { + Console.WriteLine(fixture.ConnectionString); + + int i = await fixture.Sub.CreatePart("test_11", DateTimeOffset.Now, ["some", 12]); + Assert.NotEqual(0, i); + } + + [Fact()] + public async Task CreatePart_WithEmptyListTest() + { + + int i = await fixture.Sub.CreatePart("test_12", DateTimeOffset.Now, []); + Assert.NotEqual(0, i); + } + + + [Fact()] + public async Task GetPartByRangeListTest() + { + var timeExpected = new DateTimeOffset(2024, 12, 03, 00, 00, 00, TimeSpan.Zero); + + await fixture.Sub.CreatePart("test_10", timeExpected.AddMinutes(22).AddHours(12), [1, "some1", "some2"]); + IReadOnlyCollection list = await fixture.Sub.GetPartsFromDate("test_10", timeExpected.AddDays(-3)); + Assert.NotEmpty(list); + PartByRangeInfo item = list.First(c => c.Id == "public.\"test_10__1__some1__some2__y2024m12d03\""); + Assert.NotNull(item); + Assert.Equal(timeExpected, item.FromDate); + Assert.Equal("public.test_10", item.RootTableName); + } + + [Fact()] + public async Task MigrateTest() + { + int i = await fixture.Sub.Migrate([DateTime.Now, DateTime.Now.AddDays(1)], table => + { + StrOrNum[][] result = table switch + { + "public.test_10" => [[1, "part1", "part2"], [2, "part1", "part2"]], + "public.test_11" => [["part1", 1], ["part1", 2], ["part2", 1]], + "public.test_12" => [], + _ => throw new NotImplementedException(), + }; + + return Task.FromResult(result); + }); + + Assert.True(i > 0); + } +} + diff --git a/src/Tests/Sa.Partitional.PostgreSqlTests/Sa.Partitional.PostgreSqlTests.csproj b/src/Tests/Sa.Partitional.PostgreSqlTests/Sa.Partitional.PostgreSqlTests.csproj new file mode 100644 index 0000000..d942516 --- /dev/null +++ b/src/Tests/Sa.Partitional.PostgreSqlTests/Sa.Partitional.PostgreSqlTests.csproj @@ -0,0 +1,15 @@ + + + + + + true + + + + + + + + + diff --git a/src/Tests/Sa.ScheduleTests/Sa.ScheduleTests.csproj b/src/Tests/Sa.ScheduleTests/Sa.ScheduleTests.csproj new file mode 100644 index 0000000..6e9c7d3 --- /dev/null +++ b/src/Tests/Sa.ScheduleTests/Sa.ScheduleTests.csproj @@ -0,0 +1,14 @@ + + + + + + true + + + + + + + + diff --git a/src/Tests/Sa.ScheduleTests/SchedulePostSetupTests.cs b/src/Tests/Sa.ScheduleTests/SchedulePostSetupTests.cs new file mode 100644 index 0000000..ad4c9eb --- /dev/null +++ b/src/Tests/Sa.ScheduleTests/SchedulePostSetupTests.cs @@ -0,0 +1,73 @@ +using Sa.Fixture; +using Sa.Schedule; + +namespace Sa.ScheduleTests; + + +public class SchedulePostSetupTests(SchedulePostSetupTests.Fixture fixture) : IClassFixture +{ + public class Fixture : SaSubFixture + { + static class Counter + { + private static int _count; + public static int Total => _count; + public static void Inc() => Interlocked.Increment(ref _count); + } + + class SomeJob : IJob + { + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + Counter.Inc(); + await Task.Delay(10, cancellationToken); + } + } + + public Fixture() + { + Services.AddSchedule(b => + { + b.AddJob((sp, builder) => + { + builder + .EveryTime(TimeSpan.FromMilliseconds(100)) + .RunOnce() + .StartImmediate() + ; + + }); + }); + + Services.AddSchedule(b => + { + b.AddJob((sp, builder) => + { + builder + .EveryTime(TimeSpan.FromMilliseconds(100)) + .RunOnce() + .StartImmediate() + ; + + }); + }); + } + + public static int Count => Counter.Total; + } + + private IScheduler Sub => fixture.Sub; + + + [Fact] + public async Task Check_Executing_RunOnce_ForMultiJobs() + { + int i = Sub.Start(CancellationToken.None); + + Assert.Equal(2, i); + + await Task.Delay(300); + + Assert.Equal(2, Fixture.Count); + } +} diff --git a/src/Tests/Sa.ScheduleTests/ScheduleSetupTests.cs b/src/Tests/Sa.ScheduleTests/ScheduleSetupTests.cs new file mode 100644 index 0000000..75ab891 --- /dev/null +++ b/src/Tests/Sa.ScheduleTests/ScheduleSetupTests.cs @@ -0,0 +1,56 @@ +using Sa.Fixture; +using Sa.Schedule; + +namespace Sa.ScheduleTests; + + +public class ScheduleSetupTests(ScheduleSetupTests.Fixture fixture) : IClassFixture +{ + public class Fixture : SaSubFixture + { + static class Counter + { + private static int _count; + public static int Total => _count; + public static void Inc() => Interlocked.Increment(ref _count); + } + + class SomeJob : IJob + { + public async Task Execute(IJobContext context, CancellationToken cancellationToken) + { + Counter.Inc(); + await Task.Delay(10, cancellationToken); + } + } + + public Fixture() + { + Services.AddSchedule(b => + { + b + .AddJob() + .EveryTime(TimeSpan.FromMilliseconds(100)) + .StartImmediate() + ; + }); + } + + public static int Count => Counter.Total; + } + + private IScheduler Sub => fixture.Sub; + + + [Fact] + public async Task Check_ExecuteCounterJob() + { + int i = Sub.Start(CancellationToken.None); + + Assert.NotEqual(0, i); + + await Task.Delay(300); + + Assert.True(Fixture.Count > 0); + } +} diff --git a/src/Tests/SaTests/Classes/KeepLockerTests.cs b/src/Tests/SaTests/Classes/KeepLockerTests.cs new file mode 100644 index 0000000..eef3393 --- /dev/null +++ b/src/Tests/SaTests/Classes/KeepLockerTests.cs @@ -0,0 +1,90 @@ +using Sa.Classes; + +namespace SaTests.Classes; + +public class KeepLockerTests +{ + [Fact] + public async Task KeepLocked_ExtendsLockUntilCancelled() + { + // Arrange + var extensionCount = 0; + var lockExpiration = TimeSpan.FromMilliseconds(50); + using var cancellationTokenSource = new CancellationTokenSource(); + var cancellationToken = cancellationTokenSource.Token; + + async Task extendLocked(CancellationToken token) + { + await Task.Delay(TimeSpan.FromMilliseconds(10), token); // Simulate some work + extensionCount++; + } + + // Act + using (var locker = KeepLocker.KeepLocked(lockExpiration, extendLocked, cancellationToken: cancellationToken)) + { + await Task.Delay(200); // Give it some time to run + cancellationTokenSource.Cancel(); + } + + // Assert + Assert.True(extensionCount > 0, "The lock should have been extended at least once."); + } + + [Fact] + public async Task KeepLocked_BlockImmediately_ExtendsLockImmediately() + { + // Arrange + var extensionCount = 0; + var lockExpiration = TimeSpan.FromMilliseconds(50); + using var cancellationTokenSource = new CancellationTokenSource(); + var cancellationToken = cancellationTokenSource.Token; + + async Task extendLocked(CancellationToken token) + { + await Task.Delay(TimeSpan.FromMilliseconds(10), token); // Simulate some work + extensionCount++; + } + + // Act + using (var locker = KeepLocker.KeepLocked(lockExpiration, extendLocked, blockImmediately: true, cancellationToken: cancellationToken)) + { + await Task.Delay(100); // Give it some time to run + cancellationTokenSource.Cancel(); + } + + // Assert + Assert.True(extensionCount > 0, "The lock should have been extended immediately."); + } + + [Fact] + public async Task Dispose_ReleasesResources() + { + // Arrange + var extensionCount = 0; + var lockExpiration = TimeSpan.FromMilliseconds(50); + using var cancellationTokenSource = new CancellationTokenSource(); + var cancellationToken = cancellationTokenSource.Token; + + async Task extendLocked(CancellationToken token) + { + await Task.Delay(TimeSpan.FromMilliseconds(10), token); // Simulate some work + extensionCount++; + } + + // Act + var locker = KeepLocker.KeepLocked(lockExpiration, extendLocked, cancellationToken: cancellationToken); + + await Task.Delay(100); + + locker.Dispose(); + + + var expected = extensionCount; + // Assert + Assert.True(extensionCount > 0, "The lock should have been extended immediately."); + + await Task.Delay(100); + + Assert.Equal(expected, extensionCount); + } +} \ No newline at end of file diff --git a/src/Tests/SaTests/Classes/RetryTests.cs b/src/Tests/SaTests/Classes/RetryTests.cs new file mode 100644 index 0000000..7205a9c --- /dev/null +++ b/src/Tests/SaTests/Classes/RetryTests.cs @@ -0,0 +1,146 @@ +using Sa.Classes; + +namespace SaTests.Classes; + + +public class RetryTests +{ + [Fact] + public async Task Constant_Retry_Succeeds_After_2_Attempts() + { + // Arrange + int attemptCount = 0; + ValueTask func(int input, CancellationToken token) + { + attemptCount++; + if (attemptCount < 3) + { + throw new Exception("Simulated failure"); + } + return new ValueTask(input); + } + + // Act + int result = await Retry.Constant(func, 42, retryCount: 3, waitTime: 10); + + // Assert + Assert.Equal(42, result); + Assert.Equal(3, attemptCount); + } + + [Fact] + public async Task Exponential_Retry_Succeeds_After_2_Attempts() + { + // Arrange + int attemptCount = 0; + ValueTask func(int input, CancellationToken token) + { + attemptCount++; + if (attemptCount < 3) + { + throw new Exception("Simulated failure"); + } + return new ValueTask(input); + } + + // Act + int result = await Retry.Exponential(func, 42, retryCount: 3, initialDelay: 10); + + // Assert + Assert.Equal(42, result); + Assert.Equal(3, attemptCount); + } + + [Fact] + public async Task Linear_Retry_Succeeds_After_2_Attempts() + { + // Arrange + int attemptCount = 0; + ValueTask func(int input, CancellationToken token) + { + attemptCount++; + if (attemptCount < 3) + { + throw new Exception("Simulated failure"); + } + return new ValueTask(input); + } + + // Act + int result = await Retry.Linear(func, 42, retryCount: 3, initialDelay: 10); + + // Assert + Assert.Equal(42, result); + Assert.Equal(3, attemptCount); + } + + [Fact] + public async Task DecorrelatedJitter_Retry_Succeeds_After_2_Attempts() + { + // Arrange + int attemptCount = 0; + ValueTask func(int input, CancellationToken token) + { + attemptCount++; + if (attemptCount < 3) + { + throw new Exception("Simulated failure"); + } + return new ValueTask(input); + } + + // Act + int result = await Retry.Jitter(func, 42, retryCount: 3, initialDelay: 10); + + // Assert + Assert.Equal(42, result); + Assert.Equal(3, attemptCount); + } + + [Fact] + public async Task Retry_Throws_Original_Exception_After_Max_Retries() + { + // Arrange + int attemptCount = 0; + ValueTask func(int input, CancellationToken token) + { + attemptCount++; + throw new Exception("Simulated failure"); + } + + // Act and Assert + await Assert.ThrowsAsync(() => Retry.Constant(func, 42, retryCount: 3, waitTime: 10).AsTask()); + Assert.Equal(3, attemptCount); + } + + [Fact] + public async Task Retry_Cancels_After_CancellationToken_Is_Cancelled() + { + // Arrange + int attemptCount = 0; + async ValueTask func(int input, CancellationToken token) + { + if (token.IsCancellationRequested) + { + return 111; + } + + attemptCount++; + await Task.Delay(100, CancellationToken.None); + throw new Exception("Simulated failure"); + } + + using CancellationTokenSource cts = new(); + + _ = Task.Run(async () => + { + await Task.Delay(200); + cts.Cancel(); + }); + + int result = await Retry.Constant(func, 42, retryCount: 3, waitTime: 10, cancellationToken: cts.Token); + + Assert.True(attemptCount > 0); + Assert.Equal(111, result); + } +} diff --git a/src/Tests/SaTests/Classes/StrOrNumTests.cs b/src/Tests/SaTests/Classes/StrOrNumTests.cs new file mode 100644 index 0000000..77db8b4 --- /dev/null +++ b/src/Tests/SaTests/Classes/StrOrNumTests.cs @@ -0,0 +1,32 @@ +using Sa.Classes; +using Sa.Extensions; + +namespace SaTests.Classes; + +public class StrOrNumTests +{ + [Fact] + public void StrOrNum_Mustbe_Serialize_json() + { + StrOrNum expected = "{Hi}\""; + + string json = expected.ToJson(); + + Assert.NotEmpty(json); + + StrOrNum actual = json.FromJson()!; + + Assert.Equal(expected, actual); + + + expected = 123; + + json = expected.ToJson(); + + Assert.NotEmpty(json); + + actual = json.FromJson()!; + + Assert.Equal(expected, actual); + } +} \ No newline at end of file diff --git a/src/Tests/SaTests/Classes/WorkQueueTests.cs b/src/Tests/SaTests/Classes/WorkQueueTests.cs new file mode 100644 index 0000000..0e312a7 --- /dev/null +++ b/src/Tests/SaTests/Classes/WorkQueueTests.cs @@ -0,0 +1,158 @@ +using Sa.Classes; + +namespace SaTests.Classes; + +public class WorkQueueTests +{ + public class SampleModel + { + private int _count; + + public int Count => _count; + + public Exception? Exception { get; set; } + + public void IncCount() => _count++; + } + + + internal class SampleWork : IWork + { + public async Task Execute(SampleModel model, CancellationToken cancellationToken) + { + model.IncCount(); + await Task.Delay(100, cancellationToken); + } + } + + + internal class SampleFailWork : IWorkWithHandleError + { + public Task Execute(SampleModel model, CancellationToken cancellationToken) + { + throw new Exception("test error"); + } + + public Task HandelError(Exception exception, SampleModel model, CancellationToken cancellationToken) + { + model.Exception = exception; + return Task.CompletedTask; + } + } + + + [Fact] + public async Task Schedule_ExecutesWorkSuccessfully() + { + var workService = new WorkQueue(); + var model = new SampleModel { }; + var work = new SampleWork { }; + + // Act + workService.Enqueue(model, work); + + // Wait for a short time to allow the work to be processed + await Task.Delay(200); + + // Stop the work service + await workService.Stop(model); + + // Assert + Assert.Equal(1, model.Count); + + await workService.DisposeAsync(); + } + + [Fact] + public async Task CancelledWork_MustBeStopped() + { + // Arrange + var workService = new WorkQueue(); + var model = new SampleModel { }; + var work = new SampleWork { }; + using var cancellationTokenSource = new CancellationTokenSource(); + + // Act + workService.Enqueue(model, work, cancellationTokenSource.Token); + + // Cancel the token before the work is completed + await cancellationTokenSource.CancelAsync(); + + // Wait for a short time to allow the work to be processed + await Task.Delay(200); + + // Stop the work service + await workService.Stop(model); + await workService.Stop(model); + + // Assert + Assert.Equal(0, model.Count); + + await workService.DisposeAsync(); + } + + + [Fact] + public async Task MultiWork_ExecutesWorkSuccessfully() + { + // Arrange + var workService = new WorkQueue(); + + var model = new SampleModel { }; + + int excepted = 100; + + for (int i = 0; i < excepted; i++) + { + var work = new SampleWork { }; + + // Act + workService + .Enqueue(model, work) + ; + } + + // Wait for a short time to allow the work to be processed + await workService.DisposeAsync(); + + // Assert + Assert.Equal(excepted, model.Count); + + } + + + [Fact] + public async Task WaitingEndedWork_AfterDispose() + { + // Arrange + var workService = new WorkQueue(); + var model = new SampleModel { }; + var work = new SampleWork { }; + using var cancellationTokenSource = new CancellationTokenSource(); + + // Act + workService.Enqueue(model, work, cancellationTokenSource.Token); + await workService.DisposeAsync(); + + // Assert + Assert.Equal(1, model.Count); + } + + + [Fact] + public async Task FailWork_MustBeHandled() + { + // Arrange + var workService = new WorkQueue(); + var model = new SampleModel { }; + var work = new SampleFailWork { }; + + // Act + workService.Enqueue(model, work); + + await workService.DisposeAsync(); + + // Assert + Assert.NotNull(model.Exception); + } +} \ No newline at end of file diff --git a/src/Tests/SaTests/SaTests.csproj b/src/Tests/SaTests/SaTests.csproj new file mode 100644 index 0000000..0334a33 --- /dev/null +++ b/src/Tests/SaTests/SaTests.csproj @@ -0,0 +1,13 @@ + + + + + + true + + + + + + + \ No newline at end of file

    h1^b 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 z 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