public override void AnnounceServer(string serverId, ServerContext context)
        {
            var transaction = Redis.CreateTransaction();

            transaction.SetAddAsync(RedisStorage.Prefix + "servers", serverId);

            transaction.HashSetAsync(
                string.Format(RedisStorage.Prefix + "server:{0}", serverId),
                new Dictionary<string, string>
                    {
                        { "WorkerCount", context.WorkerCount.ToString(CultureInfo.InvariantCulture) },
                        { "StartedAt", JobHelper.SerializeDateTime(DateTime.UtcNow) },
                    }.ToHashEntries());

            foreach (var queue in context.Queues)
            {
                var queue1 = queue;
                transaction.ListRightPushAsync(
                    string.Format(RedisStorage.Prefix + "server:{0}:queues", serverId),
                    queue1);
            }

            transaction.Execute();

        }
Esempio n. 2
0
        public ServerBootstrapperFacts()
        {
            _context = new ServerContext();
            _storage = new Mock<JobStorage>();
            _supervisor = new Mock<IServerSupervisor>();
            _supervisorFactory = new Lazy<IServerSupervisor>(() => _supervisor.Object);
            _connection = new Mock<IStorageConnection>();
            _cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(50));

            _storage.Setup(x => x.GetConnection()).Returns(_connection.Object);
        }
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException("serverId");
            if (context == null) throw new ArgumentNullException("context");

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            _storage.UseConnection(connection =>
            {
                string tableName = string.Format("[{0}.Server]", _storage.GetSchemaName());
                // select by serverId
                var serverResult = connection.Query<Entities.Server>(
                    string.Format("select * from {0} where Id = @id", tableName),
                    new { id = serverId }).SingleOrDefault();

                if (serverResult == null)
                {
                    // if not found insert
                    connection.Execute(string.Format("insert into {0} (Id, Data, LastHeartbeat) values (@id, @data, @lastHeartbeat)", tableName),
                        new { id = serverId, data = JobHelper.ToJson(data), lastHeartbeat = DateTime.UtcNow });
                }
                else
                {
                    // if found, update data + heartbeart
                    connection.Execute(string.Format("update {0} set Data = @data, LastHeartbeat = @lastHeartbeat where Id = @id", tableName),
                        new { id = serverId, data = JobHelper.ToJson(data), lastHeartbeat = DateTime.UtcNow });
                }
            }, true);

            //_connection.Execute(
            //    @";merge [HangFire.Server] with (holdlock) as Target "
            //    + @"using (VALUES (@id, @data, @heartbeat)) as Source (Id, Data, Heartbeat) "  // << SOURCE
            //    + @"on Target.Id = Source.Id "
            //    + @"when matched then UPDATE set Data = Source.Data, LastHeartbeat = Source.Heartbeat "
            //    + @"when not matched then INSERT (Id, Data, LastHeartbeat) values (Source.Id, Source.Data, Source.Heartbeat);",
            //    new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
        }
Esempio n. 4
0
        public ServerBootstrapper(
            string serverId,
            ServerContext context,
            JobStorage storage,
            Lazy<IServerSupervisor> supervisorFactory)
        {
            if (storage == null) throw new ArgumentNullException("storage");
            if (serverId == null) throw new ArgumentNullException("serverId");
            if (context == null) throw new ArgumentNullException("context");
            if (supervisorFactory == null) throw new ArgumentNullException("supervisorFactory");

            _storage = storage;
            _serverId = serverId;
            _context = context;
            _supervisorFactory = supervisorFactory;

            if (!RunningWithMono()) 
            {
                _globalMutex = new Mutex (false, String.Format (@"Global\{0}_{1}", BootstrapperId, _serverId));
            }
        }
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            serverId.ThrowIfNull("serverId");
            context.ThrowIfNull("context");

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            using (var repository = new Repository()) {
                var servers = repository.Session.Query<RavenServer>()
                                .Where(t => t.Id == serverId)
                                .ToList();

                var queues = servers.SelectMany(t => JobHelper.FromJson<ServerData>(t.Data).Queues).ToList();
                queues.AddRange(data.Queues.Select(t => t).ToList());
                data.Queues = queues.ToArray();

                data.WorkerCount += servers.Select(t => JobHelper.FromJson<ServerData>(t.Data).WorkerCount).Sum(t => t);

                foreach (var item in servers) {
                    repository.Delete(item);
                }

                var server = new RavenServer
                {
                    Data = JobHelper.ToJson(data),
                    Id = serverId,
                    LastHeartbeat = DateTime.UtcNow
                };

                repository.Save(server);
            }
        }
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            serverId.ThrowIfNull("serverId");
            context.ThrowIfNull("context");

            using (var repository = _storage.Repository.OpenSession()) {
                var id = Repository.GetId(typeof(RavenServer), serverId);
                var server = repository.Load<RavenServer>(id);

                if (server == null) {
                    server = new RavenServer() {
                        Id = id,
                        Data = new RavenServer.ServerData()
                    };

                    repository.Store(server);
                }

                // Merge Queues and WorkerCount
                server.Data.WorkerCount += context.WorkerCount;
                server.Data.Queues = context.Queues.Concat(server.Data.Queues ?? new List<string>()).Distinct();

                server.LastHeartbeat = DateTime.UtcNow;

                repository.SaveChanges();
            }
        }
