示例#1
0
        public void ChaseEventsForever(CancellationToken token, 
			Action<MessageWithId, Subscription> callback,
			Action<Subscription> idle = null)
        {
            const int current = 0;
            var reader =  _client.GetMessageReaderAsync(_stream);
            reader.Wait(token);

            using (var local = new CancellationTokenSource())
            using (var linked = CancellationTokenSource.CreateLinkedTokenSource(token, local.Token)){

            // TODO - figure buffer size
            var subscription = reader.Result.Subscribe(linked.Token, current, ReadBytesBuffer, ReadMessagesBuffer);
            var pages = new List<MessageWithId>();

                while (!token.IsCancellationRequested) {
                    MessageWithId msg;
                    while (!subscription.Buffer.TryDequeue(out msg)) {
                        if (idle != null) {
                            idle(subscription);
                        }
                        if (token.WaitHandle.WaitOne(100)) {
                            // time to stop
                            return;
                        }
                    }

                    pages.Add(msg);

                    var hasMore = ((MessageFlags) msg.Attributes & MessageFlags.ToBeContinued) ==
                        MessageFlags.ToBeContinued;
                    if (hasMore) {
                        continue;
                    }

                    var total = pages.Sum(m => m.Value.Length);
                    using (var mem = _manager.GetStream("chase-1", total)) {
                        foreach (var page in pages) {
                            mem.Write(page.Value, 0, page.Value.Length);
                        }
                        mem.Seek(0, SeekOrigin.Begin);

                        using (var lz = new LZ4Stream(mem, CompressionMode.Decompress, keepOpen : true)) {
                            using (var output = _manager.GetStream("chase-2")) {
                                lz.CopyTo(output);

                                var last = pages.Last();

                                try {

                                    callback(new MessageWithId(last.Id, last.Attributes, last.Key, output.ToArray(), 0),
                                        subscription);
                                }
                                catch (Exception ex) {
                                    local.Cancel();
                                    throw;
                                }
                            }

                        }

                    }
                    pages.Clear();
                }

            }
        }
示例#2
0
        public long Publish(ICollection<UnpackedMessage> unpacked, CancellationToken token)
        {
            var outgoing = new List<Message>();

            foreach (var message in unpacked) {
                using (var mem = new MemoryStream()) {
                    using (var zip = new LZ4Stream(mem, CompressionMode.Compress, false, 0, true)) {
                        zip.Write(message.Value, 0, message.Value.Length);
                    }

                    mem.Seek(0, SeekOrigin.Begin);

                    var remains = (int)mem.Length;

                    while (remains > 0)
                    {
                        Console.WriteLine("Page...");
                        var pick = Math.Min(remains, Constants.MaxValueSize);
                        var hasMoreToWrite = remains > pick;

                        var flag = hasMoreToWrite ? MessageFlags.ToBeContinued : MessageFlags.None;
                        flag |= MessageFlags.LZ4;

                        var chunk = new byte[pick];
                        mem.Read(chunk, 0, pick);
                        outgoing.Add(Message.Create(message.Key, chunk, (byte)flag));
                        remains -= pick;
                    }
                }
            }
            var result = _client.PostMessagesAsync(_stream, outgoing);
            result.Wait(token);
            return result.Result.Position;
        }