-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Use RecyclableMemoryStream #16949
Use RecyclableMemoryStream #16949
Changes from 16 commits
a1b7fa9
b0ad6e6
8135846
bb98357
1f8db5f
72eb01c
dba974f
9965bcf
1978dcd
511317a
fefc90d
3edaeaf
4c00119
7d8d313
a2e834c
12b7946
ab6e124
9572007
1c98afe
4716aef
a6465cb
b9cb6a1
20ff540
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using Microsoft.IO; | ||
|
||
namespace OrchardCore; | ||
|
||
public static class MemoryStreamFactory | ||
{ | ||
private static readonly RecyclableMemoryStreamManager _manager = new(); | ||
|
||
public static RecyclableMemoryStream GetStream(string tag = null) | ||
=> _manager.GetStream(tag); | ||
|
||
public static RecyclableMemoryStream GetStream(int requiredSize, string tag = null) | ||
=> _manager.GetStream(tag, requiredSize); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
namespace OrchardCore; | ||
|
||
public static class Str | ||
{ | ||
public static ReadOnlySpan<byte> FromBase64String(string base64) | ||
sebastienros marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
if (string.IsNullOrEmpty(base64)) | ||
{ | ||
return []; | ||
} | ||
|
||
var neededLength = GetByteArrayLengthFromBase64(base64); | ||
|
||
using var memoryStream = MemoryStreamFactory.GetStream(neededLength); | ||
var bytes = memoryStream.GetSpan(neededLength); | ||
|
||
if (!Convert.TryFromBase64String(base64, bytes, out var _)) | ||
{ | ||
throw new FormatException("Invalid Base64 string."); | ||
} | ||
|
||
return bytes; | ||
} | ||
|
||
// The length of a Base64-encoded string corresponds to the original byte length. | ||
// Base64 encoding converts every 3 bytes of data into 4 characters. | ||
// To calculate the original byte length from the Base64 string, use the formula: | ||
// (length * 3) / 4. This ensures the correct byte count by multiplying the length by 3 | ||
// before dividing by 4. | ||
private static int GetByteArrayLengthFromBase64(string base64String) | ||
{ | ||
return base64String.Length * 3 / 4; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,7 +42,9 @@ public async Task AddSourcesAsync(IConfigurationBuilder builder) | |
if (document.ShellsSettings is not null) | ||
{ | ||
var shellsSettingsString = document.ShellsSettings.ToJsonString(JOptions.Default); | ||
builder.AddTenantJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(shellsSettingsString))); | ||
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(shellsSettingsString)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just updated to OC 2.1 and my (test) site no longer starts. It looks like the problem is this new "using" which results in the stream being disposed when this method exits. The problem is that the stream is added as a configuration source here, but the stream (attached to the configuration source) isn't read until later. You can see this problem if you enable the database shells feature with OC 2.1. Note that disposing a MemoryStream isn't actually necessary. The Dispose method in MemoryStream does not release any memory, it just marks the stream as closed. So there was no harm in the old code which did not Dispose the stream. I'll create a separate issue, but I thought it might help to add a comment here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like I wasn't the only one to hit this and it's already been addressed in #17054 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mvarblow we release 2.1.1 today with this fix. Please try to upgrade your project and see if the problem is fixed. If not, please open a new issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for releasing the fix so quickly! Yes, that did resolve the issue for me, though I'm now running into another blocking issue with the user timezone service. I'll write up an issue for that one. |
||
|
||
builder.AddTenantJsonStream(stream); | ||
} | ||
} | ||
|
||
|
@@ -53,7 +55,9 @@ public async Task AddSourcesAsync(string tenant, IConfigurationBuilder builder) | |
{ | ||
var shellSettings = new JsonObject { [tenant] = document.ShellsSettings[tenant] }; | ||
var shellSettingsString = shellSettings.ToJsonString(JOptions.Default); | ||
builder.AddTenantJsonStream(new MemoryStream(Encoding.UTF8.GetBytes(shellSettingsString))); | ||
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(shellSettingsString)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same problem here. |
||
|
||
builder.AddTenantJsonStream(stream); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not using the Site Map feature, so I can't say whether this is actually a problem, but this looks wrong. With this change, the stream is disposed as it's being returned for use later (by the File result).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mvarblow it look suspicious to me too. Feel free to test it out, and submit an issue and PR.