void Initialise() { using (var session = store.OpenSession()) { session.Query <KnownEndpoint, KnownEndpointIndex>() .Lazily(endpoints => { foreach (var knownEndpoint in endpoints.Where(p => p.Monitored)) { statusProvider.RegisterNewEndpoint(knownEndpoint.EndpointDetails); } }); session.Query <Heartbeat, HeartbeatsIndex>() .Lazily(heartbeats => { foreach (var heartbeat in heartbeats) { if (heartbeat.Disabled) { statusProvider.DisableMonitoring(heartbeat.EndpointDetails); continue; } statusProvider.EnableMonitoring(heartbeat.EndpointDetails); if (heartbeat.ReportedStatus == Status.Beating) { statusProvider.RegisterHeartbeatingEndpoint(heartbeat.EndpointDetails, heartbeat.LastReportAt); } else { statusProvider.RegisterEndpointThatFailedToHeartbeat(heartbeat.EndpointDetails); } } }); session.Advanced.Eagerly.ExecuteAllPendingLazyOperations(); } }
public void Handle(EndpointHeartbeat message) { if (string.IsNullOrEmpty(message.EndpointName)) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the EndpointName in the schema"); } if (string.IsNullOrEmpty(message.Host)) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the Host in the schema"); } if (message.HostId == Guid.Empty) { throw new Exception("Received an EndpointHeartbeat message without proper initialization of the HostId in the schema"); } var id = DeterministicGuid.MakeId(message.EndpointName, message.HostId.ToString()); var key = store.Conventions.DefaultFindFullDocumentKeyFromNonStringIdentifier(id, typeof(Heartbeat), false); var endpointDetails = new EndpointDetails { HostId = message.HostId, Host = message.Host, Name = message.EndpointName }; var patchResult = store.DatabaseCommands.Patch(key, new ScriptedPatchRequest { Script = @" if(new Date(lastReported) <= new Date(this.LastReportAt)) { return; } if(this.ReportedStatus === deadStatus) { output('wasDead'); } this.LastReportAt = lastReported; this.ReportedStatus = reportedStatus; ", Values = { { "lastReported", message.ExecutedAt }, { "reportedStatus", (int)Status.Beating }, { "deadStatus", (int)Status.Dead }, } }, new ScriptedPatchRequest { Script = @" this.LastReportAt = lastReported; this.ReportedStatus = reportedStatus; this.EndpointDetails = { 'Host': endpointDetails_Host, 'HostId': endpointDetails_HostId, 'Name': endpointDetails_Name }; this.Disabled = false; output('isNew'); ", Values = { { "lastReported", message.ExecutedAt }, { "reportedStatus", (int)Status.Beating }, { "endpointDetails_Host", endpointDetails.Host }, { "endpointDetails_HostId", endpointDetails.HostId.ToString() }, { "endpointDetails_Name", endpointDetails.Name } } }, RavenJObject.Parse($@" {{ ""Raven-Entity-Name"": ""{store.Conventions.GetTypeTagName(typeof(Heartbeat))}"", ""Raven-Clr-Type"": ""{typeof(Heartbeat).AssemblyQualifiedName}"" }}")); var debugStatements = patchResult.Value <RavenJArray>("Debug"); var ravenJToken = debugStatements.SingleOrDefault(); bool isNew = false, wasDead = false; if (ravenJToken != null) { var result = ravenJToken.Value <string>(); isNew = result == "isNew"; wasDead = result == "wasDead"; } if (isNew) // New endpoint heartbeat { bus.Publish(new HeartbeatingEndpointDetected { Endpoint = endpointDetails, DetectedAt = message.ExecutedAt }); } else if (wasDead) { bus.Publish(new EndpointHeartbeatRestored { Endpoint = endpointDetails, RestoredAt = message.ExecutedAt }); } statusProvider.RegisterHeartbeatingEndpoint(endpointDetails, message.ExecutedAt); }