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