Skip to content

20261013 - cMeta v0.35.2: timeouts as given, the newest meta in the index, cx --print-home - #58

Merged
gfursin merged 7 commits into
mainfrom
dev
Oct 13, 2026
Merged

gfursin merged 7 commits into
mainfrom
dev

Conversation

@gfursin

@gfursin gfursin commented Oct 13, 2026

Copy link
Copy Markdown
Member

cMeta v0.35.2 - see CHANGELOG.md (## 0.35.2):

  • Any lock timeout is waited for as given, and it is the whole wait (inf, nan and values over threading.TIMEOUT_MAX no longer fail a waiter under contention).
  • The index keeps the newest meta of an updated artifact when two updates cross.
  • A command stopped by its timeout is stopped with every process it started, and the result says so (timed_out).
  • Durations, deadlines and retries on the monotonic clock, kept by a guard test.
  • The heartbeat of a soft lock is pushed to the drive, so another NFS client sees it.
  • cx --print-home prints the path of the cMeta home and nothing else; config.home_path() in Python.
  • cx --version names the folder of an editable or folder install as its system writes it.
  • Docs: which Python uv picks on a machine without one, and how to keep it below 3.15 for now.

Every commit is signed off. Please merge with a merge commit (not a squash), so that dev only needs a fast-forward afterwards.

🤖 Generated with Claude Code

gfursin and others added 7 commits October 12, 2026 16:28
…_choice, config.home_from_env, utils.common.console_line)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
…in the index, timed-out commands stopped

Extra tests of locks and timeouts found these, each red first:

- CMETA_LOCK_TIMEOUT, CMETA_INDEX_LOCK_TIMEOUT and the cache wait of cmeta-aops took inf, nan or a value over
  threading.TIMEOUT_MAX (4,294,967 s on Windows), and a waiter that found the lock busy failed with Python's own
  error after its notice. inf now waits until the lock is free, a huge value as long as Python can, nan is no
  number of seconds (the default and the warning). PathLock.acquire refuses nan by name and counts its timeout
  from its start, the wait for another thread of the process included.

- update wrote the meta file and then the index record from its own copy of the meta: two crossing updates left
  the older meta in the index. The record is now written from the file, read again under the index lock.

- utils.sys.run(timeout=...) on Linux and macOS left a process that ignores SIGTERM running and a captured call
  waiting for it: SIGKILL now follows after RUN_STOP_GRACE_SECONDS. The result says 'timed_out'. The session is
  made with start_new_session=True instead of preexec_fn=os.setsid (safe in a program with threads).

- An unlocked safe_read_file retried on the wall clock: a clock set forward between its start and its first
  check (NTP, a VM's clock sync - WSL2 steps it every 30 s on a machine whose host clock is off) meant no read
  and a success with no data. Now the monotonic clock and always one try. The tests of this area measure on the
  monotonic clock; two set the wall clock on purpose; the timing prints of a reindex, the utils scan and
  cserver.browse moved too, and test_durations_use_the_monotonic_clock.py guards the rule for the package.

- A soft lock's heartbeat is pushed (fsync) so that another NFS client sees a live holder's line change when
  it is written; only the heartbeat (at the acquisition an fsync cost 1.4-3 ms per lock in soft mode).

- Seven places still said a waiter's notice goes to stderr (stdout since 0.35.1).

New tests: test_utils_files_lock_limits.py, test_utils_sys_run_timeout.py,
test_integration_concurrent_updates.py, three soft-lock tests in test_utils_files_path_lock.py.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
…p it below 3.15 for now

uv uses a Python already on the machine; on a machine without one it downloads its newest - 3.15 since
October 2026 - and not every compiled dependency of cmeta[server] ships wheels for 3.15 yet (PyYAML does not),
so the install compiles it and fails without a C compiler (seen on a fresh Windows server). The installation
guide says so and shows `uv tool install --python ">=3.9,<3.15" "cmeta[server]"` (Option 1) and the same for
`uv venv` (Option 2); the README's two-minute start points to it. The website installer applies the cap by
default.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
…home_path()

cx --print-home prints one line on the standard output: the absolute path of the home this command line uses
(--home, CMETA_HOME, a virtual or conda environment, CMETA_HOME2, ~/CMETA - the same choice as every command),
with no network access and no index, and a home that does not exist yet is not set up. It is for scripts, which
read the home from cx --version until now: a report for people that asks cTuning.ai for the newest version and
ends with an error when it cannot be reached. The flag acts on its own only (after a category it stays an
ordinary parameter of the command, as before); --print_home is the same flag, and cx --help lists it.

In Python: config.home_path(home=None), the home that CMeta(home=home) uses, as an absolute path - nothing is
created. The rule of a bare --home (CMETA_HOME, else CMETA_HOME2, else ~/CMETA) is one helper now, used by
config.home_path and by the setup of an instance alike.

Docs: installation.md, using-cmeta.md, common-commands.md and the README name cx --print-home where they told a
script to read the home from cx --version.

Tests: tests/core_tests/test_config_home.py - config.home_path against CMeta(...).home_path for every way of
choosing the home (the five rules, a given folder, a bare --home, a relative CMETA_HOME), nothing created; the CLI
in another process (one line, nothing on the standard error, no home set up, the network unreachable, --home and a
bare --home, the help), and the flag after a category left to the command.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
… system writes it

The lines "Installed as" and "Update with" took the folder from the file URL the installer records (PEP 610) and
decoded only %20: on Windows they showed D:/%21FGG_Repos/..., and the git -C "..." pull they suggested failed for
any folder with "!", "#", "+", an accent and the like. Now every escape is decoded and a Windows folder keeps its
drive letter (or server) and backslashes: git -C "D:\!FGG_Repos\...\cmeta" pull.

A cMeta installed from a folder without -e is reinstalled from the URL the installer recorded: pip takes only a URL
after "@" (the path it was shown failed with pip - "No connection adapters", "No scheme supplied" - and with uv
when the folder name had an escape).

Tests: tests/core_tests/test_install_info.py - the folders of six URLs (an escape, an accent and a space, a drive
root, a server share, a POSIX folder, localhost), for an editable and for a folder install.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
The version in every file that carries it (docs/releasing.md, step 2); release date 2026-10-13. The development
version 0.35.1.1 is released as 0.35.2: every lock timeout waited for as given, the newest meta in the index after
crossing updates, a timed-out command stopped with every process it started, durations on the monotonic clock, the
heartbeat of a soft lock pushed to the drive, cx --print-home, the folder of an install named as its system writes
it in cx --version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
…s between two processes

test_a_lock_file_removed_under_a_waiter_never_gives_two_holders compared a time.monotonic() written by the waiter's
process with one taken in the test's process. The monotonic clock has no starting point common to two processes
(Python leaves it undefined): with Python 3.9 on macOS it starts at the first call in each process - 0.78 s in the
waiter against 49.4 s in the test, in the CI job macos-latest/3.9 - and the check failed although the lock behaved
right. The move of the tests to the monotonic clock (8652775) brought it in; before, both sides read the wall
clock. Now the test marks its release with a file made just before it, and the waiter writes whether that file
existed when it got the lock: the same order, checked without any clock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Grigori Fursin <gfursin@gmail.com>
@gfursin
gfursin merged commit 73e2c02 into main Oct 13, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant