Hello,
I have real scenario with two servers, I have one queue and I want to run only one job in the same time on one from two servers. It is possible? My code doesn’t work.
Possible storages can be only redis and postgresql.
using System;
using System.Threading;
using System.Threading.Tasks;
using Hangfire;
using Hangfire.Logging;
using Hangfire.Logging.LogProviders;
using Hangfire.MemoryStorage;
using Hangfire.MemoryStorage.Database;
using Hangfire.PostgreSql;
using Hangfire.Pro.Redis;
namespace HangfireLockQueue
{
public class Program
{
static void Main(string[] args)
{
// 1.memory
//JobStorage storage = new MemoryStorageFake(new MemoryStorageOptions());
// 2.redis
//JobStorage storage = new RedisStorage("redis:6379,ssl = false", new RedisStorageOptions
//{
// Prefix = "HangfireRedis-Local:"
//});
// 3.postgres
var connectionString = "Host=postgres;Database=scheduler;Username=test;Password=<>;";
JobStorage storage = new PostgreSqlStorage(connectionString, new PostgreSqlStorageOptions
{
QueuePollInterval = TimeSpan.FromMilliseconds(1),
InvisibilityTimeout = TimeSpan.FromHours(2)
});
JobStorage.Current = storage;
Console.WriteLine(JobStorage.Current);
LogProvider.SetCurrentLogProvider(new ColouredConsoleLogProvider());
RunServer1(storage);
RunServer2(storage);
Console.ReadLine();
}
private static void RunServer1(JobStorage storage)
{
Task.Factory.StartNew(() => RunServer1Client1Queue(storage));
}
private static void RunServer1Client1Queue(JobStorage storage)
{
var serverOptions = new BackgroundJobServerOptions
{
ShutdownTimeout = TimeSpan.FromMinutes(5),
ServerName = $"{Environment.MachineName}1.{Guid.NewGuid()}",
Queues = new[] { "queue1" },
WorkerCount = 1
};
using (new BackgroundJobServer(serverOptions, storage))
{
Log("Hangfire Server 1 started. Press any key to exit...");
RecurringJob.AddOrUpdate(
Guid.NewGuid().ToString(),
() => JobThree(),
"* * * * *",
queue: "queue1");
Console.ReadKey();
}
}
private static void RunServer2(JobStorage storage)
{
Task.Factory.StartNew(() => RunServer2Client1Queue(storage));
}
private static void RunServer2Client1Queue(JobStorage storage)
{
Thread.Sleep(2000);
var serverOptions = new BackgroundJobServerOptions
{
ShutdownTimeout = TimeSpan.FromMinutes(5),
ServerName = $"{Environment.MachineName}2.{Guid.NewGuid()}",
Queues = new[] { "queue1" },
WorkerCount = 1
};
using (new BackgroundJobServer(serverOptions, storage))
{
Log("Hangfire Server 2 started. Press any key to exit...");
RecurringJob.AddOrUpdate(
Guid.NewGuid().ToString(),
() => JobThree(),
"* * * * *",
queue: "queue1");
Console.ReadKey();
}
}
public static void JobThree()
{
// implement guard if not working
Thread.Sleep(3000);
Log($"JobThree, current time:{DateTime.Now.ToString()}");
}
public static void Log(string msg, LogLevel level = LogLevel.Info)
{
LogProvider.GetLogger("Main").Log(level, () => { return msg; });
}
}
}