Esempio n. 7
0
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException(nameof(serverId));
            if (context == null) throw new ArgumentNullException(nameof(context));

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            _storage.UseConnection(connection =>
            {
                connection.Execute(
$@";merge [{_storage.SchemaName}].Server with (holdlock) as Target
using (VALUES (@id, @data, @heartbeat)) as Source (Id, Data, Heartbeat)
on Target.Id = Source.Id
when matched then update set Data = Source.Data, LastHeartbeat = Source.Heartbeat
when not matched then insert (Id, Data, LastHeartbeat) values (Source.Id, Source.Data, Source.Heartbeat);",
                    new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
            });
        }
        private static ServerContext GetServerContext(IReadOnlyDictionary<string, object> properties)
        {
            var serverContext = new ServerContext();

            if (properties.ContainsKey("Queues"))
            {
                var array = properties["Queues"] as string[];
                if (array != null)
                {
                    serverContext.Queues = array;
                }
            }

            if (properties.ContainsKey("WorkerCount"))
            {
                serverContext.WorkerCount = (int)properties["WorkerCount"];
            }
            return serverContext;
        }
Esempio n. 9
0
		public override void AnnounceServer(string serverId, ServerContext context)
		{
			if (serverId == null) throw new ArgumentNullException("serverId");
			if (context == null) throw new ArgumentNullException("context");

			var data = new ServerData
			{
				WorkerCount = context.WorkerCount,
				Queues = context.Queues,
				StartedAt = DateTime.UtcNow,
			};

			// select by serverId
			var serverResult = _connection.Query<Entities.Server>(
				"select * from [HangFire.Server] where Id = @id",
				new {id = serverId}).SingleOrDefault();

			if (serverResult == null)
			{
				// if not found insert
				_connection.Execute(
					"insert into [HangFire.Server] (Id, Data, LastHeartbeat) values (@id, @data, datetime('now', 'utc'))",
					new {id = serverId, data = JobHelper.ToJson(data)});
			}
			else
			{
				// if found, update data + heartbeart
				_connection.Execute(
					"update [HangFire.Server] set Data = @data, LastHeartbeat = datetime('now', 'utc') where Id = @id",
					new { id = serverId, data = JobHelper.ToJson(data) });
			}

			//_connection.Execute(
			//    @";merge [HangFire.Server] with (holdlock) as Target "
			//    + @"using (VALUES (@id, @data, @heartbeat)) as Source (Id, Data, Heartbeat) "  // << SOURCE
			//    + @"on Target.Id = Source.Id "
			//    + @"when matched then UPDATE set Data = Source.Data, LastHeartbeat = Source.Heartbeat "
			//    + @"when not matched then INSERT (Id, Data, LastHeartbeat) values (Source.Id, Source.Data, Source.Heartbeat);",
			//    new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
		}
Esempio n. 10
0
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException("serverId");
            if (context == null) throw new ArgumentNullException("context");

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            _connection.Execute(
                @";merge HangFire.Server with (holdlock) as Target "
                + @"using (VALUES (@id, @data, @heartbeat)) as Source (Id, Data, Heartbeat) "
                + @"on Target.Id = Source.Id "
                + @"when matched then update set Data = Source.Data, LastHeartbeat = Source.Heartbeat "
                + @"when not matched then insert (Id, Data, LastHeartbeat) values (Source.Id, Source.Data, Source.Heartbeat);",
                new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
        }
        public void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException("serverId");
            if (context == null) throw new ArgumentNullException("context");

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            string sql = @"
WITH ""inputvalues"" AS (
    SELECT @id ""id"", @data ""data"", NOW() AT TIME ZONE 'UTC' ""lastheartbeat""
), ""updatedrows"" AS ( 
    UPDATE """ + _options.SchemaName + @""".""server"" ""updatetarget""
    SET ""data"" = ""inputvalues"".""data"", ""lastheartbeat"" = ""inputvalues"".""lastheartbeat""
    FROM ""inputvalues""
    WHERE ""updatetarget"".""id"" = ""inputvalues"".""id""
    RETURNING ""updatetarget"".""id""
)
INSERT INTO """ + _options.SchemaName + @""".""server""(""id"", ""data"", ""lastheartbeat"")
SELECT ""id"", ""data"", ""lastheartbeat"" FROM ""inputvalues"" ""insertvalues""
WHERE NOT EXISTS (
    SELECT 1 
    FROM ""updatedrows"" 
    WHERE ""updatedrows"".""id"" = ""insertvalues"".""id"" 
);
";

            _connection.Execute(sql,
                new { id = serverId, data = JobHelper.ToJson(data) });
        }
