Skip to content

v3.0.0.7577

Latest

Choose a tag to compare

@I-RzR-I I-RzR-I released this 11 Jun 18:23
80eb020

What's Changed


  • [FIX] -> Working-hours effective capacity is now a hard allocation cap, not a scoring nudge — a user cannot receive more items than Truncate(WorkingHours × MaxAllowedDocs / FullWorkDayHours).
  • [FIX] -> Allocation scoring uses score × remaining-headroom (greedy) instead of a plain score comparison, so the most-available user is consistently preferred over round-robin rotation.
  • [FIX] -> PriorityActivityScoringStep priority denominator is always ≥ 1 regardless of sign, eliminating the divide-by-zero that occurred when all users shared the same priority value.
  • [FIX] -> PrimaryUserId / AlternativeUserId tie-break in DistributionResult mirrors the allocator's own ascending UserId order, making both properties deterministic across runs.
  • [FIX] -> Allocation and Trace in DistributionResult are defensive copies — mutating the returned dictionary or collection does not affect subsequent engine runs.
  • [FIX] -> CancellationToken is checked between pipeline steps; a pre-cancelled token produces a failed IResult rather than throwing OperationCanceledException to the caller.
  • [FIX] -> UserLoad<TUserId> constructor throws ArgumentOutOfRangeException for negative currentLoad, capacity, or workingHours; the helper surfaces such exceptions as a failed IResult.
  • [DEV] -> DistributionResult<TUserId> exposes RequestedDocuments, UnallocatedDocuments (Max(0, Requested − TotalAllocated)), and IsFullyAllocated to signal partial-allocation runs.
  • [DEV] -> EngineConfig<TUserId> with AdditionalSteps (IReadOnlyList<IDistributionStep<TUserId>>) and AdditionalConstraints (IReadOnlyList<IConstraint<TUserId>>), plus a matching DistributionSuggestionHelper<TUserId>(EngineConfig<TUserId>) constructor overload for consumer-supplied pipeline extensibility.
  • [DEV] -> IDistributionStep<TUserId>.Execute now receives IDistributionContext<TUserId> (a narrowed, read-only-plus-explicit-mutation contract) instead of the raw mutable DistributionContext<TUserId>. Custom steps must use SetScore/SetEffectiveCapacity/IncrementAllocation/AddTrace to mutate state; direct dictionary access (context.Scores[id] = x, context.Allocation[id]++, context.Trace.Add(...)) is no longer possible. DistributionContext<TUserId> no longer exposes raw mutable IDictionary/IList properties — Scores, EffectiveCapacity, and Allocation are now IReadOnlyDictionary, and Trace is no longer public. The Abstractions.Pipeline layer no longer depends on Engine.Pipeline (the layering smell is removed).

Full Changelog: v2.0.0.6122...v3.0.0.7577