Ejemplo n.º 1
0
        public static Action <ImmutableEnvelope> Route(Func <string, IQueueWriter> factory, IEnvelopeStreamer serializer,
                                                       ITapeStorageFactory tapes)
        {
            var events      = factory(EventsQueue);
            var timerQueue  = factory(TimerQueue);
            var entityQueue = factory(EntityQueue);
            var services    = factory(ServiceQueue);
            var log         = tapes.GetOrCreateStream(DomainLogName);

            return(envelope =>
            {
                var data = serializer.SaveEnvelopeData(envelope);
                if (!log.TryAppend(data))
                {
                    throw new InvalidOperationException("Failed to record domain log");
                }

                if (envelope.DeliverOnUtc > Current.UtcNow)
                {
                    timerQueue.PutMessage(data);
                    return;
                }
                if (envelope.Items.All(i => i.Content is ICommand <IIdentity>))
                {
                    entityQueue.PutMessage(data);
                    return;
                }
                if (envelope.Items.All(i => i.Content is IEvent <IIdentity>))
                {
                    // we can have more than 1 entity event.
                    // all entity events are routed to events as separate
                    for (int i = 0; i < envelope.Items.Length; i++)
                    {
                        var name = envelope.EnvelopeId + "-e" + i;
                        var copy = EnvelopeBuilder.CloneProperties(name, envelope);
                        copy.AddItem(envelope.Items[i]);
                        events.PutMessage(serializer.SaveEnvelopeData(copy.Build()));
                    }
                    return;
                }

                if (envelope.Items.Length != 1)
                {
                    throw new InvalidOperationException(
                        "Only entity commands or entity events can be batched");
                }
                var item = envelope.Items[0].Content;
                if (item is IFunctionalCommand)
                {
                    services.PutMessage(data);
                    return;
                }
                if (item is IFunctionalEvent || item is ISampleEvent)
                {
                    events.PutMessage(data);
                    return;
                }
                throw new InvalidOperationException(string.Format("Unroutable message {0}", item));
            });
        }
Ejemplo n.º 2
0
        void RunScheduler(CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                try
                {
                    var           date  = DateTime.UtcNow;
                    const int     count = 100;
                    List <Record> list;

                    lock (_scheduler)
                    {
                        list = _scheduler.Where(r => r.DeliverOn <= date).Take(count).ToList();
                    }

                    if (list.Count > 0)
                    {
                        foreach (var record in list)
                        {
                            var item = _storage.GetItem(record.Name);

                            ImmutableEnvelope e;
                            using (var mem = new MemoryStream())
                            {
                                item.ReadInto((x, y) => y.CopyTo(mem));
                                e = _streamer.ReadAsEnvelopeData(mem.ToArray());
                            }

                            // we need to reset the timer here.
                            var newEnvelope = EnvelopeBuilder.CloneProperties(e.EnvelopeId + "-future", e);
                            newEnvelope.DeliverOnUtc(DateTime.MinValue);
                            newEnvelope.AddString("original-id", e.EnvelopeId);
                            foreach (var message in e.Items)
                            {
                                newEnvelope.AddItem(message);
                            }
                            _target.PutMessage(_streamer.SaveEnvelopeData(newEnvelope.Build()));

                            item.Delete();
                            lock (_scheduler)
                            {
                                _scheduler.Remove(record);
                            }
                        }
                    }

                    token.WaitHandle.WaitOne(5000);
                }
                catch (Exception ex)
                {
                    Trace.WriteLine(ex);
                    token.WaitHandle.WaitOne(2000);
                }
            }
        }
Ejemplo n.º 3
0
        void LoadEventsTill(long maxVersion, bool sync, ToolStripItem sender)
        {
            var context = TaskScheduler.FromCurrentSynchronizationContext();

            _domainGrid.DataSource = new[] { new { Message = "Loading..." } };

            var start = sync ? _client.SyncLog(s => Log(s)) : Task.Factory.StartNew(() => { });

            start.ContinueWith(t =>
            {
                var list = new List <DomainLogDisplayItem>();

                long maxCount;
                if (!Int64.TryParse(txtCount.Text, out maxCount))
                {
                    maxCount = MaxCount;
                }

                MaxCount = (int)maxCount;

                _client.ObserveTill(maxVersion, (int)maxCount, s =>
                {
                    var envelope = _serializer.ReadAsEnvelopeData(s.Data);


                    for (int i = 0; i < envelope.Items.Length; i++)
                    {
                        var item    = envelope.Items[i];
                        var session = DomainAwareAnalysis.GetCategoryNames(item);
                        // clone batch envelopes into separate ones
                        var clone = EnvelopeBuilder.CloneProperties(envelope.EnvelopeId + "-" + i, envelope);
                        clone.AddItem(item.Content);
                        list.Add(new DomainLogDisplayItem(clone.Build(), session, s.Version));
                    }
                });
                return(list);
            }).ContinueWith(x =>
            {
                if (x.Exception != null)
                {
                    Log("Exception: {0}", x.Exception.Message);
                    Trace.WriteLine(x.Exception);
                    return;
                }
                var items = x.Result;
                if (items.Count > 0)
                {
                    var min    = items.Min(i => i.StoreIndex) - 1;
                    _currentId = min;
                }

                _domainGrid.DataSource  = items;
                tabControl1.SelectedTab = _domainLogTab;

                // paint

                foreach (DataGridViewRow dataGridViewRow in _domainGrid.Rows)
                {
                    var disp = (DomainLogDisplayItem)dataGridViewRow.DataBoundItem;
                    foreach (DataGridViewCell cell in dataGridViewRow.Cells)
                    {
                        disp.Style(cell);
                    }
                }

                _domainGrid.Columns[0].Width = 200;
                _domainGrid.Columns[1].Width = 80;
                _domainGrid.Columns[2].Width = 90;
                _domainGrid.Columns[3].Width = 40;

                Log("Displayed {0} records starting from version {1}.", items.Count, _currentId);
            }, context)
            .ContinueWith(_ =>
            {
                if (sender != null)
                {
                    Invoke(new MethodInvoker(() => sender.Enabled = true));
                }
            });

            if (start.Status == TaskStatus.Created)
            {
                start.Start();
            }
        }