Esempio n. 12
0
        internal virtual IServerSupervisor GetBootstrapSupervisor()
        {
            var context = new ServerContext
            {
                Queues = _options.Queues,
                WorkerCount = _options.WorkerCount
            };

            var bootstrapper = new ServerBootstrapper(
                _serverId, 
                context, 
                _storage, 
                new Lazy<IServerSupervisor>(GetSupervisors));

            return CreateSupervisor(
                bootstrapper, 
                new ServerSupervisorOptions
                {
                    ShutdownTimeout = _options.ShutdownTimeout
                });
        }
        public void AnnounceServer_CreatesOrUpdatesARecord()
        {
            UseConnection((database, connection) =>
            {
                var context1 = new ServerContext
                {
                    Queues = new[] { "critical", "default" },
                    WorkerCount = 4
                };
                connection.AnnounceServer("server", context1);

                var server = AsyncHelper.RunSync(() => database.Server.Find(new BsonDocument()).ToListAsync()).Single();
                Assert.Equal("server", server.Id);
                Assert.True(((string)server.Data).StartsWith(
                    "{\"WorkerCount\":4,\"Queues\":[\"critical\",\"default\"],\"StartedAt\":"),
                    server.Data);
                Assert.NotNull(server.LastHeartbeat);

                var context2 = new ServerContext
                {
                    Queues = new[] { "default" },
                    WorkerCount = 1000
                };
                connection.AnnounceServer("server", context2);
                var sameServer = AsyncHelper.RunSync(() => database.Server.Find(new BsonDocument()).ToListAsync()).Single();
                Assert.Equal("server", sameServer.Id);
                Assert.Contains("1000", sameServer.Data);
            });
        }
        public void AnnounceServer_CreatesOrUpdatesARecord()
        {
            UseConnections((sql, connection) =>
            {
                var context1 = new ServerContext
                {
                    Queues = new[] { "critical", "default" },
                    WorkerCount = 4
                };
                connection.AnnounceServer("server", context1);

                var server = sql.Query(string.Format(@"SELECT * FROM ""{0}.SERVER""", _options.Prefix)).Single();
                Assert.Equal("server", server.ID);
                Assert.True(((string)server.DATA).StartsWith(
                    "{\"WorkerCount\":4,\"Queues\":[\"critical\",\"default\"],\"StartedAt\":"),
                    server.DATA);
                Assert.NotNull(server.LASTHEARTBEAT);

                var context2 = new ServerContext
                {
                    Queues = new[] { "default" },
                    WorkerCount = 1000
                };
                connection.AnnounceServer("server", context2);
                var sameServer = sql.Query(string.Format(@"SELECT * FROM ""{0}.SERVER""", _options.Prefix)).Single();
                Assert.Equal("server", sameServer.ID);
                Assert.Contains("1000", sameServer.DATA);
            });
        }
Esempio n. 15
0
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException(nameof(serverId));
            if (context == null) throw new ArgumentNullException(nameof(context));

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            _storage.UseConnection(connection =>
            {
                var sql =
                    _storage.SqlServerSettings != null &&
                    !string.IsNullOrEmpty(_storage.SqlServerSettings.AnnounceServerSql)
                        ? _storage.SqlServerSettings.AnnounceServerSql
                        : @";merge [{0}].Server with (holdlock) as Target "
                    + @"using (VALUES (@id, @data, @heartbeat)) as Source (Id, Data, Heartbeat) "
                    + @"on Target.Id = Source.Id "
                    + @"when matched then update set Data = Source.Data, LastHeartbeat = Source.Heartbeat "
                    +
                    @"when not matched then insert (Id, Data, LastHeartbeat) values (Source.Id, Source.Data, Source.Heartbeat);";

                    connection.Execute(
                        string.Format(sql, _storage.SchemaName),
                        new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
            });
        }
        public void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null) throw new ArgumentNullException("serverId");
            if (context == null) throw new ArgumentNullException("context");

            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            _connection.Execute(string.Format(@"
                MERGE INTO ""{0}.SERVER"" target
                USING (SELECT CAST(@id AS VARCHAR(50) CHARACTER SET UNICODE_FSS), CAST(@data AS BLOB SUB_TYPE 1 SEGMENT SIZE 80 CHARACTER SET UNICODE_FSS), CAST(@heartbeat AS TIMESTAMP) FROM rdb$database) source (id, data, heartbeat)
                ON target.id = source.id
                WHEN MATCHED THEN UPDATE SET target.data = source.data, target.lastheartbeat = source.heartbeat
                WHEN NOT MATCHED THEN INSERT (id, data, lastheartbeat) VALUES (source.id, source.data, source.heartbeat);", _options.Prefix),
                new { id = serverId, data = JobHelper.ToJson(data), heartbeat = DateTime.UtcNow });
        }
