HangfireIO / HangfireIO/Hangfire
Tasks created for IServerProcess not use ThreadPool
- 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
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