Example #1
0
            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);
        }