Esempio n. 17
0
		public void AnnounceServer(string serverId, ServerContext context)
		{
			if (serverId == null)
				throw new ArgumentNullException("serverId");

			if (context == null)
				throw new ArgumentNullException("context");

			var data = new ServerDataDto
			{
				WorkerCount = context.WorkerCount,
				Queues = context.Queues,
				StartedAt = _database.GetServerTimeUtc(),
			};

			_database.Server.Update(Query<ServerDto>.EQ(_ => _.Id, serverId),
				Update.Combine(Update<ServerDto>.Set(_ => _.Data, JobHelper.ToJson(data)), Update<ServerDto>.Set(_ => _.LastHeartbeat, _database.GetServerTimeUtc())),
				UpdateFlags.Upsert);
		}
Esempio n. 18
0
        public void AnnounceServer(string serverId, ServerContext context)
        {
            using (var transaction = Redis.CreateTransaction())
            {
                transaction.QueueCommand(x => x.AddItemToSet(
                    RedisStorage.Prefix + "servers", serverId));

                transaction.QueueCommand(x => x.SetRangeInHash(
                    String.Format(RedisStorage.Prefix + "server:{0}", serverId),
                    new Dictionary<string, string>
                        {
                            { "WorkerCount", context.WorkerCount.ToString(CultureInfo.InvariantCulture) },
                            { "StartedAt", JobHelper.SerializeDateTime(DateTime.UtcNow) },
                        }));

                foreach (var queue in context.Queues)
                {
                    var queue1 = queue;
                    transaction.QueueCommand(x => x.AddItemToList(
                        String.Format(RedisStorage.Prefix + "server:{0}:queues", serverId),
                        queue1));
                }

                transaction.Commit();
            }
        }
        public void AnnounceServer(string serverId, ServerContext context)
        {
            serverId.Should().NotBeNullOrEmpty();
            context.Should().NotBeNull();

            Debug.WriteLine("Announce server " + serverId);


            var data = new ServerData
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = DateTime.UtcNow,
            };

            UsingDatabase(db => db.InsertOrReplace(new Entities.Server()
            {
                Id = serverId,
                Data = JsonConvert.SerializeObject(data),
                LastHeartbeat = DateTime.UtcNow
            }));


        }
Esempio n. 20
0
        public override void AnnounceServer(string serverId, ServerContext context)
        {
            if (serverId == null)
                throw new ArgumentNullException("serverId");

            if (context == null)
                throw new ArgumentNullException("context");

            var data = new ServerDataDto
            {
                WorkerCount = context.WorkerCount,
                Queues = context.Queues,
                StartedAt = _database.GetServerTimeUtc(),
            };

            _database.Server.UpdateManyAsync(Builders<ServerDto>.Filter.Eq(_ => _.Id, serverId),
                Builders<ServerDto>.Update.Combine(Builders<ServerDto>.Update.Set(_ => _.Data, JobHelper.ToJson(data)), Builders<ServerDto>.Update.Set(_ => _.LastHeartbeat, _database.GetServerTimeUtc())),
                new UpdateOptions { IsUpsert = true });
        }
		public void AnnounceServer_CreatesOrUpdatesARecord()
		{
			UseConnections((sql, connection) =>
			{
				var context1 = new ServerContext
				{
					Queues = new[] {"critical", "default"},
					WorkerCount = 4
				};
				connection.AnnounceServer("server", context1);

				var server = sql.Query(@"select * from """ + GetSchemaName() + @""".""server""").Single();
				Assert.Equal("server", server.id);
				Assert.True(((string) server.data).StartsWith(
					"{\"WorkerCount\":4,\"Queues\":[\"critical\",\"default\"],\"StartedAt\":"),
					server.data);
				Assert.NotNull(server.lastheartbeat);

				var context2 = new ServerContext
				{
					Queues = new[] {"default"},
					WorkerCount = 1000
				};
				connection.AnnounceServer("server", context2);
				var sameServer = sql.Query(@"select * from """ + GetSchemaName() + @""".""server""").Single();
				Assert.Equal("server", sameServer.id);
				Assert.Contains("1000", sameServer.data);
			});
		}
 // Servers
 public abstract void AnnounceServer(string serverId, ServerContext context);