public void Dispatch(ImmutableEnvelope e) { var commands = e.Items.Select(i => (ICommand <IIdentity>)i.Content).ToList(); var id = commands.First().Id; var builder = new StringBuilder(); var old = Context.SwapFor(s => builder.AppendLine(s)); Applied results; try { results = Load(commands); } finally { Context.SwapFor(old); } var s1 = builder.ToString(); if (!String.IsNullOrEmpty(s1)) { Context.Debug(s1.TrimEnd('\r', '\n')); } AppendToStream(id, e.EnvelopeId, results, s1); PublishEvents(id, results); }
public void when_try_release_where_envelope_null() { var memoryQuarantine = new MemoryQuarantine(); var immutableEnvelope = new ImmutableEnvelope("EnvId", DateTime.UtcNow, new SerializerTest1 { Name = "Test1" }, new[] { new MessageAttribute("key1", "val1"), new MessageAttribute("key2", "val2"), }); var result0 = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); memoryQuarantine.TryRelease(null); var result1 = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); var result2 = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); var result3 = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); var result4 = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); Assert.IsFalse(result0); Assert.IsFalse(result1); Assert.IsFalse(result2); Assert.IsTrue(result3); Assert.IsFalse(result4); }
public byte[] SaveEnvelopeData(ImmutableEnvelope envelope) { Envelope = envelope; Buffer = new byte[] { 1, 2, 3 }; return Buffer; }
void PublishEvent(ImmutableEnvelope e) { if (1 != e.Items.Length) { throw new InvalidOperationException( @"Events that go through the router can't be batched! If you are publishing event sourcing messages, break them into the separate envelopes."); } // usual approach is to route based on the 'topic' field, which is // set explicitly by the sender // while migrating to AMQP servers, this functionality will be // supported by the infrastructure var name = e.Items[0].MappedType.FullName; var queues = _routing .Where(t => t.Item1.IsMatch(name)) .SelectMany(m => m.Item2) .Distinct() .Select(_queueFactory.GetWriteQueue); // if server crashes here, that's no problem, since we'll resend later // and duplicates will be handled by the infrastructure foreach (var queue in queues) { queue.PutMessage(_streamer.SaveEnvelopeData(e)); } }
void ISingleThreadMessageDispatcher.DispatchMessage(ImmutableEnvelope message) { // empty message, hm... if (message.Items.Length == 0) return; // verify that all consumers are available foreach (var item in message.Items) { if (!_messageConsumers.ContainsKey(item.MappedType)) { throw new InvalidOperationException("Couldn't find consumer for " + item.MappedType); } } using (var scope = _strategy.BeginEnvelopeScope()) { foreach (var item in message.Items) { var consumerType = _messageConsumers[item.MappedType]; scope.Dispatch(consumerType, message, item); } scope.Complete(); } }
public void PutMessage(ImmutableEnvelope envelope) { if (envelope.DeliverOnUtc < DateTime.UtcNow) { _target.PutMessage(_streamer.SaveEnvelopeData(envelope)); return; } // save to the store var id = Interlocked.Increment(ref _universalCounter); var fileName = string.Format("{0:yyyy-MM-dd-HH-mm-ss}-{1:00000000}-{2}.future", envelope.DeliverOnUtc, id, _suffix); // persist var item = _storage.GetItem(fileName); var data = _streamer.SaveEnvelopeData(envelope); item.Write(x => x.Write(data, 0, data.Length)); // add to in-memory scheduler lock (_scheduler) { _scheduler.Add(new Record(fileName, envelope.DeliverOnUtc)); } }
public void when_more_try_to_quarantine() { var memoryQuarantine = new MemoryQuarantine(); var immutableEnvelope = new ImmutableEnvelope("EnvId", DateTime.UtcNow, new SerializerTest1 { Name = "Test1" }, new[] { new MessageAttribute("key1", "val1"), new MessageAttribute("key2", "val2"), }); const int callCount = 30; var results = new bool[callCount]; for (int i = 0; i < callCount; i++) { results[i] = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); } for (int i = 0; i < callCount; i++) { if ((i + 1) % 4 == 0) Assert.IsTrue(results[i]); else Assert.IsFalse(results[i]); } }
public void DispatchMessage(ImmutableEnvelope envelope) { if (envelope.Items.Length != 1) throw new InvalidOperationException( "Batch message arrived to the shared scope. Are you batching events or dispatching commands to shared scope?"); // we get failure if one of the subscribers fails // hence, if any of the handlers fail - we give up var item = envelope.Items[0]; Type[] consumerTypes; if (!_dispatcher.TryGetValue(item.MappedType, out consumerTypes)) { // else -> we don't have consumers. It's OK for the event _observer.Notify(new EventHadNoConsumers(envelope.EnvelopeId, item.MappedType)); return; } using (var scope = _strategy.BeginEnvelopeScope()) { foreach (var consumerType in consumerTypes) { scope.Dispatch(consumerType, envelope, item); } scope.Complete(); } }
public void when_get_attribute() { var immutableEnvelope = new ImmutableEnvelope("id", DateTime.UtcNow, new object(), new[] { new MessageAttribute("attr1", "val1"), }); var attributeVal = immutableEnvelope.GetAttribute("attr1"); Assert.AreEqual("val1", attributeVal); }
public void PutMessage(ImmutableEnvelope envelope) { var fileName = string.Format("{0:yyyy-MM-dd-HH-mm-ss-ffff}-{1}", envelope.CreatedOnUtc, Guid.NewGuid()); var full = Path.Combine(_folder.FullName, fileName); var data = _streamer.SaveEnvelopeData(envelope); File.WriteAllBytes(full, data); }
void ReportFailure(string text, ImmutableEnvelope envelope) { var name = envelope.Items .Select(e => e.MappedType.Name) .Select(e => (e.Replace("Command", ""))) .FirstOrDefault() ?? "N/A"; var subject = string.Format("[Error]: Sample fails to '{0}'", name); var builder = new StringBuilder(); builder.AppendFormat( @"<p>Dear Lokad.CQRS Developer,</p><p>Something just went horribly wrong - there is a problem that I can't resolve. Please check the error log <strong>ASAP</strong>.</p> <p>Here are a few details to help you out:</p><pre><code>"); // EncoderUtil.EncodeForPre( builder.AppendLine(text); builder.AppendFormat( "</code></pre><p>Sincerely,<br /> Lokad.CQRS AI</p>"); var mail = new MailMessage() { Body = builder.ToString(), Subject = subject, IsBodyHtml = true, }; mail.To.Add(new MailAddress("*****@*****.**", "Sample Support")); _core.Send(mail); }
public void when_attribute_not_contains_and_get_default_value() { var immutableEnvelope = new ImmutableEnvelope("id", DateTime.UtcNow, new object(), new[] { new MessageAttribute("attr1", "val1"), }); var attributeVal = immutableEnvelope.GetAttribute("attr2", "default"); Assert.AreEqual("default", attributeVal); }
public EnvelopeQuarantined(Exception lastException, string dispatcher, ImmutableEnvelope envelope, byte[] message) { this.LastException = lastException; this.Dispatcher = dispatcher; this.Envelope = envelope; this.Message = message; }
public void DispatchMessage(ImmutableEnvelope envelope) { if (envelope.Items.Length != 1) { throw new InvalidOperationException( "Batch message arrived to the shared scope. Are you batching events or dispatching commands to shared scope?"); } // we get failure if one of the subscribers fails // hence, if any of the handlers fail - we give up var item = envelope.Items[0]; Type[] consumerTypes; if (!_dispatcher.TryGetValue(item.MappedType, out consumerTypes)) { // else -> we don't have consumers. It's OK for the event _observer.Notify(new EventHadNoConsumers(envelope.EnvelopeId, item.MappedType)); return; } using (var scope = _strategy.BeginEnvelopeScope()) { foreach (var consumerType in consumerTypes) { scope.Dispatch(consumerType, envelope, item); } scope.Complete(); } }
public void when_more_try_to_quarantine() { var memoryQuarantine = new MemoryQuarantine(); var immutableEnvelope = new ImmutableEnvelope("EnvId", DateTime.UtcNow, new SerializerTest1 { Name = "Test1" }, new[] { new MessageAttribute("key1", "val1"), new MessageAttribute("key2", "val2"), }); const int callCount = 30; var results = new bool[callCount]; for (int i = 0; i < callCount; i++) { results[i] = memoryQuarantine.TryToQuarantine(immutableEnvelope, new Exception()); } for (int i = 0; i < callCount; i++) { if ((i + 1) % 4 == 0) { Assert.IsTrue(results[i]); } else { Assert.IsFalse(results[i]); } } }
void ISingleThreadMessageDispatcher.DispatchMessage(ImmutableEnvelope message) { // empty message, hm... if (message.Items.Length == 0) { return; } // verify that all consumers are available foreach (var item in message.Items) { if (!_messageConsumers.ContainsKey(item.MappedType)) { throw new InvalidOperationException("Couldn't find consumer for " + item.MappedType); } } using (var scope = _strategy.BeginEnvelopeScope()) { foreach (var item in message.Items) { var consumerType = _messageConsumers[item.MappedType]; scope.Dispatch(consumerType, message, item); } scope.Complete(); } }
public byte[] SaveEnvelopeData(ImmutableEnvelope envelope) { Envelope = envelope; Buffer = new byte[] { 1, 2, 3 }; return(Buffer); }
void ReportFailure(string text, ImmutableEnvelope envelope) { // we do not report failure on attempts to send mail messages // this could be a loop // we can't report them anyway (since mail sending is not available) // note, that this could be an indirect loop. if (text.Contains(typeof(SendMailMessage).Name)) { return; } if (text.Contains(typeof(MessageQuarantined).Name)) { return; } var name = envelope.Message.GetType().Name.Replace("Command", ""); var subject = string.Format("[Error]: S2 fails '{0}'", name); var builder = new StringBuilder(); builder.AppendFormat( @"<p>Support,</p><p>Something just went horribly wrong - there is a problem that I can't resolve. Please check the error log <strong>ASAP</strong>.</p> <p>Here are a few details to help you out:</p><pre>"); builder.AppendLine(WebUtility.HtmlEncode(text)); builder.AppendFormat("</pre><p>You can use S2 Maintenance to get the error details.</p><p>Sincerely,<br /> Hub AI</p>"); // if we don't fit in the limits if (text.Length >= 1024 * 1024) { const string body = "Subj, please notify Lokad support team immediately"; const string subj = "[S2]: Quarantine overflow"; var message = new SendMailMessage(new[] { new Email("*****@*****.**") }, subj, body, false, null, null, null); _writer.SendCommand(message, true); // fail immediately return; } var to = new[] { new Email("*****@*****.**", "Salescast Support"), new Email("*****@*****.**", "Rinat Abdullin") }; var cmd = new SendMailMessage(to, subject, builder.ToString(), true, null, null, null); _writer.SendCommand(cmd, true); var buffer = _streamer.SaveEnvelopeData(envelope); var names = new[] { ContractEvil.GetContractReference(envelope.Message.GetType()) }; _writer.Publish(new MessageQuarantined(text, buffer, names, DateTime.UtcNow)); }
public byte[] SaveEnvelopeData(ImmutableEnvelope envelope) { // string contract, Guid messageId, Uri sender, var itemContracts = new MessageContract[envelope.Items.Length]; using (var content = new MemoryStream()) { int position = 0; for (int i = 0; i < envelope.Items.Length; i++) { var item = envelope.Items[i]; string name; if (!_dataSerializer.TryGetContractNameByType(item.MappedType, out name)) { var error = string.Format("Failed to find contract name for {0}", item.MappedType); throw new InvalidOperationException(error); } // normal serializers have a nasty habbit of closing the stream after they are done // we can suppress that or use a wrapper now instead using (var itemStream = new MemoryStream()) { _dataSerializer.Serialize(item.Content, itemStream); var bytes = itemStream.ToArray(); content.Write(bytes, 0, bytes.Length); } int size = (int)content.Position - position; var attribContracts = EnvelopeConvert.ItemAttributesToContract(item.GetAllAttributes()); itemContracts[i] = new MessageContract(name, size, position, attribContracts); position += size; } var envelopeAttribs = EnvelopeConvert.EnvelopeAttributesToContract(envelope.GetAllAttributes()); var contract = new EnvelopeContract(envelope.EnvelopeId, envelopeAttribs, itemContracts, envelope.DeliverOnUtc, envelope.CreatedOnUtc); using (var stream = new MemoryStream()) { // skip header stream.Seek(EnvelopeHeaderContract.FixedSize, SeekOrigin.Begin); // save envelope attributes _envelopeSerializer.SerializeEnvelope(stream, contract); var envelopeBytes = stream.Position - EnvelopeHeaderContract.FixedSize; // copy data content.WriteTo(stream); // write the header stream.Seek(0, SeekOrigin.Begin); var header = new EnvelopeHeaderContract(EnvelopeHeaderContract.Schema2DataFormat, envelopeBytes, 0); header.WriteToStream(stream); return(stream.ToArray()); } } }
public static string PrintToString(this ImmutableEnvelope envelope, Func <object, string> serializer) { using (var writer = new StringWriter(CultureInfo.InvariantCulture)) { PrintTo(envelope, writer, serializer); writer.Flush(); return(writer.GetStringBuilder().ToString()); } }
static void CallHandlers(RedirectToDynamicEvent functions, ImmutableEnvelope aem) { var e = aem.Message as IEvent; if (e != null) { functions.InvokeEvent(e); } }
public bool TryToQuarantine(ImmutableEnvelope context, Exception ex) { // quit immediately, we don't want an endless cycle! //if (context.Items.Any(m => m.Content is MessageQuarantined)) // return true; var quarantined = _quarantine.TryToQuarantine(context, ex); try { var file = string.Format("{0:yyyy-MM-dd}-{1}-engine.txt", DateTime.UtcNow, context.EnvelopeId.ToLowerInvariant()); var data = ""; if (_root.Exists(file)) { using (var stream = _root.OpenRead(file)) using (var reader = new StreamReader(stream)) { data = reader.ReadToEnd(); } } var builder = new StringBuilder(data); if (builder.Length == 0) { DescribeMessage(builder, context); } builder.AppendLine("[Exception]"); builder.AppendLine(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); builder.AppendLine(ex.ToString()); builder.AppendLine(); var text = builder.ToString(); using (var stream = _root.OpenWrite(file)) using (var writer = new StreamWriter(stream)) { writer.Write(text); } if (quarantined) { ReportFailure(text, context); } } catch (Exception x) { SystemObserver.Notify(x.ToString()); } return quarantined; }
public bool TryToQuarantine(ImmutableEnvelope context, Exception ex) { // quit immediately, we don't want an endless cycle! //if (context.Items.Any(m => m.Content is MessageQuarantined)) // return true; var quarantined = _quarantine.TryToQuarantine(context, ex); try { var file = string.Format("{0:yyyy-MM-dd}-{1}-engine.txt", DateTime.UtcNow, context.EnvelopeId.ToLowerInvariant()); var data = ""; if (_root.Exists(file)) { using (var stream = _root.OpenRead(file)) using (var reader = new StreamReader(stream)) { data = reader.ReadToEnd(); } } var builder = new StringBuilder(data); if (builder.Length == 0) { DescribeMessage(builder, context); } builder.AppendLine("[Exception]"); builder.AppendLine(DateTime.UtcNow.ToString(CultureInfo.InvariantCulture)); builder.AppendLine(ex.ToString()); builder.AppendLine(); var text = builder.ToString(); using (var stream = _root.OpenWrite(file)) using (var writer = new StreamWriter(stream)) { writer.Write(text); } if (quarantined) { ReportFailure(text, context); } } catch (Exception x) { SystemObserver.Notify(x.ToString()); } return(quarantined); }
public void when_create_instance() { var date = DateTime.UtcNow; var immutableEnvelope = new ImmutableEnvelope("id", date, new List <string>(), new[] { new MessageAttribute("attr1", "val1"), }); Assert.AreEqual("id", immutableEnvelope.EnvelopeId); Assert.AreEqual(date, immutableEnvelope.CreatedUtc); Assert.AreEqual(1, immutableEnvelope.Attributes.Count); Assert.IsTrue(immutableEnvelope.Message.GetType() == typeof(List <string>)); }
private static void MouseStatHandler(ImmutableEnvelope envelope, MouseStats stats) { var mouseMovedEvent = (MouseMoved)envelope.Items[0].Content; stats.MessagesCount++; stats.Distance += (long)Math.Sqrt(Math.Pow(mouseMovedEvent.X1 - mouseMovedEvent.X2, 2) + Math.Pow(mouseMovedEvent.Y1 - mouseMovedEvent.Y2, 2)); stats.RecordMessage(); }
public byte[] SaveEnvelopeData(ImmutableEnvelope envelope) { // string contract, Guid messageId, Uri sender, var itemContracts = new MessageContract[envelope.Items.Length]; using (var content = new MemoryStream()) { int position = 0; for (int i = 0; i < envelope.Items.Length; i++) { var item = envelope.Items[i]; string name; if (!_dataSerializer.TryGetContractNameByType(item.MappedType, out name)) { var error = string.Format("Failed to find contract name for {0}", item.MappedType); throw new InvalidOperationException(error); } // normal serializers have a nasty habbit of closing the stream after they are done // we can suppress that or use a wrapper now instead using (var itemStream = new MemoryStream()) { _dataSerializer.Serialize(item.Content, itemStream); var bytes = itemStream.ToArray(); content.Write(bytes, 0, bytes.Length); } int size = (int) content.Position - position; var attribContracts = EnvelopeConvert.ItemAttributesToContract(item.GetAllAttributes()); itemContracts[i] = new MessageContract(name, size, position, attribContracts); position += size; } var envelopeAttribs = EnvelopeConvert.EnvelopeAttributesToContract(envelope.GetAllAttributes()); var contract = new EnvelopeContract(envelope.EnvelopeId, envelopeAttribs, itemContracts, envelope.DeliverOnUtc, envelope.CreatedOnUtc); using (var stream = new MemoryStream()) { // skip header stream.Seek(EnvelopeHeaderContract.FixedSize, SeekOrigin.Begin); // save envelope attributes _envelopeSerializer.SerializeEnvelope(stream, contract); var envelopeBytes = stream.Position - EnvelopeHeaderContract.FixedSize; // copy data content.WriteTo(stream); // write the header stream.Seek(0, SeekOrigin.Begin); var header = new EnvelopeHeaderContract(EnvelopeHeaderContract.Schema2DataFormat, envelopeBytes, 0); header.WriteToStream(stream); return stream.ToArray(); } } }
static void RecordFunctionalEvent(ImmutableEnvelope envelope, MessageStore store) { if (envelope.Message is IFuncEvent) { store.RecordMessage("func", envelope); } else { throw new InvalidOperationException("Non-func event {0} landed to queue for tracking stateless events"); } }
public DomainLogDisplayItem(ImmutableEnvelope item, string session, long storeIndex) { Class = string.Join(",", item.Items.Select(s => s.MappedType.Name).ToArray()); Recorded = FormatUtil.TimeOffsetUtc(DateTime.SpecifyKind(item.CreatedOnUtc, DateTimeKind.Utc)); RecordId = item.EnvelopeId; Item = item; Session = session; AssignStyle(item, session); StoreIndex = storeIndex; Type = ' '; }
static void CallHandlers(RedirectToDynamicEvent functions, ImmutableEnvelope aem) { if (aem.Items.Length != 1) { throw new InvalidOperationException( "Unexpected number of items in envelope that arrived to projections: " + aem.Items.Length); } // we wire envelope contents to both direct message call and sourced call (with date wrapper) var content = aem.Items[0].Content; functions.InvokeEvent(content); }
public void DispatchMessage(ImmutableEnvelope message) { var entity = message.GetAttribute("to-entity", ""); if (string.IsNullOrEmpty(entity)) { throw new InvalidOperationException("Message without entity address arrived to this dispatcher"); } var commands = message.Items.Select(i => (ICommand)i.Content); Dispatch(entity, commands); }
static void CallHandlers(RedirectToDynamicEvent functions, ImmutableEnvelope aem) { foreach (var item in aem.Items) { var e = item.Content as ISampleEvent; if (e != null) { // we wire envelope contents to both direct message call and sourced call (with date wrapper) functions.InvokeEvent(e); functions.InvokeEvent(Source.For(aem.EnvelopeId, aem.CreatedOnUtc, e)); } } }
static void CallHandlers(RedirectToCommand serviceCommands, ImmutableEnvelope aem) { var content = aem.Message; var watch = Stopwatch.StartNew(); serviceCommands.Invoke(content); watch.Stop(); var seconds = watch.Elapsed.TotalSeconds; if (seconds > 10) { SystemObserver.Notify("[Warn]: {0} took {1:0.0} seconds", content.GetType().Name, seconds); } }
public static MyMessageContext Factory(ImmutableEnvelope envelope, ImmutableMessage message) { ImmutableAttribute address = envelope.GetAllAttributes().Where(a => a.Key == ContextAttributes.ORIGINATING_MACHINE).FirstOrDefault(); return(new MyMessageContext { OriginatingMachine = address == null ? "" : address.Value, CreatedOnUtc = envelope.CreatedOnUtc, DeliveredOnUtc = envelope.DeliverOnUtc, EnvelopeId = envelope.EnvelopeId, MessageIndex = message.Index, MappedType = message.MappedType.AssemblyQualifiedName }); }
CloudQueueMessage PrepareCloudMessage(ImmutableEnvelope builder) { var buffer = _streamer.SaveEnvelopeData(builder); if (buffer.Length < CloudQueueLimit) { // write message to queue return new CloudQueueMessage(buffer); } // ok, we didn't fit, so create reference message var referenceId = DateTimeOffset.UtcNow.ToString(DateFormatInBlobName) + "-" + builder.EnvelopeId; _cloudBlob.GetBlobReference(referenceId).UploadByteArray(buffer); var reference = new EnvelopeReference(builder.EnvelopeId, _cloudBlob.Uri.ToString(), referenceId); var blob = _streamer.SaveEnvelopeReference(reference); return new CloudQueueMessage(blob); }
public static EnvelopeBuilder CloneProperties(string newId, ImmutableEnvelope envelope) { if (newId == envelope.EnvelopeId) { throw new InvalidOperationException("Envelope cloned for modification should have new identity."); } var builder = new EnvelopeBuilder(newId); builder.OverrideCreatedOnUtc(envelope.CreatedOnUtc); builder.DeliverOnUtc(envelope.DeliverOnUtc); foreach (var attribute in envelope.GetAllAttributes()) { builder.AddString(attribute.Key, attribute.Value); } return(builder); }
void AssignStyle(ImmutableEnvelope item, string session) { Style += cell => { if (session == (cell.Value as string)) { cell.Style.BackColor = DomainAwareAnalysis.GetBackgroundColorForCategory(session); } else if (cell.Value is char) { cell.Style.BackColor = DomainAwareAnalysis.GetBackgroundColorForCategory(Class); } else { cell.Style.BackColor = DomainAwareAnalysis.GetBackgroundColorForContract(item.Items[0]); } }; }
private static void MouseClickHandler(ImmutableEnvelope envelope, IAtomicWriter <unit, PointsView> writer) { var mouseMovedEvent = (MouseClick)envelope.Items[0].Content; writer.AddOrUpdate(unit.it, () => new PointsView(), v => { var Point = v.Points.FirstOrDefault(p => p.X == mouseMovedEvent.X && p.Y == mouseMovedEvent.Y); if (Point != null) { Point.Intensity += 10; } else { v.Points.Add(new HeatPoint(mouseMovedEvent.X, mouseMovedEvent.Y, 50)); } }); }
public void PutMessage(ImmutableEnvelope envelope) { var buffer = _streamer.SaveEnvelopeData(envelope); var now = DateTime.UtcNow; using (var db = new DataContext(_connectionString)) { db.ExecuteCommand ( "exec [dbo].[Enqueue] {0}, {1}, {2}, {3}, {4}", _queueID, envelope.EnvelopeId, envelope.CreatedOnUtc, envelope.DeliverOnUtc < now ? now : envelope.DeliverOnUtc, buffer ); } }
public void DispatchMessage(ImmutableEnvelope message) { // We either accept commands, events or control messages. // if tis is control message var controls = message .GetAllAttributes() .Where(ia => ia.Key.StartsWith("router-")) .ToArray(); if (controls.Length > 0) { if (message.Items.Length > 0) { throw new InvalidOperationException("Router control message should not have any content"); } _storage.UpdateSingletonEnforcingNew<RouteTable>(rt => UpgradeRouterTable(controls, rt)); foreach (var attribute in controls) { Console.WriteLine(" route {0}: {1}",attribute.Key, attribute.Value); } ReloadRouteMap(); return; } // replace with your logic to detect commands. if (message.Items.All(m => m.Content is IPS_SampleCommand)) { _queueFactory.GetWriteQueue("commands").PutMessage(this._streamer.SaveEnvelopeData(message)); return; } if (message.Items.All(m => m.Content is IPS_SampleEvent)) { PublishEvent(message); return; } throw new InvalidOperationException( "This is not command, event or control message. Please handle this case."); }
public void Dispatch(Type consumerType, ImmutableEnvelope envelop, ImmutableMessage message) { using (var inner = _envelopeScope.BeginLifetimeScope(DispatchLifetimeScopeTags.MessageItemScopeTag)) { var instance = inner.Resolve(consumerType); var consume = _hint(consumerType, message.MappedType); try { _context.SetContext(envelop, message); consume.Invoke(instance, new[] { message.Content }); } catch (TargetInvocationException e) { throw InvocationUtil.Inner(e); } finally { _context.ClearContext(); } } }
public bool TryToQuarantine(ImmutableEnvelope envelope, Exception ex) { var quarantined = _quarantine.TryToQuarantine(envelope, ex); try { var item = GetStreamingItem(envelope.CreatedOnUtc, envelope.EnvelopeId); var data = ""; try { data = item.ReadText(); } catch (StreamingItemNotFoundException) { } var builder = new StringBuilder(data); if (builder.Length == 0) { builder.AppendLine(envelope.PrintToString(o => o.SerializeAndFormat())); } builder.AppendLine("[Exception]"); builder.AppendLine(DateTime.UtcNow.ToString()); builder.AppendLine(ex.ToString()); builder.AppendLine(); var text = builder.ToString(); item.WriteText(text); if (quarantined) ReportFailure(text, envelope); } catch (Exception x) { Trace.WriteLine(x.ToString()); } return quarantined; }
public void SendEnvelope(ImmutableEnvelope envelope) { var queue = GetOutboundQueue(); var data = _streamer.SaveEnvelopeData(envelope); if (Transaction.Current == null) { queue.PutMessage(data, envelope.DeliverOnUtc); SystemObserver.Notify(new EnvelopeSent(queue.Name, envelope.EnvelopeId, false, envelope.Items.Select(x => x.MappedType.Name).ToArray(), envelope.GetAllAttributes())); } else { var action = new CommitActionEnlistment(() => { queue.PutMessage(data); SystemObserver.Notify(new EnvelopeSent(queue.Name, envelope.EnvelopeId, true, envelope.Items.Select(x => x.MappedType.Name).ToArray(), envelope.GetAllAttributes())); }); Transaction.Current.EnlistVolatile(action, EnlistmentOptions.None); } }
public DispatchRecoveryFailed(Exception exception, ImmutableEnvelope envelope, string queueName) { DispatchException = exception; Envelope = envelope; QueueName = queueName; }
public void PutMessage(ImmutableEnvelope envelope) { _queue.Add(envelope); }
public EnvelopeCleanupFailed(Exception exception, string dispatcher, ImmutableEnvelope envelope) { Exception = exception; Dispatcher = dispatcher; Envelope = envelope; }
public EnvelopeQuarantined(Exception lastException, string dispatcher, ImmutableEnvelope envelope) { LastException = lastException; Dispatcher = dispatcher; Envelope = envelope; }
public EnvelopeDispatched(ImmutableEnvelope envelope, string dispatcher) { Envelope = envelope; Dispatcher = dispatcher; }
public void PutMessage(ImmutableEnvelope envelope) { SystemObserver.Notify(new EnvelopeDispatched(envelope, Name)); m_bus.Send(envelope); }
void PublishEvent(ImmutableEnvelope e) { if (1 != e.Items.Length) { throw new InvalidOperationException( @"Events that go through the router can't be batched! If you are publishing event sourcing messages, break them into the separate envelopes."); } // usual approach is to route based on the 'topic' field, which is // set explicitly by the sender // while migrating to AMQP servers, this functionality will be // supported by the infrastructure var name = e.Items[0].MappedType.FullName; var queues = _routing .Where(t => t.Item1.IsMatch(name)) .SelectMany(m => m.Item2) .Distinct() .Select(_queueFactory.GetWriteQueue); // if server crashes here, that's no problem, since we'll resend later // and duplicates will be handled by the infrastructure foreach (var queue in queues) { queue.PutMessage(this._streamer.SaveEnvelopeData(e)); } }
public EnvelopeDispatchFailed(ImmutableEnvelope envelope, string queueName, Exception exception) { Exception = exception; Envelope = envelope; QueueName = queueName; }
static void DescribeMessage(StringBuilder builder, ImmutableEnvelope context) { builder.AppendLine(context.PrintToString(o => JsvFormatter.Format(JsonSerializer.SerializeToString(o)))); }
public void TryRelease(ImmutableEnvelope context) { _quarantine.TryRelease(context); }
public void RecordMessage(string key, ImmutableEnvelope envelope) { // record properties as attributes var attribs = new List<MessageAttribute>(envelope.Attributes.Count + 2) { new MessageAttribute("id", envelope.EnvelopeId), new MessageAttribute("utc", envelope.CreatedUtc.ToString("o")) }; // copy existing attributes attribs.AddRange(envelope.Attributes); AppendToStore(key, attribs, -1, new[] { envelope.Message }); }
void ReportFailure(string text, ImmutableEnvelope envelope) { // we do not report failure on attempts to send mail messages // this could be a loop // we can't report them anyway (since mail sending is not available) // note, that this could be an indirect loop. if (text.Contains(typeof(SendMailMessage).Name)) return; if (text.Contains(typeof(MessageQuarantined).Name)) return; var name = envelope.Message.GetType().Name.Replace("Command", ""); var subject = string.Format("[Error]: S2 fails '{0}'", name); var builder = new StringBuilder(); builder.AppendFormat( @"<p>Support,</p><p>Something just went horribly wrong - there is a problem that I can't resolve. Please check the error log <strong>ASAP</strong>.</p> <p>Here are a few details to help you out:</p><pre>"); builder.AppendLine(WebUtility.HtmlEncode(text)); builder.AppendFormat("</pre><p>You can use S2 Maintenance to get the error details.</p><p>Sincerely,<br /> Hub AI</p>"); // if we don't fit in the limits if (text.Length >= 1024 * 1024) { const string body = "Subj, please notify Lokad support team immediately"; const string subj = "[S2]: Quarantine overflow"; var message = new SendMailMessage(new[] { new Email("*****@*****.**") }, subj, body, false, null, null, null); _writer.SendCommand(message, true); // fail immediately return; } var to = new[] { new Email("*****@*****.**", "Salescast Support"), new Email("*****@*****.**", "Rinat Abdullin") }; var cmd = new SendMailMessage(to, subject, builder.ToString(), true, null, null, null); _writer.SendCommand(cmd, true); var buffer = _streamer.SaveEnvelopeData(envelope); var names = new[] { ContractEvil.GetContractReference(envelope.Message.GetType()) }; _writer.Publish(new MessageQuarantined(text, buffer, names, DateTime.UtcNow)); }
public void DispatchMessage(ImmutableEnvelope message) { _dispatcher(message); }
public EnvelopeQuarantined(Exception lastException, ImmutableEnvelope envelope, string queueName) { LastException = lastException; Envelope = envelope; QueueName = queueName; }