HangfireIO / HangfireIO/Hangfire

Tasks created for IServerProcess not use ThreadPool

Open
#677 3 comments 0 reactions 0 assignees View on GitHub
t: question
Dominant language
C#
Stars
10.1k
Forks
1.8k
Avg merge
1h 19m
Merged PRs (30d)
1

Description

Version: 1.6.4

our pseudo code:

``` csharp
for (int i = 0; i < 25; i++)
{
var sqlStorage = new SqlServerStorage($"connection string for each tenant", options);
var server = new BackgroundJobServer(sqlStorage);
jobServers.Add(server);
var manager = new RecurringJobManager(sqlStorage);
var crone = "00 12 * * *";
manager.AddOrUpdate(i.ToString(), Hangfire.Common.Job.FromExpression(() => HighCPUUsage(i)), crone, TimeZoneInfo.Local);
manager.AddOrUpdate((i + 100).ToString(), Hangfire.Common.Job.FromExpression(() => SimpleJob(i + 100)), crone, TimeZoneInfo.Local);
}
```

Hangfire code

class:

``` csharp
internal static class ServerProcessExtensions
```

function:

``` csharp
public static Task CreateTask([NotNull] this IServerProcess process, BackgroundProcessContext context)
```

Task created by code:

``` csharp
return Task.Factory.StartNew(
() => RunProcess(process, context),
TaskCreationOptions.LongRunning);
```

Tasks created with option TaskCreationOptions.LongRunning not use ThreadPool and create new Thread without limits.

Our company uses Hangfire in multitenancy server, where more than 20 tenant. Each tenant is scheduled the job with greater use of the CPU. After running all the jobs CPU can be loaded 100%.

I change TaskCreationOprions on Default and test the same case. CPU not load on 100% with ThreadPool.

Need add ServerTaskCreationOptions in BackgroundJobServerOptions or something else for configure this option.

For test that thread not created by ThreadPool I use System.Threading.Thread.IsThreadPoolThread property in job function. And see source code .Net:

``` csharp
[SecurityCritical]
protected internal override void QueueTask(Task task)
{
if ((task.Options & TaskCreationOptions.LongRunning) != 0)
{
// Run LongRunning tasks on their own dedicated thread.
Thread thread = new Thread(s_longRunningThreadWork);
thread.IsBackground = true; // Keep this thread from blocking process shutdown
thread.Start(task);
}
else
{
// Normal handling for non-LongRunning tasks.
bool forceToGlobalQueue = ((task.Options & TaskCreationOptions.PreferFairness) != 0);
ThreadPool.UnsafeQueueCustomWorkItem(task, forceToGlobalQueue);
}
}
```

Contributor guide

Open the contributing guide

Research direction

Start in ServerProcessExtensions.CreateTask, where IServerProcess tasks use Task.Factory.StartNew with TaskCreationOptions.LongRunning. Review BackgroundJobServerOptions and the task creation path to determine how a configurable ServerTaskCreationOptions would be exposed. Done means the option can select the task creation behavior and the multitenant scenario can verify whether work runs on ThreadPool threads.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.