Skip to content

String-Based Bg-Job Publishing with Dynamic Payload#25059

Open
salihozkara wants to merge 14 commits intodevfrom
issue-24918-bg-jobs
Open

String-Based Bg-Job Publishing with Dynamic Payload#25059
salihozkara wants to merge 14 commits intodevfrom
issue-24918-bg-jobs

Conversation

@salihozkara
Copy link
Member

Related #24918

Add non-generic EnqueueAsync(string jobName, object args, ...) to IBackgroundJobManager and implement it across providers. Implementations and helpers added/updated for Hangfire (IJsonSerializer usage, new HangfireJobExecutionAdapter), Quartz (new QuartzJobExecutionAdapter and job-data based enqueue), RabbitMQ (IJobQueue non-generic EnqueueAsync, JobQueueManager.GetAsync(jobName)), TickerQ (reflective CreateTickerRequest helper), and DefaultBackgroundJobManager (returns string ids). Also update NullBackgroundJobManager to throw for the new overload and extend tests to cover enqueueing by job name. These changes enable enqueueing jobs dynamically by name with serialized arguments and unify cross-provider execution paths.
Avoids invalid casts when the provided args are not of runtime type TArgs. The method now checks for a direct TArgs instance and calls EnqueueAsync directly; otherwise it serializes and deserializes the args via Serializer to produce a TArgs instance before enqueuing. This preserves the fast path for matching types while safely handling boxed or different runtime argument representations.
Introduce dynamic background job support so jobs can be registered and executed without a compile-time job type. Key changes:

- Add DynamicBackgroundJobContext, IDynamicBackgroundJobHandlerProvider and DynamicBackgroundJobHandlerProvider to allow registering/unregistering dynamic handlers at runtime.
- Extend BackgroundJobConfiguration with DynamicHandler and IsDynamic, and make JobType nullable for dynamic scenarios.
- Update AbpBackgroundJobOptions to use a ConcurrentDictionary for name lookup, and add methods to Add/Remove dynamic jobs and GetJobOrNull.
- Extend JobExecutionContext with JobName and propagate it through Hangfire/Quartz/RabbitMQ/TickerQ adapters and worker code.
- Update BackgroundJobExecuter to detect and execute dynamic handlers, deserialize/ensure dictionary args, and retain existing typed execution path.
- Add tests (DynamicJobExecutionTracker, runtime/compile-time dynamic handler tests) and register a sample dynamic job in test module.
- Update demo SampleJobCreator and DemoAppSharedModule to demonstrate compile-time and runtime dynamic job registration and enqueueing.

These changes enable flexible, dictionary-based job arguments and runtime registration of background job handlers while preserving existing typed job execution.
Introduce anonymous/background-job-by-name support: add AnonymousJobArgs, IAnonymousJobHandlerRegistry and AnonymousJobHandlerRegistry, and an AnonymousJobExecutorAsyncBackgroundJob to execute JSON-based anonymous handlers. AbpBackgroundJobOptions now stores anonymous handlers and exposes registration/query helpers. Updated background job managers (Default, Hangfire, Quartz, RabbitMQ, TickerQ) to wrap registered anonymous jobs into AnonymousJobArgs when enqueuing and to depend on the handler registry and JSON serializer where needed. Removed the old dynamic handler types/APIs (DynamicBackgroundJobContext, IDynamicBackgroundJobHandlerProvider, DynamicBackgroundJobHandlerProvider) and related dynamic handling code; BackgroundJobConfiguration simplified (JobType non-nullable) and JobExecutionContext no longer carries JobName. Tests and demo code updated to use anonymous handlers and tracking. This change centralizes runtime-registered handlers keyed by job name and standardizes anonymous job payloads as JSON.
Delete .cursor/hooks/state/continual-learning-index.json and .cursor/hooks/state/continual-learning.json which held persisted continual-learning metadata (transcript index, last run timestamps, last processed generation ID, etc.). This cleans up obsolete/reset state for the Cursor continual-learning hooks.
Move AnonymousJobExecutorAsyncBackgroundJob into the Abstractions package and remove its dependency on ICancellationTokenProvider. The constructor and handler invocation now use a default CancellationToken and unused usings were cleaned up.

In AbpTickerQBackgroundJobManager, add NormalizeArgs and use it before creating the ticker request to ensure the provided args match the expected args type. The normalization performs a JSON round-trip when necessary so CreateTickerRequest receives an instance of the correct type.
Add informational logging when jobs are wrapped into the anonymous transport and when anonymous transport jobs are executed to improve observability. Introduce ILogger properties (defaulting to NullLogger) and add LogInformation calls in Hangfire, Quartz, RabbitMQ, TickerQ and Default background job managers, and in AnonymousJobExecutorAsyncBackgroundJob.ExecuteAsync. Improve Hangfire dashboard display by attempting to deserialize serialized AnonymousJobArgs to show the effective (original) job name via a new TryGetEffectiveJobName JSON helper. Add required using directives and safe JSON parsing with fallbacks.
@salihozkara salihozkara added this to the 10.3-preview milestone Mar 10, 2026
@salihozkara salihozkara requested a review from maliming March 10, 2026 10:43
Copilot AI review requested due to automatic review settings March 10, 2026 10:43

This comment was marked as outdated.

Make anonymous job JSON parsing more robust and fix DI registration for Quartz adapter. Add TryGetJobNameElement to accept both "JobName" and "jobName"; update anonymous job handlers to dispose JsonDocument and to prefer lowercase "value" with a fallback to "Value" for compatibility with different serializers. Also register a non-generic QuartzJobExecutionAdapter in DI and remove an extraneous BOM from a using line.
Introduce AnonymousJobExecutionContext and switch anonymous job handler APIs to accept it (Func<AnonymousJobExecutionContext, CancellationToken, Task> / Action<AnonymousJobExecutionContext, CancellationToken>). Update AbpBackgroundJobOptions, IAnonymousJobHandlerRegistry, AnonymousJobHandlerRegistry and AnonymousJobExecutorAsyncBackgroundJob to use the new context and to obtain a cancellation token via ICancellationTokenProvider. Update all callsites (tests, demo module, sample job creator) and documentation to show registering/enqueuing anonymous handlers by name and explain Hangfire display behavior. Also add a .cursor hooks state file. The demo no longer skips enqueuing anonymous jobs for RabbitMQ in this change.

This comment was marked as outdated.

Wrap JsonDocument usage in explicit using blocks for anonymous job handlers to ensure deterministic disposal and avoid capturing/disposal issues. Also rename the compile-time handler parameter from `context` to `ctx` to prevent potential shadowing. Changes applied to DemoAppSharedModule.cs and SampleJobCreator.cs.
Rename the internal anonymous transport job name from "AnonymousJob" to "Abp.AnonymousJob" and update docs accordingly. Add null/whitespace argument checks (Check.NotNull / Check.NotNullOrWhiteSpace) in anonymous handler registration and lookup APIs. Change background job managers (Hangfire, Quartz, RabbitMQ, TickerQ, Default) to only wrap jobs as anonymous when an anonymous handler is registered and there is no typed job configuration (check via BackgroundJobOptions.GetJobOrNull). Wire AbpBackgroundJobOptions into affected managers and update tests with a new case verifying that a typed job prevents anonymous wrapping.

This comment was marked as outdated.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants