Run the unit tests on three workers, each letting go of the languages it met (#1033) #1085
No reviewers
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo!1085
Loading…
Reference in a new issue
No description provided.
Delete branch "1033-worker-memory"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A test worker grew towards 1 GB over the suite (#830), so the unit job's 2 GB container held
two workers and not three: with three (run 1658) the kernel killed two of them at once.
Measured one process through the whole suite in order, after every test file: what grew and
never came back was every language the worker had met. Django keeps each language's merged
catalogue, and below it Python's gettext keeps every .mo it opened (2,717 of them, about
110 MB, including the ones a fixture compiled into a directory since deleted); Django builds
reverse()'s tables once per active language in every resolver and namespace resolver (about
1.3 MB and 4,000 objects a language, although Postulo translates no route); and Babel keeps
every CLDR locale it loaded (about 75 MB for all of them). An instance meets a few languages;
the suite renders every page in all 86, reads month names in each and names every language in
every other, and a worker then carried them all to the end.
tests/conftest.py now drops all three after a test file that met more than four languages,
after the file's own fixtures are torn down. Production code is unchanged: there each cache
is paid once for the languages a process serves.
The other large cost was tests/test_translations.py, whose module fixture parses every
catalogue of every set: some 400 MB while the file runs, and under xdist's plain
loadeveryworker was handed some of its tests near the end of the suite and parsed them all at once.
The file is now one xdist group, which CI runs with
--dist loadgroupso one worker takesit, and the fixture drops the references and comments nothing reads, a third of that.
Measured on Windows (the absolute numbers differ from CI's Linux; the shape does not), one
process through the suite: 1,124 MB at the end and a 1,421 MB peak before, 881 and 1,106
after, 2.9 million objects down to 2.0, and 35 minutes instead of 44. With -n 3 --dist
loadgroup the suite passed in 14 min 53 s and the workers peaked at 606, 754 and 965 MB.
ci.yml and every-python.yml run the unit step with
-n 3 --dist loadgroup, with the numbersin the comment; CONTRIBUTING says so; the marker is registered for
-p no:xdistruns.Refs #1033
Notes for review
Item 3 of #1033: the unit job on three workers. This replaces the
-n 2comment in #1083 (draft), which held the unit job back on memory.gettext._translations, 2,717.mofiles, about 110 MB;reverse()tables in every resolver, about 113 MB, though Postulo translates no route;test_translations.pyparses every catalogue (about 390 MB), and under--dist loadevery worker took some of it near the end. That is why run 1658 lost two workers at the same second.release_languages()drops those caches;test_translations.pyis onexdist_group, and its fixture keeps only what the tests read;-n 3 --dist loadgroup.loadgroup.🤖 Generated with Claude Code
ecbd5134865126ee10a2