Skip to content

Commit 2a2647c

Browse files
committed
use leased buffer for tags when calling SetAsync
1 parent e791702 commit 2a2647c

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/Middleware/OutputCaching/src/OutputCacheEntryFormatter.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,38 @@ public static async ValueTask StoreAsync(string key, OutputCacheEntry value, Has
4343
var buffer = new RecyclableArrayBufferWriter<byte>();
4444
Serialize(buffer, value);
4545

46-
string[] tagsArr = tags is { Count: > 0 } ? tags.ToArray() : Array.Empty<string>();
47-
4846
if (store is IOutputCacheBufferStore bufferStore)
4947
{
50-
await bufferStore.SetAsync(key, new(buffer.GetMemory()), tagsArr, duration, cancellationToken);
48+
await bufferStore.SetAsync(key, new(buffer.GetMemory()), CopyToLeasedMemory(tags, out var lease), duration, cancellationToken);
49+
if (lease is not null)
50+
{
51+
ArrayPool<string>.Shared.Return(lease);
52+
}
5153
}
5254
else
5355
{
5456
// legacy API/in-proc: create an isolated right-sized byte[] for the payload
57+
string[] tagsArr = tags is { Count: > 0 } ? tags.ToArray() : Array.Empty<string>();
5558
await store.SetAsync(key, buffer.ToArray(), tagsArr, duration, cancellationToken);
5659
}
5760

5861
buffer.Dispose(); // this is intentionally not using "using"; only recycle on success, to avoid async code accessing shared buffers (esp. in cancellation)
62+
63+
static ReadOnlyMemory<string> CopyToLeasedMemory(HashSet<string>? tags, out string[]? lease)
64+
{
65+
if (tags is null || tags.Count == 0)
66+
{
67+
lease = null;
68+
return default;
69+
}
70+
int index = 0;
71+
lease = ArrayPool<string>.Shared.Rent(tags.Count);
72+
foreach (var tag in tags)
73+
{
74+
lease[index++] = tag;
75+
}
76+
return new ReadOnlyMemory<string>(lease, 0, index);
77+
}
5978
}
6079

6180
// Format:

0 commit comments

Comments
 (0)