Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer payloads asynchronously when appropriate #2297

Merged
merged 2 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Fixes

- Buffer payloads asynchronously when appropriate ([#2297](https://github.com/getsentry/sentry-dotnet/pull/2297))

## 3.30.0

### Features
Expand Down
25 changes: 22 additions & 3 deletions src/Sentry/Protocol/Envelopes/EnvelopeItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ public EnvelopeItem(IReadOnlyDictionary<string, object?> header, ISerializable p
/// <returns>The file name or null.</returns>
public string? TryGetFileName() => Header.GetValueOrDefault(FileNameKey) as string;

private async Task<MemoryStream> BufferPayloadAsync(IDiagnosticLogger? logger, CancellationToken cancellationToken)
{
var buffer = new MemoryStream();

if (Payload is JsonSerializable jsonSerializable)
{
// There's no advantage to buffer fully-materialized in-memory objects asynchronously,
// and there's some minor overhead in doing so. Thus we will serialize synchronously.

// ReSharper disable once MethodHasAsyncOverloadWithCancellation
jsonSerializable.Serialize(buffer, logger);
}
else
{
await Payload.SerializeAsync(buffer, logger, cancellationToken).ConfigureAwait(false);
}

buffer.Seek(0, SeekOrigin.Begin);
return buffer;
}

private MemoryStream BufferPayload(IDiagnosticLogger? logger)
{
var buffer = new MemoryStream();
Expand Down Expand Up @@ -117,9 +138,7 @@ public async Task SerializeAsync(Stream stream, IDiagnosticLogger? logger,
// in item headers. Don't trust any previously calculated value to be correct.
// See https://github.com/getsentry/sentry-dotnet/issues/1956

// NOTE: Previously we used BufferPayloadAsync, but since we buffer from in-memory objects to a MemoryStream
// there's no advantage to doing so asynchronously. We will get better perf from a synchronous approach.
var payloadBuffer = BufferPayload(logger);
var payloadBuffer = await BufferPayloadAsync(logger, cancellationToken).ConfigureAwait(false);
#if NETFRAMEWORK || NETSTANDARD2_0
using (payloadBuffer)
#else
Expand Down