| Age | Commit message (Collapse) | Author |
|
Two concurrent 'ask' invocations could race on the alias cache file:
both wrote the JSON to a shared '<path>.tmp' filename and then both
called os.Rename, so the loser failed with:
replace task alias cache: rename .../task-aliases-v2.json.tmp
.../task-aliases-v2.json: no such file or directory
The shared tempfile also enabled lost updates because each process
loaded the file independently before saving its own version on top.
Fix:
- Take an exclusive flock on a sentinel file (task-aliases-v2.json.lock)
in the cache directory around the full load/modify/save cycle in both
ensureTaskAliases and resolveTaskSelectorFromCache, using the existing
internal/filelock package.
- Switch save() to os.CreateTemp so each writer gets a unique tempfile
name; the loser's tempfile is removed cleanly on rename failure.
- Refactor resolveTaskSelectorFromCache by extracting
finalizeResolvedTaskSelector to keep functions under 50 lines.
Adds TestEnsureTaskAliases_ConcurrentCallsDoNotRaceOnTempFile, which
reproduces the original error reliably on the unfixed code and now
passes with -race.
Amp-Thread-ID: https://ampcode.com/threads/T-019df49f-52a5-75b1-98d5-371a163ef100
Co-authored-by: Amp <amp@ampcode.com>
|
|
When the task alias cache file contains invalid JSON (e.g. from a
concurrent write race producing two concatenated JSON objects), the
previous code returned a hard error that blocked all `ask` subcommands.
Now loadTaskAliasCache discards the corrupt file and starts fresh,
assigning new alias IDs on the next run. Validation errors (e.g.
next_id reuse) still surface as errors since those indicate a logic bug.
Also fix stale v1 reference in integration test aliasCachePath.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Alias IDs are now stored in reversed form (e.g. id=37 → "10" instead
of "01") so that the first character varies quickly across consecutive
IDs, making shell auto-completion more effective. The counter logic is
unchanged; only the string representation is reversed via a new
reverseString helper in encodeTaskAliasID/decodeTaskAliasID.
The cache file is bumped to task-aliases-v2.json so existing mappings
are abandoned and all aliases are regenerated with the new format.
Also fix TestDispatcher_CompleteUUIDsSubcommand to use an isolated temp
dir for the alias cache, preventing flakiness from cross-test pollution.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|