elsa-workflows / elsa-workflows/elsa-extensions

Hangfire shell features incomplete: HangfireSchedulerShellFeature throws; BackgroundActivity scheduler not wired; UseMemoryStorage false is a no-op

Closed
#196 0 comments 0 reactions 0 assignees View on GitHub
bug triaged
Dominant language
C#
Stars
49
Forks
48
Avg merge
21h 35m
Merged PRs (30d)
20

Description

## Summary

The Elsa 3 **shell-feature** path for Hangfire in `Elsa.Scheduling.Hangfire` is not a working substitute for the classic `FeatureBase` path. Enabling these shell features today either crashes or silently fails to swap the core scheduler contracts.

This is separate from the long-running Hangfire *runtime* bugs (#121 duplicates on restart, elsa-core #3110 / #4819 / #7356). Those assume Hangfire is correctly registered; this issue is about the **new shell surface not actually installing** that registration.

## Evidence

### 1. `HangfireSchedulerShellFeature` is a stub

`src/modules/scheduling/Elsa.Scheduling.Hangfire/ShellFeatures/HangfireSchedulerShellFeature.cs`:

```csharp
public void ConfigureServices(IServiceCollection services)
{
throw new NotImplementedException();
}
```

Contrast with the classic path (`HangfireSchedulerFeature`), which wires `SchedulingFeature.WorkflowScheduler` to `HangfireWorkflowScheduler`, and with Quartz’s shell path (`QuartzSchedulerFeature`), which fully registers `IWorkflowScheduler`.

Enabling “Hangfire Workflow Scheduler” in the shell therefore cannot succeed.

### 2. `HangfireBackgroundActivitySchedulerShellFeature` does not replace `IBackgroundActivityScheduler`

`HangfireBackgroundActivitySchedulerShellFeature` only does:

```csharp
services.AddSingleton();
```

It never replaces the `IBackgroundActivityScheduler` registration. Core `WorkflowRuntimeFeature` (shell) still registers:

```csharp
.AddSingleton(BackgroundActivityScheduler) // defaults to LocalBackgroundActivityScheduler
```

The classic path (`HangfireBackgroundActivitySchedulerFeature`) correctly does:

```csharp
Module.Configure(f =>
f.BackgroundActivityScheduler = sp => sp.GetRequiredService());
```

So the shell toggle can look “on” while background activities still run on the local in-process queue.

### 3. `HangfireShellFeature.UseMemoryStorage = false` is a no-op

```csharp
var jobStorage = UseMemoryStorage ? new() : null ?? new MemoryStorage();
```

Both branches resolve to `MemoryStorage`. There is no alternate storage when the setting is false (and no SQL/other provider wiring on the shell feature, unlike the obsolete classic `UseSqlServerStorage` / `UseSqliteStorage` helpers).

## Proposed direction (subtractive / parity)

Prefer **parity with the classic FeatureBase wiring and with Quartz’s shell feature**, not a new abstraction:

1. Implement `HangfireSchedulerShellFeature` the same way `HangfireSchedulerFeature` / `QuartzSchedulerFeature` do: register `HangfireWorkflowScheduler` as `IWorkflowScheduler` (and the Cron descriptor modifier).
2. Wire `HangfireBackgroundActivityScheduler` as `IBackgroundActivityScheduler` (replace Local), matching `HangfireBackgroundActivitySchedulerFeature`.
3. Fix or remove the broken `UseMemoryStorage` setting until a real non-memory storage path exists on the shell feature; do not leave a toggle that cannot change behavior.
4. Optionally rename the misleading file `HangfireBackgroundActivityInvokerFeature.cs` (class is `HangfireBackgroundActivitySchedulerFeature`) while touching this area.

Milestone: leave unset for Triage / Crew Lead.

## Related (do not treat as duplicates)

- elsa-extensions #121 — duplicate Hangfire jobs on restart (runtime idempotency; assumes Hangfire is wired)
- elsa-core #3110, #4819, #7356, #8145 — runtime / architecture of background execution once Hangfire *is* in play

Contributor guide

Open the contributing guide

Research direction

Start with src/modules/scheduling/Elsa.Scheduling.Hangfire/ShellFeatures/HangfireSchedulerShellFeature.cs and compare it with HangfireSchedulerFeature and QuartzSchedulerFeature. Inspect HangfireBackgroundActivitySchedulerShellFeature and HangfireShellFeature for the scheduler registration and UseMemoryStorage behavior. Done means the shell features install the Hangfire scheduler contracts and the storage setting no longer silently has the same effect for both values.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.