Skip to content

Add failure policy in dapr schedular#69

Merged
yilmaztayfun merged 1 commit into
masterfrom
60-enhancement-add-opentelemetry-tracing-spans-to-distributed-event-bus-pipeline
May 19, 2026
Merged

Add failure policy in dapr schedular#69
yilmaztayfun merged 1 commit into
masterfrom
60-enhancement-add-opentelemetry-tracing-spans-to-distributed-event-bus-pipeline

Conversation

@yilmaztayfun

@yilmaztayfun yilmaztayfun commented May 19, 2026

Copy link
Copy Markdown
Contributor

Summary by Sourcery

Add configurable failure policies to background job scheduling and propagate them through the background job service and scheduler interfaces.

New Features:

  • Introduce JobScheduleFailurePolicy and FailurePolicyType to represent drop and constant retry scheduling behaviors.
  • Allow callers of IBackgroundJobService.EnqueueAsync and IJobScheduler.ScheduleAsync to specify an optional job failure policy when scheduling jobs.

Enhancements:

  • Map JobScheduleFailurePolicy to Dapr job failure policy options in the DaprJobScheduler so that Dapr jobs honor the configured behavior.
  • Simplify logging and parameter passing in background job update and scheduling flows.

Summary by CodeRabbit

Release Notes

  • New Features

    • Background job scheduling now supports configurable failure policies. Jobs can be configured to drop on failure or retry with customizable intervals and maximum retry attempts.
  • Chores

    • Removed Zipkin exporter package reference from build configuration.

Review Change Stack

@yilmaztayfun yilmaztayfun self-assigned this May 19, 2026
@yilmaztayfun yilmaztayfun requested review from a team May 19, 2026 23:29
@sourcery-ai

sourcery-ai Bot commented May 19, 2026

Copy link
Copy Markdown

Reviewer's Guide

Introduces a configurable job failure policy for Dapr-scheduled background jobs, threading a new JobScheduleFailurePolicy abstraction through the background job APIs into the Dapr scheduler where it is mapped to Dapr’s IJobFailurePolicyOptions, while doing minor cleanup to scheduling calls and logging.

File-Level Changes

Change Details Files
Expose failure policy configuration on background job and scheduler APIs and pass it through scheduling flows.
  • Extend IBackgroundJobService.EnqueueAsync to accept an optional JobScheduleFailurePolicy parameter.
  • Extend IJobScheduler.ScheduleAsync to accept an optional JobScheduleFailurePolicy parameter.
  • Update BackgroundJobService to accept and forward the failure policy to the job scheduler when scheduling new jobs.
  • Ensure UpdateAsync and UpdateScheduleAsync call sites remain compatible by using named parameters for the cancellation token.
framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IBackgroundJobService.cs
framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IJobScheduler.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/BackgroundJobService.cs
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/Dapr/DaprJobScheduler.cs
Map the new JobScheduleFailurePolicy abstraction to Dapr job failure policy options inside the Dapr scheduler.
  • Add an optional failurePolicyOptions parameter to DaprJobScheduler.ScheduleAsync and forward it into daprJobsClient.ScheduleJobAsync.
  • Introduce a private MapFailurePolicy helper that converts JobScheduleFailurePolicy values into the appropriate IJobFailurePolicyOptions implementation (drop or constant interval with optional MaxRetries).
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/Dapr/DaprJobScheduler.cs
Define the JobScheduleFailurePolicy model used by callers to specify failure behavior.
  • Add a sealed JobScheduleFailurePolicy class with PolicyType, Interval, and MaxRetries properties and static factory methods for Drop and Constant policies.
  • Introduce the FailurePolicyType enum to represent the supported policy kinds.
framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/JobScheduleFailurePolicy.cs
Minor cleanup of logging behavior around job enqueueing.
  • Remove a redundant informational log line after committing the unit of work in BackgroundJobService.EnqueueAsync, keeping only the log inside the scheduler callback.
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/BackgroundJobService.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@yilmaztayfun yilmaztayfun merged commit d11937e into master May 19, 2026
3 of 6 checks passed
@coderabbitai

coderabbitai Bot commented May 19, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b21cbe58-1d45-471d-a53e-021086146dd1

📥 Commits

Reviewing files that changed from the base of the PR and between 4763f12 and 9f851ff.

📒 Files selected for processing (6)
  • framework/src/BBT.Aether.AspNetCore/BBT.Aether.AspNetCore.csproj
  • framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IBackgroundJobService.cs
  • framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IJobScheduler.cs
  • framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/JobScheduleFailurePolicy.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/BackgroundJobService.cs
  • framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/Dapr/DaprJobScheduler.cs

📝 Walkthrough

Walkthrough

This PR introduces a JobScheduleFailurePolicy model allowing callers to specify how scheduled background jobs should handle failures—either dropping failed jobs or retrying with a constant interval and optional maximum retry count. The policy flows through service and Dapr scheduler layers via optional parameters added to public scheduling interfaces.

Changes

Background Job Scheduling Failure Policy

Layer / File(s) Summary
Policy model definition
framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/JobScheduleFailurePolicy.cs
JobScheduleFailurePolicy sealed class with PolicyType, optional Interval, and optional MaxRetries properties; Drop() and Constant(interval, maxRetries?) static factory methods; FailurePolicyType enum with Drop and Constant values.
Interface contract updates
framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IBackgroundJobService.cs, framework/src/BBT.Aether.Core/BBT/Aether/BackgroundJob/IJobScheduler.cs
Both IBackgroundJobService.EnqueueAsync and IJobScheduler.ScheduleAsync add optional JobScheduleFailurePolicy? failurePolicyOptions = null parameter to expose failure-policy selection at the scheduling boundary.
BackgroundJobService plumbing
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/BackgroundJobService.cs
EnqueueAsync accepts the optional policy and forwards it to jobScheduler.ScheduleAsync inside the uow.OnCompleted callback; removes post-commit "Successfully enqueued…" log; UpdateAsync passes cancellationToken by name.
DaprJobScheduler policy mapping
framework/src/BBT.Aether.Infrastructure/BBT/Aether/BackgroundJob/Dapr/DaprJobScheduler.cs
ScheduleAsync accepts the optional policy, maps it via new MapFailurePolicy helper (null → null, Drop → drop options, Constant → constant options with max retries), and passes the result to Dapr ScheduleJobAsync; UpdateScheduleAsync uses named cancellationToken argument.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • burgan-tech/aether#57: Modifies DaprJobScheduler.ScheduleAsync to add overwrite: true to the Dapr ScheduleJobAsync call.
  • burgan-tech/aether#56: Extends DaprJobScheduler.ScheduleAsync with overwrite: true parameter in the same Dapr scheduling call.
  • burgan-tech/aether#28: Modifies background-job scheduling around uow.OnCompleted callback and jobScheduler.ScheduleAsync invocation.

Suggested reviewers

  • darcoakk
  • middt

Poem

A rabbit hops through scheduled tasks,
With policies both tried and tasked—
Drop or retry, pick your way,
Jobs now know how long to stay! 🐰⏰

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 60-enhancement-add-opentelemetry-tracing-spans-to-distributed-event-bus-pipeline

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • When updating jobs (e.g., in UpdateScheduleAsync and BackgroundJobService.UpdateAsync), the existing failure policy is not preserved or reapplied, so rescheduling a job will silently drop any configured policy; consider retrieving and reusing the existing policy to keep behavior consistent.
  • MapFailurePolicy silently returns null for unsupported or misconfigured JobScheduleFailurePolicy values (e.g., PolicyType.Constant with Interval == null), which can hide configuration errors; consider throwing or logging in these cases to surface misconfigurations early.
  • The new failurePolicyOptions parameter on IJobScheduler.ScheduleAsync changes the interface signature and will require all implementers to update their implementations; if this is intended, ensure downstream schedulers are updated, or consider a non-breaking extension mechanism if external implementations are expected.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- When updating jobs (e.g., in `UpdateScheduleAsync` and `BackgroundJobService.UpdateAsync`), the existing failure policy is not preserved or reapplied, so rescheduling a job will silently drop any configured policy; consider retrieving and reusing the existing policy to keep behavior consistent.
