Пример #1
0
        /// <inheritdoc />
        public async Task <InsertEventsResult> InsertAsync(
            InsertEventsQuery query,
            TimeSpan timeout,
            CancellationToken cancellationToken = default)
        {
            try
            {
                using (var disposable = writersPool.Acquire(out var buffer))
                {
                    buffer.Reset();

                    var content = new ValueDisposable <Content>(CreateContent(query, buffer), disposable);

                    var response = await sender
                                   .SendAsync(query.Stream, settings.ApiKeyProvider(), content, timeout, cancellationToken)
                                   .ConfigureAwait(false);

                    return(response);
                }
            }
            catch (Exception error)
            {
                log.Warn(error);
                return(new InsertEventsResult(HerculesStatus.UnknownError, error.Message));
            }
        }
        public void Should_call_dispose_action_once()
        {
            var mock = Substitute.For <IDisposable>();
            var d    = new ValueDisposable <int>(42, mock);

            mock.DidNotReceive().Dispose();

            d.Dispose();
            mock.Received().Dispose();
            mock.ClearReceivedCalls();

            d.Dispose();
            mock.DidNotReceive().Dispose();
        }
Пример #3
0
        private async Task <InsertEventsResult> SendAsync(
            [NotNull] string path,
            [NotNull] string stream,
            [CanBeNull] string apiKey,
            [NotNull] ValueDisposable <Content> content,
            TimeSpan timeout,
            CancellationToken cancellationToken)
        {
            try
            {
                var request = Request.Post(path)
                              .WithAdditionalQueryParameter(Constants.QueryParameters.Stream, stream)
                              .WithContentTypeHeader(Constants.ContentTypes.OctetStream);

                if (!string.IsNullOrEmpty(apiKey))
                {
                    request = request.WithHeader(Constants.HeaderNames.ApiKey, apiKey);
                }

                if (compressionEnabled)
                {
                    request = request
                              .WithContentEncodingHeader(Constants.Compression.Lz4Encoding)
                              .WithHeader(Constants.Compression.OriginalContentLengthHeaderName, content.Value.Length);
                    content = Compress(content);
                }

                request = request.WithContent(content.Value);

                var result = await client
                             .SendAsync(request, cancellationToken : cancellationToken, timeout : timeout)
                             .ConfigureAwait(false);

                var operationStatus = responseAnalyzer.Analyze(result.Response, out var errorMessage);

                return(new InsertEventsResult(operationStatus, errorMessage));
            }
            catch (Exception error)
            {
                log.Warn(error);
                return(new InsertEventsResult(HerculesStatus.UnknownError, error.Message));
            }
            finally
            {
                content.Dispose();
            }
        }
Пример #4
0
        private ValueDisposable <Content> Compress(ValueDisposable <Content> disposableContent)
        {
            var content = disposableContent.Value;
            var maximumCompressedLength = LZ4Codec.MaximumOutputSize(content.Length);
            var buffer = bufferPool.Rent(maximumCompressedLength);

            var compressedLength = LZ4Codec.Encode(content.Buffer, content.Offset, content.Length, buffer, 0, buffer.Length);

            if (compressedLength == 0 || compressedLength > maximumCompressedLength)
            {
                bufferPool.Return(buffer);
                throw new Exception($"Failed to compress {content.Length} bytes: expected no more than {maximumCompressedLength} bytes, but received {compressedLength} bytes.");
            }

            disposableContent.Dispose();

            return(new ValueDisposable <Content>(
                       new Content(buffer, 0, compressedLength),
                       new ActionDisposable(() => bufferPool.Return(buffer))));
        }
Пример #5
0
        private RawReadStreamPayload ParseReadResponseBody([NotNull] Response response)
        {
            try
            {
                var reader = new BinaryBufferReader(response.Content.Buffer, response.Content.Offset)
                {
                    Endianness = Endianness.Big
                };

                var coordinates = StreamCoordinatesReader.Read(reader);

                var content = new ValueDisposable <ArraySegment <byte> >(
                    new ArraySegment <byte>(response.Content.Buffer, (int)reader.Position, (int)(response.Content.Length - reader.Position)),
                    new ActionDisposable(() => bufferPool.Return(response.Content.Buffer)));

                return(new RawReadStreamPayload(content, coordinates));
            }
            catch (Exception)
            {
                bufferPool.Return(response.Content.Buffer);
                throw;
            }
        }
Пример #6
0
 public Task <InsertEventsResult> FireAndForgetAsync(string stream, string apiKey, ValueDisposable <Content> content, TimeSpan timeout, CancellationToken cancellationToken) =>
 SendAsync("stream/sendAsync", stream, apiKey, content, timeout, cancellationToken);
Пример #7
0
 public RawReadStreamPayload(ValueDisposable <ArraySegment <byte> > content, StreamCoordinates next)
 {
     this.content = content;
     Content      = content.Value;
     Next         = next;
 }