feat(binary): лимит памяти для ДвоичныеДанные из конфигурации (#1667)#1670
feat(binary): лимит памяти для ДвоичныеДанные из конфигурации (#1667)#1670johnnyshut wants to merge 3 commits into
Conversation
Добавили ключ binaryData.inMemoryMaxBytes (байты) в oscript.cfg и переменную OSCRIPT_CONFIG. Изменили OneScriptCoreOptions: разбор значения с проверкой и запасным значением по умолчанию (50 МБ). Добавили BinaryDataConfigurationDefaults, IBinaryDataMemoryLimit и регистрацию в SetDefaultOptions. Добавили BinaryDataRuntimeSettings (AsyncLocal): на время BslProcess.Run лимит берётся из DI; вне процесса — дефолт. Изменили BinaryDataContext и конструктор FileBackingStream без параметров для использования эффективного лимита. Изменили FileBackingConstants.DEFAULT_MEMORY_LIMIT — ссылка на общий дефолт из ScriptEngine. Изменили CGI: WebRequestContext принимает лимит из сервисов до CreateProcess.
📝 WalkthroughWalkthroughThis PR introduces configurable in-memory memory limits for binary data handling in OneScript by creating a new library with DI-backed configuration, updating binary components to use runtime settings, and integrating host applications. It also improves process executor lifecycle management and extends solution build configuration for x64 platform support. ChangesBinary Data Memory Limit Configuration
Process Executor Lifecycle Management
🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
src/ScriptEngine/Machine/BinaryDataRuntimeSettings.cs (1)
20-24: ⚡ Quick winHarden runtime settings against invalid DI-provided limits
PushFromServicescurrently trustsIBinaryDataMemoryLimit.MaxBytesInMemory. A custom host registration can pass invalid values and break downstream buffering behavior; sanitize here before storing toAsyncLocal.💡 Suggested fix
internal static void PushFromServices(IServiceContainer services) { var opts = services.TryResolve<IBinaryDataMemoryLimit>(); - InMemoryMaxBytes.Value = opts?.MaxBytesInMemory ?? BinaryDataConfigurationDefaults.InMemoryMaxBytes; + var maxBytes = opts?.MaxBytesInMemory ?? BinaryDataConfigurationDefaults.InMemoryMaxBytes; + if (maxBytes <= 0 || maxBytes == int.MaxValue) + maxBytes = BinaryDataConfigurationDefaults.InMemoryMaxBytes; + + InMemoryMaxBytes.Value = maxBytes; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ScriptEngine/Machine/BinaryDataRuntimeSettings.cs` around lines 20 - 24, PushFromServices currently writes IBinaryDataMemoryLimit.MaxBytesInMemory directly into the AsyncLocal InMemoryMaxBytes.Value; validate and sanitize the DI-provided value first so invalid or negative numbers don't corrupt runtime buffering. In PushFromServices, read opts?.MaxBytesInMemory into a local, check for null/<=0 and replace with BinaryDataConfigurationDefaults.InMemoryMaxBytes, and optionally clamp extremely large values to a sane upper bound before assigning to InMemoryMaxBytes.Value; reference IBinaryDataMemoryLimit, PushFromServices, InMemoryMaxBytes and BinaryDataConfigurationDefaults.InMemoryMaxBytes when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/oscript/CgiBehavior.cs`:
- Around line 72-73: Replace the hard Resolve call so CGI startup uses a safe DI
lookup with a default fallback: try to get IBinaryDataMemoryLimit from
engine.Services (avoid engine.Services.Resolve which throws) and if null or
missing use BinaryDataConfigurationDefaults.InMemoryMaxBytes, then pass that
value into the WebRequestContext constructor; update the code locations
referencing IBinaryDataMemoryLimit, engine.Services.Resolve and the
WebRequestContext creation to use this conditional/fallback logic.
In `@src/oscript/Web/WebRequestContext.cs`:
- Around line 37-40: Validate the constructor parameter in WebRequestContext by
checking postBodyInMemoryMaxBytes at the start of the WebRequestContext(int
postBodyInMemoryMaxBytes) constructor and throw an ArgumentOutOfRangeException
(with a clear message mentioning _postBodyInMemoryMaxBytes and expected positive
byte count) when the value is invalid (e.g., <= 0 or otherwise out of allowed
range) so the error fails fast instead of propagating later into
FileBackingStream.
- Line 79: The code constructs FileBackingStream with the full content length
which causes MemoryStream to preallocate huge buffers; change the capacity
argument so initial allocation is capped by _postBodyInMemoryMaxBytes (e.g.,
pass Math.Min(len, _postBodyInMemoryMaxBytes) instead of len) when creating the
FileBackingStream (the call that assigns dest = new FileBackingStream(...)) so
the in-memory buffer is limited and spilling-to-disk behavior works as intended.
In `@src/ScriptEngine/BslProcess.cs`:
- Around line 45-46: Wrap the runtime push/pop and _isRunning mutation in a
try/finally so Pop() and _isRunning reset always run even if executor hooks
throw: call BinaryDataRuntimeSettings.PushFromServices and set _isRunning = true
before invoking Array.ForEach(_executorProviders, e =>
e.BeforeProcessStart(this)), then ensure BinaryDataRuntimeSettings.Pop() and
_isRunning = false are executed in a finally block; similarly, ensure any
Array.ForEach(_executorProviders, e => e.AfterProcessExit(this)) failures do not
prevent the finally from running (catch per-hook exceptions if desired) so Pop()
and _isRunning reset cannot be skipped.
---
Nitpick comments:
In `@src/ScriptEngine/Machine/BinaryDataRuntimeSettings.cs`:
- Around line 20-24: PushFromServices currently writes
IBinaryDataMemoryLimit.MaxBytesInMemory directly into the AsyncLocal
InMemoryMaxBytes.Value; validate and sanitize the DI-provided value first so
invalid or negative numbers don't corrupt runtime buffering. In
PushFromServices, read opts?.MaxBytesInMemory into a local, check for null/<=0
and replace with BinaryDataConfigurationDefaults.InMemoryMaxBytes, and
optionally clamp extremely large values to a sane upper bound before assigning
to InMemoryMaxBytes.Value; reference IBinaryDataMemoryLimit, PushFromServices,
InMemoryMaxBytes and BinaryDataConfigurationDefaults.InMemoryMaxBytes when
making the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 22f9a33d-f478-4b86-9fcf-a6bc6faba769
📒 Files selected for processing (12)
src/OneScript.StandardLibrary/Binary/BinaryDataContext.cssrc/OneScript.StandardLibrary/Binary/FileBackingConstants.cssrc/OneScript.StandardLibrary/Binary/FileBackingStream.cssrc/ScriptEngine.HostedScript/oscript.cfgsrc/ScriptEngine/BinaryDataConfigurationDefaults.cssrc/ScriptEngine/BslProcess.cssrc/ScriptEngine/Hosting/EngineBuilderExtensions.cssrc/ScriptEngine/IBinaryDataMemoryLimit.cssrc/ScriptEngine/Machine/BinaryDataRuntimeSettings.cssrc/ScriptEngine/OneScriptCoreOptions.cssrc/oscript/CgiBehavior.cssrc/oscript/Web/WebRequestContext.cs
… обработки ошибок Логика уведомлений исполнителя перемещена в единый условный блок для большей ясности. Улучшена обработка ошибок при завершении процесса для обеспечения надлежащей очистки ресурсов. Обновлены параметры BinaryDataRuntimeSettings для обеспечения положительных ограничений памяти и резервных значений по умолчанию. Скорректирован WebRequestContext для проверки ограничений памяти при создании экземпляра.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
src/oscript/Web/WebRequestContext.cs (1)
37-42:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winReject
Int32.MaxValueat the constructor boundary too.
FileBackingStreamtreatsInt32.MaxValueasSYSTEM_IN_MEMORY_LIMITand throws, soWebRequestContext(int)still accepts a value it cannot actually use. Failing fast here keeps the public API consistent and avoids a later exception fromProcessPostData().Suggested fix
- if (postBodyInMemoryMaxBytes <= 0) + if (postBodyInMemoryMaxBytes <= 0 || postBodyInMemoryMaxBytes == int.MaxValue) throw new ArgumentOutOfRangeException(nameof(postBodyInMemoryMaxBytes), - "Лимит памяти для тела POST-запроса должен быть положительным числом байт."); + "Лимит памяти для тела POST-запроса должен быть положительным числом байт и меньше Int32.MaxValue.");🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/oscript/Web/WebRequestContext.cs` around lines 37 - 42, The WebRequestContext constructor currently only rejects non-positive values but must also reject Int32.MaxValue because FileBackingStream treats that value as SYSTEM_IN_MEMORY_LIMIT and will throw later; update the WebRequestContext(int postBodyInMemoryMaxBytes) constructor to validate that postBodyInMemoryMaxBytes is > 0 and < Int32.MaxValue (or != Int32.MaxValue) and throw an ArgumentOutOfRangeException with a clear message if the value is Int32.MaxValue so callers fail fast (this keeps behavior consistent with FileBackingStream and avoids a later exception in ProcessPostData()).src/ScriptEngine/BslProcess.cs (1)
49-68:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftUnwind executors that already started when a later
BeforeProcessStartthrows.
_isRunningbecomestrueonly after the whole startup loop succeeds, so a failure in any laterBeforeProcessStartskipsAfterProcessExitfor executors that already initialized state.StackMachineExecutor.BeforeProcessStart()allocates machine/debugger state (src/ScriptEngine/Machine/StackMachineExecutor.cs:25-45), so failed startup can still leak per-process setup here.Suggested direction
+ var startedExecutors = new List<IExecutorProvider>(); try { if (notifyExecutors) - Array.ForEach(_executorProviders, e => e.BeforeProcessStart(this)); + { + foreach (var executor in _executorProviders) + { + executor.BeforeProcessStart(this); + startedExecutors.Add(executor); + } + } _isRunning = true; return _bslExecutorsByModule[module.GetType()](this, target, module, method, arguments); } finally { if (notifyExecutors) { try { - if (_isRunning) - Array.ForEach(_executorProviders, e => e.AfterProcessExit(this)); + for (var i = startedExecutors.Count - 1; i >= 0; i--) + startedExecutors[i].AfterProcessExit(this); } finally { BinaryDataRuntimeSettings.Pop(); _isRunning = false;🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/ScriptEngine/BslProcess.cs` around lines 49 - 68, When calling each executor's BeforeProcessStart (via Array.ForEach over _executorProviders) a later exception can skip AfterProcessExit for earlier executors; modify BslProcess.Start (the block invoking BeforeProcessStart/AfterProcessExit) to track which providers successfully completed BeforeProcessStart (e.g., a local list/flag per provider) and set _isRunning only for the process-level state, then in the finally ensure you call AfterProcessExit for every provider that was marked started (not gated solely on _isRunning), and still call BinaryDataRuntimeSettings.Pop() and clear _isRunning; in short: record started executors during the BeforeProcessStart loop and unwind them via their AfterProcessExit even if startup throws.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/oscript/Web/WebRequestContext.cs`:
- Around line 37-42: The WebRequestContext constructor currently only rejects
non-positive values but must also reject Int32.MaxValue because
FileBackingStream treats that value as SYSTEM_IN_MEMORY_LIMIT and will throw
later; update the WebRequestContext(int postBodyInMemoryMaxBytes) constructor to
validate that postBodyInMemoryMaxBytes is > 0 and < Int32.MaxValue (or !=
Int32.MaxValue) and throw an ArgumentOutOfRangeException with a clear message if
the value is Int32.MaxValue so callers fail fast (this keeps behavior consistent
with FileBackingStream and avoids a later exception in ProcessPostData()).
In `@src/ScriptEngine/BslProcess.cs`:
- Around line 49-68: When calling each executor's BeforeProcessStart (via
Array.ForEach over _executorProviders) a later exception can skip
AfterProcessExit for earlier executors; modify BslProcess.Start (the block
invoking BeforeProcessStart/AfterProcessExit) to track which providers
successfully completed BeforeProcessStart (e.g., a local list/flag per provider)
and set _isRunning only for the process-level state, then in the finally ensure
you call AfterProcessExit for every provider that was marked started (not gated
solely on _isRunning), and still call BinaryDataRuntimeSettings.Pop() and clear
_isRunning; in short: record started executors during the BeforeProcessStart
loop and unwind them via their AfterProcessExit even if startup throws.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 67fd241a-6dc6-485e-962b-7b19be63e644
📒 Files selected for processing (4)
src/ScriptEngine/BslProcess.cssrc/ScriptEngine/Machine/BinaryDataRuntimeSettings.cssrc/oscript/CgiBehavior.cssrc/oscript/Web/WebRequestContext.cs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/ScriptEngine/Machine/BinaryDataRuntimeSettings.cs
| /// </summary> | ||
| public static class BinaryDataRuntimeSettings | ||
| { | ||
| private static readonly AsyncLocal<int?> InMemoryMaxBytes = new AsyncLocal<int?>(); |
There was a problem hiding this comment.
Просьба пояснить зачем этот класс и что он призвать делать. Меня пугают AsyncLocal-ы тут.
There was a problem hiding this comment.
Лимит нужен в стандартной либе, а конфиг живёт у движка. Через AsyncLocal просто кладём число «на время выполнения скрипта», чтобы из BinaryData/FileBackingStream можно было его прочитать, не таская сервисы через все методы
There was a problem hiding this comment.
В этом и проблема. Почему не сделать конфиг там, где он нужен - в либе. Это первое, второе - зачем так часть "актуализировать" значение, ведь оно просто достается из конфига один раз на весь процесс oscript.exe и потом не меняется?
There was a problem hiding this comment.
Понял, переделаю.
|
|
||
| _isRunning = true; | ||
| if (notifyExecutors) | ||
| BinaryDataRuntimeSettings.PushFromServices(Services); |
There was a problem hiding this comment.
Вот это тоже мне непонятно зачем и что делает.
There was a problem hiding this comment.
Мы один раз подтягиваем лимит из настроек движка и записываем его в это AsyncLocal. Дальше код двоичных данных сам берёт уже это значение. Без этого конструктор FileBackingStream вообще не узнал бы лимит.
| } | ||
| finally | ||
| { | ||
| BinaryDataRuntimeSettings.Pop(); |
There was a problem hiding this comment.
Стекоподобная установка настроек двоичных данных чтобы что?
There was a problem hiding this comment.
Push в начале Run, Pop в finally в конце, чтобы после выполнения значение не осталось висеть на потоке и не попало случайно в следующий запуск. Если название сбивает с толку - могу переформулировать
| /// Лимит объёма данных в памяти для объектов «ДвоичныеДанные» и смежных потоков | ||
| /// до выгрузки во временный файл (байты). | ||
| /// </summary> | ||
| public interface IBinaryDataMemoryLimit |
There was a problem hiding this comment.
Мне не нравится размазывание вот этого параметра по разным сборкам. Пользоваться этим будут только классы из StandardLibrary, но знание про настройку живет в CoreOptions сборки ScriptingEngine,
По-моему, лучше было бы, если те, кто потребляет этот параметр и объявляли бы у себя эту опцию.
There was a problem hiding this comment.
Если перетащить всё только в StandardLibrary - надо будет думать как не разъехаться с конфигом и oscript
There was a problem hiding this comment.
надо будет думать как не разъехаться с конфигом и oscript
Вот эта фраза непонятна, нужно пояснение
There was a problem hiding this comment.
Сейчас число одно и берётся из конфига движка. Если продублировать настройку «у потребителей», можно случайно получить два разных лимита или один забудут поправить. Про oscript имел в виду, что это как раз тот конфиг, откуда уже читают настройки.
…ичных данных Созданы новые классы и интерфейсы для управления лимитом памяти двоичных данных, включая BinaryDataConfigurationDefaults, IBinaryDataMemoryLimit и BinaryDataMemoryLimit. Реализована регистрация лимита памяти в EngineBuilderExtensions и обновлены соответствующие классы для использования нового механизма. Удален устаревший BinaryDataRuntimeSettings. Обновлены тестовые и основные приложения для интеграции новых настроек.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/ScriptEngine/BslProcess.cs (1)
64-75: 💤 Low valueConsider wrapping each
AfterProcessExitcall to ensure all executors receive cleanup notification.If one executor's
AfterProcessExitthrows, the loop exits and remaining executors won't be notified. Depending on what executors do (e.g., release resources, pop state), this could leave other executors in an inconsistent state.If best-effort cleanup for all executors is desired:
♻️ Optional: catch-and-aggregate exceptions per executor
if (startedExecutors != null) { + List<Exception> cleanupExceptions = null; for (var i = startedExecutors.Count - 1; i >= 0; i--) - startedExecutors[i].AfterProcessExit(this); + { + try + { + startedExecutors[i].AfterProcessExit(this); + } + catch (Exception ex) + { + cleanupExceptions ??= new List<Exception>(); + cleanupExceptions.Add(ex); + } + } + if (cleanupExceptions != null) + throw new AggregateException(cleanupExceptions); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/ScriptEngine/BslProcess.cs` around lines 64 - 75, The loop calling startedExecutors[i].AfterProcessExit(this) can abort if one executor throws; modify the loop in BslProcess (where startedExecutors and _isRunning are used) to call each executor inside its own try/catch so all executors get notified even if one fails, and optionally collect/aggregate exceptions (e.g., into a List<Exception>) to rethrow or log after the loop; preserve the existing finally that sets _isRunning = false.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/ScriptEngine/BslProcess.cs`:
- Around line 64-75: The loop calling startedExecutors[i].AfterProcessExit(this)
can abort if one executor throws; modify the loop in BslProcess (where
startedExecutors and _isRunning are used) to call each executor inside its own
try/catch so all executors get notified even if one fails, and optionally
collect/aggregate exceptions (e.g., into a List<Exception>) to rethrow or log
after the loop; preserve the existing finally that sets _isRunning = false.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a0f91c0b-43c7-4ece-9f63-ae751783b71c
📒 Files selected for processing (19)
src/1Script.slnsrc/OneScript.BinaryData/BinaryDataConfigurationDefaults.cssrc/OneScript.BinaryData/BinaryDataMemoryLimit.cssrc/OneScript.BinaryData/BinaryDataMemoryLimitConfiguration.cssrc/OneScript.BinaryData/BinaryDataRuntimeSettings.cssrc/OneScript.BinaryData/IBinaryDataMemoryLimit.cssrc/OneScript.BinaryData/OneScript.BinaryData.csprojsrc/OneScript.StandardLibrary/Binary/BinaryDataContext.cssrc/OneScript.StandardLibrary/Binary/FileBackingConstants.cssrc/OneScript.StandardLibrary/Binary/FileBackingStream.cssrc/OneScript.StandardLibrary/EngineBuilderExtensions.cssrc/ScriptEngine/BslProcess.cssrc/ScriptEngine/Hosting/EngineBuilderExtensions.cssrc/ScriptEngine/ScriptEngine.csprojsrc/ScriptEngine/ScriptingEngine.cssrc/TestApp/MainWindow.xaml.cssrc/oscript/CgiBehavior.cssrc/oscript/ConsoleHostBuilder.cssrc/oscript/Web/WebRequestContext.cs
🚧 Files skipped from review as they are similar to previous changes (4)
- src/OneScript.StandardLibrary/Binary/BinaryDataContext.cs
- src/ScriptEngine/Hosting/EngineBuilderExtensions.cs
- src/oscript/Web/WebRequestContext.cs
- src/OneScript.StandardLibrary/Binary/FileBackingStream.cs
| private static volatile int _inMemoryMaxBytes = BinaryDataConfigurationDefaults.InMemoryMaxBytes; | ||
|
|
||
| /// <summary> | ||
| /// Читает лимит из DI и сохраняет для использования кодом без доступа к контейнеру (конструктор «Файловый поток с буфером» и т.п.). | ||
| /// Вызывается при создании экземпляра основного движка скриптов. | ||
| /// </summary> | ||
| public static void ApplyFromServices(IServiceContainer services) | ||
| { | ||
| var opts = services.TryResolve<IBinaryDataMemoryLimit>(); | ||
| var maxBytes = opts?.MaxBytesInMemory ?? BinaryDataConfigurationDefaults.InMemoryMaxBytes; | ||
| if (maxBytes <= 0 || maxBytes == int.MaxValue) | ||
| maxBytes = BinaryDataConfigurationDefaults.InMemoryMaxBytes; | ||
|
|
||
| _inMemoryMaxBytes = maxBytes; | ||
| } |
There was a problem hiding this comment.
Scope the runtime limit per execution context, not as a process-wide mutable static.
Line 17 and Line 30 make the effective memory limit global for the whole process. That can bleed config between concurrently running engines and make behavior depend on initialization order.
💡 Refactor direction
+using System.Threading;
...
- private static volatile int _inMemoryMaxBytes = BinaryDataConfigurationDefaults.InMemoryMaxBytes;
+ private static readonly AsyncLocal<int?> _currentInMemoryMaxBytes = new AsyncLocal<int?>();
...
- public static void ApplyFromServices(IServiceContainer services)
+ public static int ResolveFromServices(IServiceContainer services)
{
var opts = services.TryResolve<IBinaryDataMemoryLimit>();
var maxBytes = opts?.MaxBytesInMemory ?? BinaryDataConfigurationDefaults.InMemoryMaxBytes;
if (maxBytes <= 0 || maxBytes == int.MaxValue)
maxBytes = BinaryDataConfigurationDefaults.InMemoryMaxBytes;
-
- _inMemoryMaxBytes = maxBytes;
+ return maxBytes;
}
...
- public static int GetEffectiveInMemoryMaxBytes() => _inMemoryMaxBytes;
+ public static int GetEffectiveInMemoryMaxBytes() =>
+ _currentInMemoryMaxBytes ?? BinaryDataConfigurationDefaults.InMemoryMaxBytes;
+
+ public static void SetCurrentInMemoryMaxBytes(int maxBytes) =>
+ _currentInMemoryMaxBytes.Value =
+ (maxBytes <= 0 || maxBytes == int.MaxValue)
+ ? BinaryDataConfigurationDefaults.InMemoryMaxBytes
+ : maxBytes;
+
+ public static void ClearCurrentInMemoryMaxBytes() =>
+ _currentInMemoryMaxBytes.Value = null;Also applies to: 37-37
Зачем
Закрывает #1667: порог «держать двоичные данные в памяти до перехода на временный файл» больше не зашит константой только в коде — задаётся через конфигурацию.
Что сделали
binaryData.inMemoryMaxBytes(целое число байт) вoscript.cfgи в состав настроек изOSCRIPT_CONFIG. Если ключ не задан или значение некорректно — используется 50 МБ (BinaryDataConfigurationDefaults.InMemoryMaxBytes).IBinaryDataMemoryLimitи регистрацию вSetDefaultOptions(singleton на основеOneScriptCoreOptions).BinaryDataRuntimeSettings: на время выполненияBslProcess.Runлимит попадает вAsyncLocalи используетсяBinaryDataContextи параметрlessFileBackingStream(); вне процесса BSL остаётся значение по умолчанию.FileBackingConstants.DEFAULT_MEMORY_LIMIT— тот же дефолт, что и вScriptEngine.WebRequestContextполучает лимит из контейнера после сборки движка (доCreateProcess), т.к. запрос создаётся раньше старта BSL-процесса.Как проверить
oscript.cfgраскомментировать/задать, например:binaryData.inMemoryMaxBytes=1048576, убедиться, что поведение буферизации соответствует ожиданиям для больших потоков.dotnet build src/oscript/oscript.csproj(как минимум).Summary by CodeRabbit
New Features
Bug Fixes
Chores