Run one job queue in the same time on multiple servers

Tags: #<Tag:0x00007fe1d974fa00>

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; });
        }
    }
}

entries in database: hangfire.lock are missing

Since Hangfire 1.5 multiple servers are automatically supported, according to the following doc.
https://docs.hangfire.io/en/latest/background-processing/running-multiple-server-instances.html

How ever you have an option to setup method to run in a specific Q.