- `MapFailurePolicy` silently returns `null` for unsupported or misconfigured `JobScheduleFailurePolicy` values (e.g., `PolicyType.Constant` with `Interval == null`), which can hide configuration errors; consider throwing or logging in these cases to surface misconfigurations early.
- The new `failurePolicyOptions` parameter on `IJobScheduler.ScheduleAsync` changes the interface signature and will require all implementers to update their implementations; if this is intended, ensure downstream schedulers are updated, or consider a non-breaking extension mechanism if external implementations are expected.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 2 duplication

Metric Results
Complexity 0
Duplication 2

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a JobScheduleFailurePolicy to the background job system, enabling configurable retry strategies such as 'Drop' and 'Constant'. While the core logic for passing these policies to the scheduler is implemented, several issues were identified: the failure policy is not persisted in the BackgroundJobInfo entity, causing it to be lost during job reconstruction or updates. Furthermore, the policy is missing from update calls in both BackgroundJobService and DaprJobScheduler. Other feedback includes a recommendation to remove rather than comment out a package reference and to eliminate a redundant delete operation in the Dapr scheduler.

uow.OnCompleted(async _ =>
{
await jobScheduler.ScheduleAsync(handlerName, jobName, schedule, payloadBytes, cancellationToken);
await jobScheduler.ScheduleAsync(handlerName, jobName, schedule, payloadBytes, failurePolicyOptions, cancellationToken);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

While the failure policy is correctly passed to the scheduler here, it is not being persisted in the BackgroundJobInfo entity (the jobInfo object created on line 97). Since this service integrates job persistence with scheduling, the failure policy will be lost if the job needs to be reconstructed from the database or updated later. Consider adding a field to BackgroundJobInfo or storing the policy within ExtraProperties.

var payloadBytes = eventSerializer.Serialize(envelope);
await jobScheduler.ScheduleAsync(jobInfo.HandlerName, jobInfo.JobName, newSchedule, payloadBytes,
cancellationToken);
cancellationToken: cancellationToken);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The failurePolicyOptions parameter is missing from this ScheduleAsync call. When a job's schedule is updated, the original failure policy should be retrieved from the job store and passed here to ensure it is preserved. Currently, updating a job effectively resets its failure policy to null.

var jobInfo = await daprJobsClient.GetJobAsync(jobName, cancellationToken);
await daprJobsClient.DeleteJobAsync(jobName, cancellationToken);
await ScheduleAsync(handlerName, jobName, newSchedule, jobInfo.Payload, cancellationToken);
await ScheduleAsync(handlerName, jobName, newSchedule, jobInfo.Payload, cancellationToken: cancellationToken);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This call to ScheduleAsync does not pass the failure policy, causing it to be lost during schedule updates. You should extract the existing failure policy from the jobInfo object (returned by Dapr on line 95) and pass it to the ScheduleAsync method. Additionally, since ScheduleAsync uses overwrite: true in its implementation, the explicit call to DeleteJobAsync on line 96 is redundant and creates a non-atomic operation that could lead to job loss if the subsequent scheduling fails.

<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" />
<!-- <PackageReference Include="OpenTelemetry.Exporter.Zipkin" />-->

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Commenting out package references is generally discouraged as it leaves dead code in the project file. If the Zipkin exporter is no longer needed, it should be removed entirely. If it is intended to be optional or used only in specific environments, consider using conditional property groups or documenting the reason for keeping it commented out.

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant