Skip to content

Commit 78f5470

Browse files
committed
fix: set the allocator purge delay before the launched entry loads native code
The `sqb` launcher hands off to `sqlbuild.cli.entry.main.launched`, which imported `LAUNCH_RECORD_OPTION` from `sqlbuild._native` at module import. That loaded the extension, and its mimalloc allocator, before `entry.main` defaulted `MIMALLOC_PURGE_DELAY`, so mimalloc kept its default purge delay and returned far less freed memory to the OS. Dense 10000-model compiles peaked about 200-400 MiB higher. Default the purge delay in the launched entry before importing the native constant, and extend the fresh-process allocator entry test to cover the launched entry.
1 parent 8845304 commit 78f5470

3 files changed

Lines changed: 33 additions & 5 deletions

File tree

‎src/sqlbuild/cli/entry/main/launched.py‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
"""Python CLI entrypoint the native `sqb` executable hands every invocation it does not serve."""
22

3+
import os
34
import sys
45

5-
from sqlbuild._native import LAUNCH_RECORD_OPTION
6+
from sqlbuild.cli.entry.constants import (
7+
NATIVE_ALLOCATOR_PURGE_DELAY_MILLISECONDS,
8+
NATIVE_ALLOCATOR_PURGE_DELAY_VARIABLE,
9+
)
610
from sqlbuild.cli.entry.main.entry import main as run_cli
711

812

913
def main() -> int:
10-
"""Run the CLI with the arguments `sqb` received; the CLI reads a leading launch record."""
14+
"""Run the CLI with the `sqb` arguments, setting the allocator purge delay first."""
15+
16+
os.environ.setdefault(
17+
NATIVE_ALLOCATOR_PURGE_DELAY_VARIABLE, NATIVE_ALLOCATOR_PURGE_DELAY_MILLISECONDS
18+
)
19+
from sqlbuild._native import LAUNCH_RECORD_OPTION
1120

1221
arguments: list[str] = sys.argv[1:]
1322
offered: bool = bool(arguments) and arguments[0].startswith(LAUNCH_RECORD_OPTION)

‎tests/integration/src/sqlbuild/cli/commands/main/_test_types.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ class DiscoveryWorkTestCase:
928928
@dataclass(frozen=True)
929929
class NativeAllocatorEntryTestCase:
930930
description: str
931+
entry_module: str
931932
inherited_environment: tuple[tuple[str, str], ...]
932933
expected_purge_delay: str
933934

‎tests/integration/src/sqlbuild/cli/commands/main/test_native_allocator_entry.py‎

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@
1414
)
1515

1616
_PURGE_DELAY_VARIABLE: str = "MIMALLOC_PURGE_DELAY"
17+
_ENTRY_MODULE: str = "sqlbuild.cli.entry.main.entry"
18+
_LAUNCHED_MODULE: str = "sqlbuild.cli.entry.main.launched"
1719
_SCRIPT: str = """
20+
import importlib
1821
import json
1922
import os
2023
import sys
21-
from sqlbuild.cli.entry.main.entry import main
2224
25+
entry = importlib.import_module(sys.argv[1])
2326
loaded_at_import = "sqlbuild._native" in sys.modules
24-
exit_code = main(["--version"])
27+
sys.argv = ["sqlbuild-python", "--version"]
28+
exit_code = entry.main() if entry.__name__.endswith(".launched") else entry.main(["--version"])
2529
loaded_by_version = "sqlbuild._native" in sys.modules
2630
import sqlbuild._native
2731
print(json.dumps({
@@ -38,11 +42,25 @@
3842
[
3943
NativeAllocatorEntryTestCase(
4044
description="unset purge delay defaults to ten milliseconds",
45+
entry_module=_ENTRY_MODULE,
4146
inherited_environment=(),
4247
expected_purge_delay="10",
4348
),
4449
NativeAllocatorEntryTestCase(
4550
description="user purge delay is preserved",
51+
entry_module=_ENTRY_MODULE,
52+
inherited_environment=((_PURGE_DELAY_VARIABLE, "250"),),
53+
expected_purge_delay="250",
54+
),
55+
NativeAllocatorEntryTestCase(
56+
description="launched entry defaults the purge delay before native load",
57+
entry_module=_LAUNCHED_MODULE,
58+
inherited_environment=(),
59+
expected_purge_delay="10",
60+
),
61+
NativeAllocatorEntryTestCase(
62+
description="launched entry preserves a user purge delay",
63+
entry_module=_LAUNCHED_MODULE,
4664
inherited_environment=((_PURGE_DELAY_VARIABLE, "250"),),
4765
expected_purge_delay="250",
4866
),
@@ -57,7 +75,7 @@ def test_given_fresh_process_when_running_cli_entry_then_purge_delay_is_set_befo
5775
environment.update(test_case.inherited_environment)
5876

5977
result: subprocess.CompletedProcess[str] = subprocess.run(
60-
[sys.executable, "-c", _SCRIPT],
78+
[sys.executable, "-c", _SCRIPT, test_case.entry_module],
6179
check=True,
6280
capture_output=True,
6381
env=environment,

0 commit comments

Comments
 (0)