/// <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(); }
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(); } }
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)))); }
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; } }
public Task <InsertEventsResult> FireAndForgetAsync(string stream, string apiKey, ValueDisposable <Content> content, TimeSpan timeout, CancellationToken cancellationToken) => SendAsync("stream/sendAsync", stream, apiKey, content, timeout, cancellationToken);
public RawReadStreamPayload(ValueDisposable <ArraySegment <byte> > content, StreamCoordinates next) { this.content = content; Content = content.Value; Next = next; }