diff --git a/CHANGELOG.md b/CHANGELOG.md index ba10d892..f4f35a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `ISupportDryRun` — an opt-in interface exposing `bool IsDryRun { get; set; }` for + ETL stages that support a dry run: the full pipeline is exercised but the external + side effect that mutates a destination or source is skipped. Implemented by the + stage that honours it (not by the base classes). (#259) + ### Changed ### Deprecated diff --git a/src/Wolfgang.Etl.Abstractions/ISupportDryRun.cs b/src/Wolfgang.Etl.Abstractions/ISupportDryRun.cs new file mode 100644 index 00000000..69db54a1 --- /dev/null +++ b/src/Wolfgang.Etl.Abstractions/ISupportDryRun.cs @@ -0,0 +1,42 @@ +namespace Wolfgang.Etl.Abstractions; + +/// +/// Implemented by ETL stages that support a dry run — a mode in which the +/// full pipeline is exercised but the external side effect that mutates a destination +/// or source is skipped. +/// +/// +/// A dry run runs the stage exactly as a real run would — enumerating the source, +/// evaluating SkipItemCount and MaximumItemCount, incrementing the +/// progress counters, firing the progress-timer callback and logging as usual — but +/// it does not perform the side effect that mutates external state. This is +/// useful for validating a newly built pipeline (source feed, mapping, batching, +/// throttling) against production data without writing, and for estimating how long +/// a real run would take. +/// +/// The interface is opt-in: a stage advertises it only when it genuinely +/// honours . It is therefore the responsibility of the +/// implementer to gate its side effect on ; the ETL base +/// classes deliberately do not implement this interface because the side effect +/// lives inside the derived stage and the base class has no way to skip it. +/// +/// +/// Dry run applies to any stage with an external side effect — a loader skips its +/// write, and an extractor that mutates its source as it reads (for example +/// committing a message-queue offset, deleting a message on receipt, marking mail +/// read or moving a processed file) skips that acknowledgement. A pure transformer +/// has no external side effect and would not normally implement this interface. +/// +/// +public interface ISupportDryRun +{ + /// + /// Gets or sets a value indicating whether the stage runs in dry-run mode. + /// + /// + /// When , the stage runs the full pipeline but skips the + /// external side effect that mutates the destination or source. Defaults to + /// . + /// + bool IsDryRun { get; set; } +} diff --git a/src/Wolfgang.Etl.Abstractions/PublicAPI.Unshipped.txt b/src/Wolfgang.Etl.Abstractions/PublicAPI.Unshipped.txt index 7dc5c581..31b06ed9 100644 --- a/src/Wolfgang.Etl.Abstractions/PublicAPI.Unshipped.txt +++ b/src/Wolfgang.Etl.Abstractions/PublicAPI.Unshipped.txt @@ -1 +1,4 @@ #nullable enable +Wolfgang.Etl.Abstractions.ISupportDryRun +Wolfgang.Etl.Abstractions.ISupportDryRun.IsDryRun.get -> bool +Wolfgang.Etl.Abstractions.ISupportDryRun.IsDryRun.set -> void diff --git a/src/Wolfgang.Etl.Abstractions/Wolfgang.Etl.Abstractions.csproj b/src/Wolfgang.Etl.Abstractions/Wolfgang.Etl.Abstractions.csproj index 0ed4633d..5ced7c1e 100644 --- a/src/Wolfgang.Etl.Abstractions/Wolfgang.Etl.Abstractions.csproj +++ b/src/Wolfgang.Etl.Abstractions/Wolfgang.Etl.Abstractions.csproj @@ -2,7 +2,7 @@ net462;net472;net48;net481;netstandard2.0;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0 latest - 0.14.1 + 0.15.0