ppkit 0.2.1__tar.gz → 0.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ppkit-0.2.3/CHANGELOG.md +755 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/CONTRIBUTING.md +63 -19
- {ppkit-0.2.1 → ppkit-0.2.3}/PKG-INFO +70 -16
- {ppkit-0.2.1 → ppkit-0.2.3}/README.md +69 -15
- {ppkit-0.2.1 → ppkit-0.2.3}/ci/check +2 -2
- ppkit-0.2.3/ci/suite +88 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/__init__.py +1 -1
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/cli.py +6 -1
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/http.py +802 -195
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/kill.py +19 -3
- ppkit-0.2.3/pp/commands/memory.py +1023 -0
- ppkit-0.2.3/pp/commands/queue.py +621 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/config.py +9 -1
- ppkit-0.2.3/pp/lib/guarded.py +163 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/jobcore.py +135 -119
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/jobpolicy.py +301 -106
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/jobq.py +885 -228
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/jobstore.py +98 -63
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/lock.py +28 -11
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/paths.py +38 -11
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/proc.py +164 -46
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/ui.py +4 -2
- ppkit-0.2.3/pp/lib/words.py +69 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pyproject.toml +1 -1
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/journey.py +13 -50
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/sandbox.py +64 -11
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_cli.py +26 -93
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_cmd.py +92 -5
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_constructs.py +45 -23
- ppkit-0.2.3/tests/test_http.py +1357 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_batch.py +2 -26
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_cli.py +33 -18
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_cmd.py +22 -68
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_http.py +81 -21
- ppkit-0.2.3/tests/test_journey_memory.py +180 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_promote.py +6 -24
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_queue.py +339 -286
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_kill.py +79 -79
- ppkit-0.2.3/tests/test_memory.py +671 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_paths.py +22 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_proc.py +44 -13
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_promote.py +8 -1
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_queue.py +1857 -412
- ppkit-0.2.1/CHANGELOG.md +0 -346
- ppkit-0.2.1/pp/commands/queue.py +0 -449
- ppkit-0.2.1/tests/test_http.py +0 -699
- {ppkit-0.2.1 → ppkit-0.2.3}/.pp.toml +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/LICENSE +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/bin/pp +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/ci/package +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/__main__.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/__init__.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/batch.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/cmd.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/completion.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/commands/promote.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/__init__.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/pp/lib/session.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_batch.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_journey_kill.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_lock.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_session.py +0 -0
- {ppkit-0.2.1 → ppkit-0.2.3}/tests/test_ui.py +0 -0
ppkit-0.2.3/CHANGELOG.md
ADDED
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.2.3
|
|
4
|
+
|
|
5
|
+
`pp memory` is a new command for a memory that agents share: it ranks the
|
|
6
|
+
notes for a situation, follows and proposes links, drafts groups, checks the
|
|
7
|
+
index, and runs an agent's own edit while no other edit runs. `pp queue`
|
|
8
|
+
adds job keys, events, resizes, card pins and retries that take changes,
|
|
9
|
+
and its help is a short page with four topic pages. `pp http` serves under a
|
|
10
|
+
proxy's path, keeps pinned tabs, answers sooner and searches the tabs.
|
|
11
|
+
`pp kill` asks first when a number is also a job's id.
|
|
12
|
+
|
|
13
|
+
`pp memory` is a new command for a memory that agents share: a folder of
|
|
14
|
+
markdown notes, one fact per file, with `[[links]]` between them.
|
|
15
|
+
|
|
16
|
+
- `pp memory find WORDS` ranks the notes for a situation by BM25 over their
|
|
17
|
+
words. Links bring in the notes the words miss, through personalized
|
|
18
|
+
PageRank, each marked `via` the note it came through.
|
|
19
|
+
- A pointer, `§G:NAME`, is the link to write: one rare character, the
|
|
20
|
+
memory's scope (`[memory] scope`, `G` by default) and the note's name. A
|
|
21
|
+
pointer of another scope, such as `§pp:NAME` or a project's `§P:`, is
|
|
22
|
+
left alone. `check` reports a `§G:` pointer to no note as broken.
|
|
23
|
+
`[[NAME]]` and markdown links to `.md` files are links too.
|
|
24
|
+
- `pp memory related NAME` shows what a note links and what links it, the
|
|
25
|
+
notes most like it that it does not link, and the hubs that hold it or
|
|
26
|
+
might.
|
|
27
|
+
- `pp memory groups` drafts about √N groups for N notes, for the hub notes
|
|
28
|
+
that `MEMORY.md` lists. `--in HUB` drafts groups for one hub's notes.
|
|
29
|
+
- `pp memory check` lists links to no file, two notes with one name, notes
|
|
30
|
+
nothing links, notes the root does not reach in two steps, and pairs of
|
|
31
|
+
notes alike enough to compare. It prints the sizes against √N. Its exit
|
|
32
|
+
status is 1 only for a broken link or a name two notes share.
|
|
33
|
+
- `pp memory edit -- CMD` runs an agent's own command that changes notes,
|
|
34
|
+
such as `sed -i` or a python heredoc, under the memory's write lock, so
|
|
35
|
+
two edits at once take turns. The command finds the memory in
|
|
36
|
+
`PP_MEMORY_DIR`. The edit is the command's whole session: what the command
|
|
37
|
+
leaves running is ended with it. When the command fails, leaves something
|
|
38
|
+
running, runs past `--timeout` (a minute, `[memory] edit_timeout`) or is
|
|
39
|
+
stopped (Ctrl-C, SIGTERM or SIGHUP), every note it changed, added or
|
|
40
|
+
removed is put back. `--json` names them. An edit or import that an edit's
|
|
41
|
+
command runs is part of that edit, and those take turns among themselves.
|
|
42
|
+
- A memory whose folder is a git repository of its own keeps a history:
|
|
43
|
+
each kept edit and import is one commit of its `*.md` files, named for
|
|
44
|
+
the notes it changed, with the command, the project and the session in
|
|
45
|
+
its message. What changed outside `pp memory edit` since the last commit
|
|
46
|
+
is committed first, on its own. An undone edit commits nothing. `--json`
|
|
47
|
+
of edit and import gains `commit` and `outside_commit`.
|
|
48
|
+
- `pp memory check` lists the open tasks in notes (unchecked boxes, TODO
|
|
49
|
+
and FIXME lines, "next step:" lines): a memory holds what is true, and what
|
|
50
|
+
is to do belongs in a to-do list.
|
|
51
|
+
- `pp memory edit` runs its command with no input where pp has none to hand
|
|
52
|
+
on, instead of failing.
|
|
53
|
+
- `pp memory import FOLDER...` copies notes in, with `origin:` in their
|
|
54
|
+
front matter. It never writes over a file, and it lists a name that is
|
|
55
|
+
taken by other text instead of copying it.
|
|
56
|
+
- Every verb has `--json` and `--dir`. `[memory] dir`, `root` and
|
|
57
|
+
`edit_timeout` go in `config.toml`.
|
|
58
|
+
|
|
59
|
+
`pp queue`: a job's session is what a stop reaches, and what its command
|
|
60
|
+
leaves running ends with it.
|
|
61
|
+
|
|
62
|
+
- A kill or a timeout signals every process in the job's session, not only
|
|
63
|
+
its process group. A command that moves itself to a group of its own,
|
|
64
|
+
such as GNU `timeout`, no longer outlives the job. Only a process that
|
|
65
|
+
starts a session of its own (setsid) leaves it.
|
|
66
|
+
- When a job's command ends and something it started still runs in its
|
|
67
|
+
session, pp ends that the way a stop ends a job: SIGTERM, the grace, then
|
|
68
|
+
SIGKILL. The job is recorded with its command's own outcome once nothing
|
|
69
|
+
of it is left, and its slot, counters and card stay held until then,
|
|
70
|
+
or until pp's SIGKILL for what it left has had its grace.
|
|
71
|
+
- `--keep-leftovers`, or `keep_leftovers = true` in a project's `[queue]`
|
|
72
|
+
or in `[queue.NAME]`, keeps what a command that ended on its own leaves
|
|
73
|
+
running. A kill or a timeout still reaches it. `--no-keep-leftovers`
|
|
74
|
+
ends it for one job whose project keeps it.
|
|
75
|
+
- A job's `stop` gains `leftovers`, set on pp's own stop for what a command
|
|
76
|
+
left. Its `by` is "leftovers". A job record gains `keep_leftovers`.
|
|
77
|
+
- A job record's file begins with its state. A listing reads the records it
|
|
78
|
+
does not hand out no further than that, so ended jobs cost a worker's pass
|
|
79
|
+
and `status` little. A record an earlier pp wrote is read whole until a
|
|
80
|
+
pass that writes its queue's records writes it again in the new order,
|
|
81
|
+
with nothing else changed.
|
|
82
|
+
- A worker's launch pass reads its queued jobs again in one pass, not one
|
|
83
|
+
look per job. It decides on a read every reader shares whether anything
|
|
84
|
+
starts, and takes the store alone only when something does.
|
|
85
|
+
- `pp queue` reads whole only the jobs it shows. A record's head carries its
|
|
86
|
+
priority beside its state and end, which the counts and the run order
|
|
87
|
+
need. `--json` still lists every live job whole.
|
|
88
|
+
- A built-in command named exactly runs without reading every command file,
|
|
89
|
+
so every `pp NAME` starts sooner.
|
|
90
|
+
|
|
91
|
+
`pp http` can sit behind a proxy that serves it under a path.
|
|
92
|
+
|
|
93
|
+
- `--prefix /notes`, or `[http] prefix`, puts the path before every link,
|
|
94
|
+
redirect and fetch pp writes. A request is answered with the path or
|
|
95
|
+
without it, so the proxy may strip it or pass it on.
|
|
96
|
+
- `--bind unix:PATH`, or `[http] bind = "unix:PATH"`, listens on a unix
|
|
97
|
+
socket. The socket is made 0660, so its group and its folder decide who
|
|
98
|
+
connects. A socket left by a server that is gone is replaced. A live
|
|
99
|
+
one, or any other file, is refused. A request on the socket gets the
|
|
100
|
+
same Host check as one on a loopback port.
|
|
101
|
+
- Every answer says `Cache-Control: no-store` and `CDN-Cache-Control:
|
|
102
|
+
no-store`, so no cache on the way keeps a copy.
|
|
103
|
+
- `/raw/` serves scripts and stylesheets as `text/plain`, and any other
|
|
104
|
+
binary file as `application/octet-stream`. Only media keep their own
|
|
105
|
+
type. HTML and XML keep their sandbox whatever bytes they hold.
|
|
106
|
+
- Each library pp loads from cdnjs is pinned by its SRI hash, and the
|
|
107
|
+
loader refuses a file it has no hash for. The page's
|
|
108
|
+
Content-Security-Policy names each library file, and the folder of
|
|
109
|
+
highlight.js languages, instead of all of cdnjs.
|
|
110
|
+
- `.credentials*` joins the files pp never serves.
|
|
111
|
+
|
|
112
|
+
`pp http` searches the tabs: the box at the top of every page.
|
|
113
|
+
|
|
114
|
+
- `/search?q=WORDS` lists the files whose text or path holds every word,
|
|
115
|
+
each a plain substring in any case, those named for them first, then the
|
|
116
|
+
newest. Each comes with how many of its lines hold the rarest of the
|
|
117
|
+
words, counted up to 16, and up to 3 of those lines, those holding the
|
|
118
|
+
most words first, linked to the line. It reads the first 8 words and says so when it is given
|
|
119
|
+
more. `/_pp/search` gives the same as JSON.
|
|
120
|
+
- A markdown page opened at a line shows its source, where the line is.
|
|
121
|
+
- It reads only what the tabs serve, through the walk Recent takes, so a
|
|
122
|
+
hidden, excluded or denied file is never read, nor a link unless
|
|
123
|
+
`follow_symlinks` is on, when it reads what the file views serve.
|
|
124
|
+
- A search reads no file. The walk reads the text of each file that
|
|
125
|
+
changed, for up to `scan_budget` CPU seconds, and leaves the rest to the
|
|
126
|
+
next walk. A search answers from that text, so a change is found once a
|
|
127
|
+
walk has read it. The page says how long ago the walk listed the files.
|
|
128
|
+
- A binary file, one over `search_cap` (1 MB), and one past the 256 MB of
|
|
129
|
+
distinct text search keeps are matched by their path alone, and the page
|
|
130
|
+
says how many. A text two files share is kept once.
|
|
131
|
+
- It reads prose and Python by default: `*.md *.txt *.rst *.org *.tex
|
|
132
|
+
*.py`. `search` in `[http]` names other patterns.
|
|
133
|
+
|
|
134
|
+
`pp http` answers sooner.
|
|
135
|
+
|
|
136
|
+
- A walk lists a folder again only when its mtime has changed. A folder
|
|
137
|
+
changed in the last two seconds is listed again either way.
|
|
138
|
+
- The Recent walk and the search walk run when the server starts. A request
|
|
139
|
+
that comes before they end waits for them.
|
|
140
|
+
- The deny list and the globs are matched as one pattern each, and a path
|
|
141
|
+
is resolved by the kernel in one call.
|
|
142
|
+
|
|
143
|
+
`pp http` keeps the tabs you pin in its bar.
|
|
144
|
+
|
|
145
|
+
- "▾ all N" at the end of the bar lists every tab, with a filter box and a
|
|
146
|
+
pin toggle. A pinned tab stays in the bar, and its handle drags it into
|
|
147
|
+
the order you want, by mouse or by finger. The pins are kept by your
|
|
148
|
+
browser, so the server still only reads. With no pins the bar holds
|
|
149
|
+
every tab, as before.
|
|
150
|
+
- A folder page's headings sort it: click name, size or modified, and click
|
|
151
|
+
the same heading again for the other way round. Folders stay first.
|
|
152
|
+
|
|
153
|
+
`pp queue resize` changes what a job reserves: `pp queue resize 14 --gpu-gb
|
|
154
|
+
16`. It takes `--gpu-gb`, `--cpu`, `--mem-gb` and `--need NAME=N`.
|
|
155
|
+
|
|
156
|
+
- A queued or held job takes any size a pool holds, from its next start.
|
|
157
|
+
A size a retry of it could not get is refused, as at `add`.
|
|
158
|
+
- A running job can only give back what it reserves. The room is free at
|
|
159
|
+
once, so a job waiting for it starts. The run keeps what it was started
|
|
160
|
+
with, such as its cards and `PP_QUEUE_MEM_GB`.
|
|
161
|
+
- A retry of it, and `retry`, reserve what it reserved before the resize.
|
|
162
|
+
`show --json` and `status --json` gain `asked`, which holds that.
|
|
163
|
+
|
|
164
|
+
`pp queue`: a job says where it has got to with a line of its output that
|
|
165
|
+
begins `pp-event:`.
|
|
166
|
+
|
|
167
|
+
- `pp queue` shows a running job's latest event in place of its last log
|
|
168
|
+
line, and a recent job's beneath its row. `status --json` gives it as
|
|
169
|
+
`event` on each running and recent job.
|
|
170
|
+
- `show` names each attempt's latest event, and the values its events
|
|
171
|
+
state as NAME=NUMBER words, such as `peak_gpu_gb=13.2`. `show --json`
|
|
172
|
+
gives them as `event` and `values`, on the job and on each history
|
|
173
|
+
entry.
|
|
174
|
+
- `wait -f` prints each event as it comes. `wait ID --event REGEX` returns
|
|
175
|
+
0 once each job's current attempt has stated an event the pattern
|
|
176
|
+
matches, 1 where a job failed first, and 4 where one ended well without
|
|
177
|
+
stating it.
|
|
178
|
+
- Events are read from the job's own part of its log, so a container's
|
|
179
|
+
output carries them with no mount, and a retry starts with none of the
|
|
180
|
+
attempt before it.
|
|
181
|
+
|
|
182
|
+
`pp queue log` and `show` read a job's own part of a log file several jobs
|
|
183
|
+
write.
|
|
184
|
+
|
|
185
|
+
- A job's lines run from the line pp writes before each attempt to the
|
|
186
|
+
next such line, or to the end of the file. pp records where the log
|
|
187
|
+
ended once the run is over, as `log_end` on the record and on each
|
|
188
|
+
history entry. What lands after that and before the next attempt, such
|
|
189
|
+
as a stop command's output, is still the attempt's.
|
|
190
|
+
- `log` without -f printed the file's last lines, whoever wrote them, so
|
|
191
|
+
a file a lane's jobs share showed the latest job's lines under any id.
|
|
192
|
+
`log -f` read on past the job's end. `show` and a failure's tail could
|
|
193
|
+
show the next job's lines, and `status` the next job's last line.
|
|
194
|
+
- The line pp writes when it requeues a job now names the job, so it
|
|
195
|
+
counts as that job's.
|
|
196
|
+
- Jobs that write one file at the same time still mix their lines in it.
|
|
197
|
+
So can the jobs of two queues that write it one after the other.
|
|
198
|
+
|
|
199
|
+
`pp kill N` asks first when N is also the id of a queued, held or running
|
|
200
|
+
`pp queue` job.
|
|
201
|
+
|
|
202
|
+
- Job ids and pids are both small numbers, so `pp kill 14366` meant for a
|
|
203
|
+
job could signal an unrelated process with that pid at once. Such a pid
|
|
204
|
+
now shows and asks as a pattern does, and names `pp queue kill`. A
|
|
205
|
+
number that is no process but is any job's id says the same.
|
|
206
|
+
|
|
207
|
+
`pp queue add --retry-gpu-gb N`: every retry reserves at least N GB of a
|
|
208
|
+
card.
|
|
209
|
+
|
|
210
|
+
- `--retries` with `--retry-if "CUDA out of memory"` retried at the size
|
|
211
|
+
the run had run out at, which failed again. The requeue now writes the
|
|
212
|
+
larger size on the record with the attempt, and the retry waits for room
|
|
213
|
+
that size.
|
|
214
|
+
- It is a key too, `retry_gpu_gb`, in a project's `[queue]` and in
|
|
215
|
+
`[queue.NAME]`. Given as the flag it needs a `--gpu-gb`, and a size no
|
|
216
|
+
card holds is refused at add.
|
|
217
|
+
- Each history entry now carries the `needs` its attempt reserved, and
|
|
218
|
+
`show` names them.
|
|
219
|
+
|
|
220
|
+
`pp queue` hands a job's `--mem-gb` to it as `PP_QUEUE_MEM_GB`.
|
|
221
|
+
|
|
222
|
+
- It is in the job's environment and in its runner's env file, and unset
|
|
223
|
+
where the job declared none. The help's docker runner turns it into
|
|
224
|
+
`--memory` and `--memory-swap`, so a container is capped at the RAM its
|
|
225
|
+
job reserved.
|
|
226
|
+
|
|
227
|
+
Smaller changes to `pp queue`:
|
|
228
|
+
|
|
229
|
+
- Every verb takes selections separated by commas, as `--after` does:
|
|
230
|
+
`wait 41,42`. A word that holds nothing but commas is refused.
|
|
231
|
+
- `--gpu-gb 0` says that a job that needs no card leaves the flag out.
|
|
232
|
+
- The help says a container sees only what its runner mounts.
|
|
233
|
+
- The help's docker runner copies as printed. Its first line carried a
|
|
234
|
+
comment, which the kernel hands bash as the name of a script to run.
|
|
235
|
+
- `log -f` on a queued job says it waits for the job to start, and that no
|
|
236
|
+
worker is up when none is. `drop` of an ended job names `clean`.
|
|
237
|
+
- `pp help queue` is a short page, and `pp help queue containers`,
|
|
238
|
+
`settings`, `agents` and `reference` hold the rest. `pp help queue all`
|
|
239
|
+
prints every page.
|
|
240
|
+
|
|
241
|
+
`pp queue add --key KEY` queues a job once, however many times it is added.
|
|
242
|
+
|
|
243
|
+
- An add whose key a job in the store carries already adds nothing. It
|
|
244
|
+
prints that job's id on stdout, as an add does, and says so on stderr.
|
|
245
|
+
So an agent that runs an add again after losing its answer, or two
|
|
246
|
+
sessions that add one key at once, queue one job.
|
|
247
|
+
- The key is read in the transaction that stores the job. A key takes the
|
|
248
|
+
characters a tag takes, selects nothing, and is free again once `drop`
|
|
249
|
+
or `clean` removes its job. `retry` queues a job with no key.
|
|
250
|
+
- `show --json` and `status --json` gain `key`, null where none was given.
|
|
251
|
+
|
|
252
|
+
`pp queue`: the next job no longer starts beside work a lost run left.
|
|
253
|
+
|
|
254
|
+
- A runner's work outside the job's group, such as a container, outlives
|
|
255
|
+
a run that ends with no exit code of its own: the docker client was
|
|
256
|
+
killed, or pp's SIGKILL came at the end of the grace. pp recorded such a
|
|
257
|
+
job and let go of its slot, counters and card at once, and the
|
|
258
|
+
project's stop command ran after that. So the next job of a lane, or of
|
|
259
|
+
a shared counter, could start beside that container until the command
|
|
260
|
+
had ended it.
|
|
261
|
+
- What the attempt held now stays held until that stop command has
|
|
262
|
+
returned, and `pp queue status` counts it. A worker that dies before
|
|
263
|
+
starting the command leaves it to the next pass of any queue's worker,
|
|
264
|
+
which runs it once.
|
|
265
|
+
|
|
266
|
+
`pp queue clean` keeps a job whose hook has not run yet.
|
|
267
|
+
|
|
268
|
+
- A worker that dies between a job's outcome and its hook leaves the hook
|
|
269
|
+
to the next worker. A `clean` before that worker came removed the record,
|
|
270
|
+
and the hook never ran. Such a record now stays, and clean says which
|
|
271
|
+
ones it kept and how to run their hooks.
|
|
272
|
+
|
|
273
|
+
`pp queue`: a stop command that ends its job at once is still that stop's
|
|
274
|
+
outcome.
|
|
275
|
+
|
|
276
|
+
- pp read a stop's time from a finer clock than the one the system stamps
|
|
277
|
+
an exit code's file with. That clock moves in ticks of 1 to 10 ms, so a
|
|
278
|
+
code written within one tick after a stop began going out could read as
|
|
279
|
+
written before it. Such a job was recorded as its own failure, exit code
|
|
280
|
+
137, and its `on_fail` hook ran. A timeout's stop in that window was
|
|
281
|
+
recorded as the job's own failure instead of a timeout.
|
|
282
|
+
- A stop's `going`, `sent` and `kill9` are now read from the clock the
|
|
283
|
+
system stamps files with. An exit code written in the same tick as
|
|
284
|
+
`going` counts as written after it, and its code is kept.
|
|
285
|
+
|
|
286
|
+
`pp queue wait --fail-fast` returns at the first failure.
|
|
287
|
+
|
|
288
|
+
- A wait or a watch over a batch hears of a job that fails in seconds then,
|
|
289
|
+
and not when the batch's last job ends. It tells that outcome as it tells
|
|
290
|
+
any, exits 1, and leaves the jobs still to end running. Over named jobs a
|
|
291
|
+
drop counts as a failure too. `--idle` takes it as well.
|
|
292
|
+
- A wait that gives up at its `--timeout` tells first how each job that
|
|
293
|
+
ended has ended, as a watch does as it goes. It used to say only how many
|
|
294
|
+
had not ended, so a bounded wait in a loop never heard of a failure.
|
|
295
|
+
- A wait or a watch over a queued job whose queue launches nothing, because
|
|
296
|
+
`config.toml` is wrong or left empty, says so once, with the file and why.
|
|
297
|
+
- The line `add` ends with names one command, `pp queue wait IDS`, with
|
|
298
|
+
`--fail-fast` for several jobs, and `release` for held ones.
|
|
299
|
+
- `wait --mine` tells every failure this session has not heard of and the
|
|
300
|
+
latest 20 successes, and counts the rest, which later waits tell.
|
|
301
|
+
|
|
302
|
+
`pp queue --mine` shows only the queues that hold this session's jobs.
|
|
303
|
+
|
|
304
|
+
- With `--mine`, `--here` or `--project` the text view leaves out a queue
|
|
305
|
+
none of whose jobs it would list. `--json` still lists every queue.
|
|
306
|
+
- `pp queue ID` shows that job, as `pp queue show ID` does. `pp queue status
|
|
307
|
+
ID` says to use show, exit 2.
|
|
308
|
+
|
|
309
|
+
`pp queue add --ok-rc 12,13`: exit codes besides 0 that count as success.
|
|
310
|
+
|
|
311
|
+
- A job whose command ends with a code it names is done: `on_done` fires,
|
|
312
|
+
`wait` exits 0 and `--after` treats it as any ended job. The code is kept
|
|
313
|
+
on the record, so a model checker's counterexample (rc 13) is done with
|
|
314
|
+
rc 13. 0 always counts. A command a signal ended exits 128 and the
|
|
315
|
+
signal's number, so `--ok-rc 137` would count a SIGKILL as done.
|
|
316
|
+
- `ok_rc` in a project's `[queue]` or in `[queue.NAME]` sets it for every
|
|
317
|
+
job, as every per-job flag's key does.
|
|
318
|
+
- `--ok-rc 10 --ok-rc 20` is both codes, as `--ok-rc 10,20` is. A campaign
|
|
319
|
+
file's line that gives its own replaces the add's.
|
|
320
|
+
- `show` and the line `add` prints name the codes.
|
|
321
|
+
- A job record gains `ok_rc`, `[]` where none was given.
|
|
322
|
+
|
|
323
|
+
`pp queue wait -f` follows jobs, from where this session's last follow got to.
|
|
324
|
+
|
|
325
|
+
- `pp queue watch` is `wait -f`: one verb, with one set of flags.
|
|
326
|
+
|
|
327
|
+
- A monitor that runs `watch` is ended after a while and started again. The
|
|
328
|
+
next watch of the same session says every event of a job since the last
|
|
329
|
+
one it heard, and how each attempt that ended in between ended, where it
|
|
330
|
+
used to say only where the job had got to. A watch ended in the middle of
|
|
331
|
+
a pass may say that pass's lines again. A watch of another session, or
|
|
332
|
+
of none, starts where the job is, as before. A monitor process that is
|
|
333
|
+
itself started again is a new session unless `PP_SESSION` or the agent's
|
|
334
|
+
own session names it.
|
|
335
|
+
- pp keeps, on each job, where the follows of its last 8 sessions got to.
|
|
336
|
+
It writes a position when an attempt starts, every 30 seconds and as the
|
|
337
|
+
follow ends, so a follow killed outright may say its last lines again.
|
|
338
|
+
That field is pp's own and no reader is promised its shape.
|
|
339
|
+
|
|
340
|
+
`pp queue`: a job's stated peak is on its outcome line, and an add well
|
|
341
|
+
past a kin job's peak says so.
|
|
342
|
+
|
|
343
|
+
- A job whose events state `peak_gpu_gb`, `peak_mem_gb` or `peak_cpu` has
|
|
344
|
+
that beside what it reserved on the line `wait` and `watch` tell its
|
|
345
|
+
outcome on: `peak gpu_gb 16.2/32`.
|
|
346
|
+
- An add that reserves well past the peak the newest done job of its
|
|
347
|
+
family stated says so on stderr, in one line naming every job of the add
|
|
348
|
+
it covers, with the `resize` that gives room back while they run. A
|
|
349
|
+
family is one tag, or tags that differ only after their last dot.
|
|
350
|
+
|
|
351
|
+
`pp queue retry` runs ended jobs again as they ran, or with changes.
|
|
352
|
+
|
|
353
|
+
- `pp queue retry 12-14 -- --eval-ckpt last` queues each of them again with
|
|
354
|
+
one argument more. The flags `add` takes for a job's settings are taken
|
|
355
|
+
too, and win over what the job ran with, `--env` and `--need` key by key.
|
|
356
|
+
- Each new job runs in its job's directory and queue, with its tag, runner
|
|
357
|
+
and stop, and every setting it ran with, read off its record. It reserves
|
|
358
|
+
what the job asked before a resize, and records `retry_of`.
|
|
359
|
+
- A job a range, a tag or a prefix names that cannot be queued again (its
|
|
360
|
+
directory is gone, no pool holds it) is left as it is and named, and a
|
|
361
|
+
retry that queued none exits 2. One named by its id refuses the retry,
|
|
362
|
+
and nothing is queued.
|
|
363
|
+
- A retry of a `sh -c` job with words added warns that the shell reads the
|
|
364
|
+
first word as `$0`.
|
|
365
|
+
|
|
366
|
+
`pp queue add --card N` pins a job's `--gpu-gb` to card N.
|
|
367
|
+
|
|
368
|
+
- The job reserves on that card alone and waits for it, though another
|
|
369
|
+
card has room, so the arms of a timing comparison run on one card.
|
|
370
|
+
- A pin keeps no other job off its card. `card = 1` in `[queue.NAME]`
|
|
371
|
+
sends a queue's jobs to card 1, and `slots = 1` in its resources runs
|
|
372
|
+
them one at a time. A job of another queue may still take that card.
|
|
373
|
+
- A card pp does not see, `--card` on a job with no `--gpu-gb`, and a
|
|
374
|
+
size the card cannot hold are refused at `add` and at `resize`.
|
|
375
|
+
- A job record gains `card`, null where the job may take any card. `show`
|
|
376
|
+
and the line `add` prints name it.
|
|
377
|
+
|
|
378
|
+
`pp help queue` says how to read the past and run a host tool.
|
|
379
|
+
|
|
380
|
+
- `pp queue --json -n N` is a history: `recent` holds the N jobs that
|
|
381
|
+
ended latest, each with its tag, rc, started, ended and seconds.
|
|
382
|
+
- `--no-runner` runs one tool of this machine's, java for one, in a
|
|
383
|
+
project whose runner is a container.
|
|
384
|
+
- A `--no-runner` job that starts a container itself hands it its card with
|
|
385
|
+
`docker run --gpus device=$CUDA_VISIBLE_DEVICES -e CUDA_VISIBLE_DEVICES=0`.
|
|
386
|
+
`--gpus all` shows it every card, and its device 0 may be another job's.
|
|
387
|
+
|
|
388
|
+
## v0.2.2
|
|
389
|
+
|
|
390
|
+
`pp queue` records a kill as a kill when the worker sending it dies before
|
|
391
|
+
it records the send. Such a job no longer ends as its own failure, and its
|
|
392
|
+
`on_fail` hook does not run. A stop's new `going` field says when pp began
|
|
393
|
+
sending it.
|
|
394
|
+
|
|
395
|
+
`pp queue`: a kill whose worker dies while sending it is still a kill.
|
|
396
|
+
|
|
397
|
+
- A worker that died between sending a kill's stop and recording it left the
|
|
398
|
+
next worker to read the job's end as the job's own. That job was recorded
|
|
399
|
+
as its own failure, with exit code 137 or reason `lost`, and its `on_fail`
|
|
400
|
+
hook ran. It is now recorded `killed`, and no hook runs. A timeout's stop
|
|
401
|
+
in the same window now ends as a timeout.
|
|
402
|
+
- A stop gains `going` in `show --json` and `status --json`: when pp began
|
|
403
|
+
sending it, recorded before anything goes out. An exit code the attempt
|
|
404
|
+
wrote after that time is the stop's outcome, with the code kept, unless pp
|
|
405
|
+
was refused the stop. A job that ends on its own just as its worker dies
|
|
406
|
+
before sending is recorded the same way.
|
|
407
|
+
- `show` says "sending began" for a stop pp began sending and has nothing
|
|
408
|
+
marked sent for. A stop pp was refused still says "nothing signalled".
|
|
409
|
+
- `kill` reports a job that ended in that window as killed, "ended as its
|
|
410
|
+
stop was being sent", instead of saying the job had already ended.
|
|
411
|
+
|
|
412
|
+
## v0.2.1
|
|
413
|
+
|
|
414
|
+
pp finds the session that runs it with nothing set, so `--mine` works for
|
|
415
|
+
any agent and in a terminal. `pp queue` reads the cards with a command of
|
|
416
|
+
yours, and any command answers to an alias of your own. A `pp-NAME` program
|
|
417
|
+
is a command only in pp's own folders, and no longer on your `PATH`.
|
|
418
|
+
|
|
419
|
+
`pp`: a program named `pp-NAME` on your `PATH` is no longer a command.
|
|
420
|
+
|
|
421
|
+
- pp looks for such a program in `~/.config/pp/commands/`, in each plugin
|
|
422
|
+
and in each `PP_PATH` folder, and reads no `PATH` for one. Other software
|
|
423
|
+
installs programs named `pp-*`, and on `PATH` such a program takes a
|
|
424
|
+
command's name or a unique prefix of it (`pp q`) and shows in `pp -h`. A
|
|
425
|
+
program of yours stays a command by moving it into
|
|
426
|
+
`~/.config/pp/commands/`, or by listing the folder it is in in `PP_PATH`.
|
|
427
|
+
- Every Python command is still found before any such program, and the
|
|
428
|
+
programs in that folder order, so nothing pp found in those folders
|
|
429
|
+
moves.
|
|
430
|
+
|
|
431
|
+
`pp queue`: the card reading and the calling session are named by you, with
|
|
432
|
+
nvidia-smi and the process pp runs under as the defaults.
|
|
433
|
+
|
|
434
|
+
- `[resources] gpu_gb = { probe = "CMD" }` reads the machine's cards with a
|
|
435
|
+
command of yours instead of nvidia-smi. CMD prints one line a card,
|
|
436
|
+
`index,name,total_MiB,used_MiB,util`, which is nvidia-smi's own
|
|
437
|
+
`--format=csv,noheader,nounits` line, and the index it prints is the one pp
|
|
438
|
+
reserves and publishes in `CUDA_VISIBLE_DEVICES`. The reading is cached for
|
|
439
|
+
the pool's `every` and taken under the probe's own claim, as any probe's is.
|
|
440
|
+
A probe in a `[queue.NAME.resources] gpu_gb` is still refused: one machine
|
|
441
|
+
has one set of cards.
|
|
442
|
+
- `pp queue status --json` gains `cards_why`: why `cards` is null, and `""`
|
|
443
|
+
where the cards were read.
|
|
444
|
+
- pp finds the calling session from the process it runs under: the nearest
|
|
445
|
+
process above pp that is neither a shell nor a wrapper, named with its pid,
|
|
446
|
+
its start time and this boot. So `--mine` and a job's `owner` are any
|
|
447
|
+
agent's with nothing set, since every command an agent runs is a child of
|
|
448
|
+
the agent's own process, and a person's terminal is a session the same way.
|
|
449
|
+
`PP_SESSION`, where it is set and not empty, is the name an agent gives its
|
|
450
|
+
own session instead, and wins over `CLAUDE_CODE_SESSION_ID`. A process pp
|
|
451
|
+
started itself, a job or its runner or a hook or a stop command, is no
|
|
452
|
+
session. pid 1 and an init are no session either, so a `wait` left running
|
|
453
|
+
by a shell that has returned, which the kernel reparents to an init, says
|
|
454
|
+
there is none instead of answering for another session's jobs. The session
|
|
455
|
+
is found once in a run, so such a wait reports the outcomes it selected to
|
|
456
|
+
the session that queued them and no later `wait --mine` of that session
|
|
457
|
+
reports them again. pp strips those variables from everything it starts.
|
|
458
|
+
- `pp queue status --mine`, which `pp queue --mine` and `ls --mine` are too,
|
|
459
|
+
is the jobs this session queued, in every state, in the text view and in
|
|
460
|
+
`--json`'s `running`, `queued`, `held` and `recent`. It applies together
|
|
461
|
+
with `--here` and `--project`, and narrows the jobs shown and not what the
|
|
462
|
+
queues, the workers and the pools hold. Where there is no session it exits
|
|
463
|
+
2, as `wait --mine` does.
|
|
464
|
+
|
|
465
|
+
`pp`: a command answers to a name of your own.
|
|
466
|
+
|
|
467
|
+
- `[alias]` in `~/.config/pp/config.toml` names any command anything on this
|
|
468
|
+
machine: `st = "promote status"`, or a list of words. A word is resolved
|
|
469
|
+
as a command's own name, then `[alias]`, then a module's `ALIASES`, then a
|
|
470
|
+
unique prefix, so an alias hides no command and beats a prefix. `pp help
|
|
471
|
+
st` and `pp st <TAB>` follow the expansion.
|
|
472
|
+
- An alias runs no other alias. One whose key is a command's name or `help`,
|
|
473
|
+
or outside `[a-z][a-z0-9_-]*`, or whose first word names no command, is
|
|
474
|
+
skipped and listed under `pp -h`'s "broken (skipped)". The table is read
|
|
475
|
+
only where a word is not a command's exact name, so a config file that
|
|
476
|
+
cannot be parsed leaves every command pp ships working.
|
|
477
|
+
- `pp cmd alias` lists every alias of both kinds, with what it runs and
|
|
478
|
+
where it is declared (`--json` for the same as data). `pp cmd alias NAME
|
|
479
|
+
CMD [ARGS...]` adds one, `pp cmd alias NAME --rm` takes it back, and `-n`
|
|
480
|
+
prints the change and writes nothing. Those flags count wherever they
|
|
481
|
+
stand, so `pp cmd alias st promote status -n` is a dry run. A command line
|
|
482
|
+
of its own `-n`, `--rm` or `--json` goes after a `--`: `pp cmd alias dq --
|
|
483
|
+
queue drop -n`.
|
|
484
|
+
- `pp cmd alias` is the one place pp writes `config.toml`: one line of the
|
|
485
|
+
`[alias]` table under a lock, the file's mode kept, every other byte as it
|
|
486
|
+
was. A change it cannot make as one line names the file to edit by hand.
|
|
487
|
+
- `pp cmd ls` shows each command's aliases of both kinds, and its `--json`
|
|
488
|
+
rows gain `config_aliases` beside `aliases`.
|
|
489
|
+
|
|
490
|
+
`pp queue`: the views, the plans and the help say more of what pp knows
|
|
491
|
+
about your cards, your queues and your projects.
|
|
492
|
+
|
|
493
|
+
- `status --json` publishes the gpu_gb pool of each scope in `pools` and
|
|
494
|
+
`shared`, an entry like every other pool's with one field of its own:
|
|
495
|
+
`per_card`, that scope's budget on each card of the reading and what its
|
|
496
|
+
running jobs reserve on that card. The text view shows those numbers card
|
|
497
|
+
by card. So a job is sized against the smallest budget of every scope its
|
|
498
|
+
queue draws from before it is queued, instead of being refused first.
|
|
499
|
+
- `pp queue` covers every queue a `[queue.NAME]` table names, beside the
|
|
500
|
+
queues that hold records and the ones a worker is up for. Such a queue
|
|
501
|
+
with nothing in it is a section with nothing in it and an entry in
|
|
502
|
+
`--json`, and reading it creates no directory and no file. "no queues yet"
|
|
503
|
+
is for a machine with none of the three.
|
|
504
|
+
- `pp queue add` warns on stderr where the job has no runner, no `.pp.toml`
|
|
505
|
+
is in or above its directory, and a directory directly below is a project
|
|
506
|
+
whose `[queue]` sets one. The warning names that directory and `--cwd`,
|
|
507
|
+
once per directory, and the job is queued as it asks.
|
|
508
|
+
- The command `add` hands an agent names the ids it queued as ranges (`wait
|
|
509
|
+
8-13 20`), which is one word for a campaign of a hundred lines.
|
|
510
|
+
- `clean` and `drop` say in their plan that they remove the records and pp's
|
|
511
|
+
own files for them, and that a log at a path a `log` pattern or `--log`
|
|
512
|
+
named stays.
|
|
513
|
+
- The extra run of the project's stop command once a run is over writes to
|
|
514
|
+
the worker's log instead of the job's log. The stop a kill or a timeout
|
|
515
|
+
asked for still writes in the job's log.
|
|
516
|
+
- `pp help queue` names the shape of each `--json`: one object with its keys
|
|
517
|
+
for `status`, one job and its watchers for `show`, and a list of `{queue,
|
|
518
|
+
pid, how, log, up}` for `worker status`.
|
|
519
|
+
- `pp help queue` says that several selection forms are several words on one
|
|
520
|
+
verb, that a tag or a prefix selects every job of that name the store
|
|
521
|
+
holds, an earlier round's ended ones too, and that a campaign line's
|
|
522
|
+
`--cwd` is that line's own directory and so its project.
|
|
523
|
+
|
|
524
|
+
## v0.2.0
|
|
525
|
+
|
|
526
|
+
The interface this minor version keeps. `pp help queue` says what is promised
|
|
527
|
+
and what may change in a patch. `pp queue` stops what a container runner
|
|
528
|
+
started, takes a campaign from a file with one job's flags per line, and runs
|
|
529
|
+
a stage after the one it names.
|
|
530
|
+
|
|
531
|
+
`pp queue`: a job is named and selected the same way by every verb.
|
|
532
|
+
|
|
533
|
+
- A job added without `--tag` has no name. Views show its command, and a
|
|
534
|
+
selection by tag never matches it.
|
|
535
|
+
- A `--tag` is at most 64 characters of letters, digits and `.`, `_`, `-`
|
|
536
|
+
and `:`. It may not hold `..`, be `.` on its own, or read as an id or a
|
|
537
|
+
range, because a tag can be part of a log file's name.
|
|
538
|
+
- `counter` is not a queue name, beside `probes` and `watchers`: a queue of
|
|
539
|
+
that name took the place of the job id counter, and every later `add`
|
|
540
|
+
failed.
|
|
541
|
+
- Every verb that takes jobs takes the same five forms: an id, a range
|
|
542
|
+
(`12-15`), a tag matched whole, `--prefix P` (repeatable), and `--all`
|
|
543
|
+
with `-q NAME`. `--all` without `-q` is a usage error, and a tag or a
|
|
544
|
+
prefix that names jobs in two queues is an error that lists the ids.
|
|
545
|
+
`pp queue note` is the exception, and takes one job by its id or by a
|
|
546
|
+
tag that names one.
|
|
547
|
+
- `pp queue clean` takes a selection as well as `--older AGE`.
|
|
548
|
+
|
|
549
|
+
`pp queue`: a project says how its work is launched and stopped, so a kill
|
|
550
|
+
and a timeout reach work that is not in the job's process group.
|
|
551
|
+
|
|
552
|
+
- `[queue] stop` in a project's `.pp.toml`, and `--stop CMD` on `add`:
|
|
553
|
+
`"group"` where the runner's work stays in the job's own process group,
|
|
554
|
+
else a shell command that ends it. `pp queue add` is refused in a project
|
|
555
|
+
that sets `[queue] runner` and no stop, naming both spellings.
|
|
556
|
+
`--runner CMD` on `add` sets the runner for one job.
|
|
557
|
+
- In a project with a command stop, `pp queue kill` and a `--timeout` run
|
|
558
|
+
that command in place of the SIGTERM to the job's process group. The
|
|
559
|
+
grace, the SIGKILL and the sweep of the group are unchanged, so a project
|
|
560
|
+
with `stop = "group"` behaves as it did. The kill line says which ran, and
|
|
561
|
+
a stop command that failed is reported with its exit code.
|
|
562
|
+
- A job added with `--no-runner` carries `stop = "group"` whatever its
|
|
563
|
+
project says.
|
|
564
|
+
- The sweep that runs when a job's run is over also runs the project's stop
|
|
565
|
+
command, where there is one and the attempt wrote no exit code of its own,
|
|
566
|
+
and it takes the job's process group with it. So nothing the runner
|
|
567
|
+
started outlives the attempt that started it, and a leaked process no
|
|
568
|
+
longer holds a reservation the next job is told it may use.
|
|
569
|
+
- A job and its runner are given `PP_QUEUE_CONTAINER`, a name no other run
|
|
570
|
+
on the machine has, one per attempt, beginning `pp-<queue>-<id>-`; and
|
|
571
|
+
`PP_QUEUE_ENVFILE`, the path of a file of `KEY=VALUE` lines readable by
|
|
572
|
+
its owner alone. That file holds the project's `[queue] env`, the job's
|
|
573
|
+
`--env`, `CUDA_VISIBLE_DEVICES` where a card was reserved, `PP_QUEUE`,
|
|
574
|
+
`PP_QUEUE_JOB` and `PP_QUEUE_CONTAINER`, and nothing else of the
|
|
575
|
+
machine's: no `PATH`, `VIRTUAL_ENV`, `CONDA_PREFIX`, `CONDA_DEFAULT_ENV`
|
|
576
|
+
or `PP_QUEUE_RCFILE`. The record names it, and it goes with the record.
|
|
577
|
+
- An `--env` value, or a `[queue] env` value, holding a newline is refused,
|
|
578
|
+
and so is a name holding `=`, NUL or a newline.
|
|
579
|
+
- An exit code an attempt wrote while a stop of it was going out is that
|
|
580
|
+
stop's outcome, killed or timeout, with the code kept as `rc`.
|
|
581
|
+
- `pp queue kill --grace DUR` takes a duration and overrides the job's own
|
|
582
|
+
grace for the jobs that kill names.
|
|
583
|
+
|
|
584
|
+
`pp queue`: a job's output goes where the project says.
|
|
585
|
+
|
|
586
|
+
- `log` in a project's `[queue]`, and `--log PATH` on `add`: a path with
|
|
587
|
+
`{tag}` or `{id}` in it, relative to the project root or absolute. Any
|
|
588
|
+
other placeholder, a path holding `..`, and a relative path that leaves
|
|
589
|
+
the project root are refused. `{tag}` on a job with no tag is filled in
|
|
590
|
+
with the job's id.
|
|
591
|
+
- Every attempt appends to that one file, after a `[pp queue]` line naming
|
|
592
|
+
the job and its command, and several jobs may name one file. The record
|
|
593
|
+
names the file; `log`, `show`, a failure's tail and `PP_QUEUE_LOG` all
|
|
594
|
+
read it from there. `drop` and `clean` remove the files pp put in its own
|
|
595
|
+
store, and never a log at a path you named.
|
|
596
|
+
- `--retry-if` matches from the byte offset where the failed attempt's own
|
|
597
|
+
output begins, so it no longer matches an earlier attempt's lines or pp's
|
|
598
|
+
own line.
|
|
599
|
+
|
|
600
|
+
`pp queue`: a campaign file carries one job's flags per line, and a job can
|
|
601
|
+
wait for the jobs it names.
|
|
602
|
+
|
|
603
|
+
- A line of a `--from` file is the rest of an `add` command line: its own
|
|
604
|
+
flags, then `--`, then the command. A flag on the `add` is the default for
|
|
605
|
+
every line and a line's own flag wins over it; `--env` and `--need` merge
|
|
606
|
+
key by key. A line that is only a command behaves as before.
|
|
607
|
+
- A line is split into words the way a shell splits them, with quotes and
|
|
608
|
+
backslashes honoured. A line holding `|`, `&`, `;`, `<`, `>`, `(`, `)`,
|
|
609
|
+
`` ` `` or `$(` outside quotes is refused with its line number, and so is a
|
|
610
|
+
line with no `--` whose first word begins with `-`. A file one line of
|
|
611
|
+
which is refused queues nothing. A command that wants a shell operator
|
|
612
|
+
passes it quoted: `-- sh -c 'python x.py | grep -v noise'`.
|
|
613
|
+
- `--from FILE` together with a command on the same command line is a usage
|
|
614
|
+
error, and so is a line that names the queue, the file, `--hold` or
|
|
615
|
+
`--no-start`, which are the batch's and no line's.
|
|
616
|
+
- `--after SELECTION` on `add`: the job waits until every job that selection
|
|
617
|
+
named has ended, whatever the outcome. The value is one or more selections
|
|
618
|
+
separated by commas (`41,42`, `41-66`, `s1_eval,s1_report`), read as the
|
|
619
|
+
job is added and kept as ids on the record. An id no job has is a usage
|
|
620
|
+
error and nothing is queued. A job that is waiting is skipped rather than
|
|
621
|
+
waited for, so it never becomes the head of its queue, and a job whose
|
|
622
|
+
record is gone counts as ended.
|
|
623
|
+
- `pp queue retry` over a range, a tag, a prefix or `--all` shows a plan and
|
|
624
|
+
asks, as `kill` and `drop` do; `-n` shows the plan and `-y` does not ask.
|
|
625
|
+
A job that succeeded has ended, so it suits `retry`. The new job is owned
|
|
626
|
+
by the session that asked for it, and a priority is set with
|
|
627
|
+
`pp queue reprio` on the job the retry queued.
|
|
628
|
+
- A bare `pp queue wait` waits for every job that is queued or running
|
|
629
|
+
instead of returning at the first outcome. It names no held job; a
|
|
630
|
+
selection that names one waits for it and says so. `--timeout` is honoured
|
|
631
|
+
whatever `--poll` is, and ids together with `--idle` or `--mine` is a
|
|
632
|
+
usage error.
|
|
633
|
+
- A worker that adopts a running job takes the offset its output begins at
|
|
634
|
+
from the job's own run claim, so `--retry-if` reads that attempt's lines
|
|
635
|
+
and never pp's own line.
|
|
636
|
+
|
|
637
|
+
`pp queue`: every setting has one declaration, one default and one order of
|
|
638
|
+
its sources.
|
|
639
|
+
|
|
640
|
+
- Each setting of a job is a key of a project's `.pp.toml [queue]` as well
|
|
641
|
+
as of `[queue.NAME]`: `timeout`, `retries`, `retry_delay`, `retry_if`,
|
|
642
|
+
`on_fail`, `on_done`, `prio`, `gpu_gb`, `cpu`, `mem_gb`, `need`, `env`,
|
|
643
|
+
`log` and `grace`. The first source that gives a setting wins, in this
|
|
644
|
+
order: `add`'s flag, the project's `[queue]`, the queue's `[queue.NAME]`,
|
|
645
|
+
the built-in default. `env` and `need` merge key by key.
|
|
646
|
+
- `grace` is one setting of the job: `--grace DUR` on `add`, the `grace`
|
|
647
|
+
key, the resolved value on the record, and 10s by default. A timeout's
|
|
648
|
+
stop and a kill of that job both take it.
|
|
649
|
+
- Durations are read one way everywhere: `90s`, `30m`, `2h`, `1d`, a bare
|
|
650
|
+
number of seconds, `.5` and `1.5h`, and `none` where a setting offers it.
|
|
651
|
+
An empty value, a value that is not finite and one over 1e9 seconds are
|
|
652
|
+
refused, in a config key as on a command line.
|
|
653
|
+
- Numbers are bounded: `retries` at most 1000, `retry_delay` at most the
|
|
654
|
+
one-hour cap, a queue's `poll` longer than 0. A need that is 0, negative
|
|
655
|
+
or nan is refused.
|
|
656
|
+
- `pp queue work` takes no `--backfill` and no `--poll`: both are keys of
|
|
657
|
+
`[queue.NAME]`, which the queue's worker re-reads every loop, so they
|
|
658
|
+
change under running jobs with no restart.
|
|
659
|
+
|
|
660
|
+
`pp queue`: the store and the machine surface.
|
|
661
|
+
|
|
662
|
+
- A queue's `FORMAT` is 2. A pp that reads another format refuses the queue
|
|
663
|
+
where it opens it, naming the format the queue says and the one that pp
|
|
664
|
+
reads, rather than reading it.
|
|
665
|
+
- The `--json` field `gpu`, an integer, becomes `cards`, a list of card
|
|
666
|
+
indices; a job that reserved no card has `cards: []`.
|
|
667
|
+
- New `--json` fields: `stop_cmd`, `grace`, `after`, `container`, `envfile`,
|
|
668
|
+
`log_at`, and `cards`, `container`, `envfile` and `log_at` in each
|
|
669
|
+
`history` entry. `show --json` carries every promised field on a job in
|
|
670
|
+
each of the five states: a field the record does not hold yet is null, or
|
|
671
|
+
an empty list. The two exceptions are `after`, which is there only on a
|
|
672
|
+
job that names the jobs it waits for, and `stop`, only on a job asked to
|
|
673
|
+
stop.
|
|
674
|
+
- `pp help queue` is one page: a first job, a project whose work runs in a
|
|
675
|
+
container in four steps, names and selection, campaign files, the settings
|
|
676
|
+
table, how a job ends, workers, and what is left to you.
|
|
677
|
+
|
|
678
|
+
`pp kill`: `--grace DUR` takes a duration in the spelling every duration pp
|
|
679
|
+
takes has. A bare number is still seconds.
|
|
680
|
+
|
|
681
|
+
`pp promote`, `pp cmd` and `pp http`: plans under `-n`, help by flag, and
|
|
682
|
+
links one target holds.
|
|
683
|
+
|
|
684
|
+
- `pp -h NAME` and `pp --help NAME` print that command's help, as
|
|
685
|
+
`pp help NAME` does. `pp -h NAME VERB` prints the verb's.
|
|
686
|
+
- `pp promote rollback`, `pp promote link`, `pp promote init` and
|
|
687
|
+
`pp cmd new` take `-n`: each one shows its plan and changes nothing.
|
|
688
|
+
- `pp promote` does not take over a link path another target holds: the
|
|
689
|
+
refusal names that target, and `--force-links` moves the link.
|
|
690
|
+
- `pp promote status --json` has `failed`: the current release's
|
|
691
|
+
activation failed, or nothing gated it.
|
|
692
|
+
- `pp promote diff --json` has `source_gone`. A target whose project
|
|
693
|
+
directory is gone exits 1 there, in place of git's error.
|
|
694
|
+
- `pp cmd ls --json` has `aliases`, each command's short names.
|
|
695
|
+
- An unknown key in `[[http.roots]]` or `[[http.discover]]` is a config
|
|
696
|
+
error naming the file and the key, so a misspelt `marker` stops the
|
|
697
|
+
server instead of serving every folder under `under`.
|
|
698
|
+
- `pp help http` documents every `[http]` key with its default.
|
|
699
|
+
|
|
700
|
+
## v0.1.1
|
|
701
|
+
|
|
702
|
+
Fixes. A few command lines and config values that did harm are refused.
|
|
703
|
+
|
|
704
|
+
- `pp batch run` refuses a file-name field where a shell would read the
|
|
705
|
+
name again as code: inside `$( )`, backticks, `${ }`, arithmetic, a
|
|
706
|
+
`[[ ]]` test, a case pattern, a comment, `eval`, `trap`, a shell's `-c`
|
|
707
|
+
script, or a template with a heredoc or a function. The message names the
|
|
708
|
+
spelling that works: `sh -c 'cmd "$1"' sh {}`. Its plan lists every
|
|
709
|
+
command.
|
|
710
|
+
- A `pp batch rename` that is interrupted leaves a journal of what landed,
|
|
711
|
+
and `pp batch undo` takes that journal and says so.
|
|
712
|
+
- `pp promote WORD` releases nothing when the word is neither a verb nor a
|
|
713
|
+
path. It used to release the project in the current directory.
|
|
714
|
+
- A wrong value in `[promote]` is refused, naming the file and the key.
|
|
715
|
+
`name` must be one path component: `name = ".."` let `gc` remove every
|
|
716
|
+
release and plugin.
|
|
717
|
+
- `pp promote` keeps the release it flips away from, so the one you rolled
|
|
718
|
+
back to is still there after the next promote.
|
|
719
|
+
- A socket or fifo in a tree project no longer hangs `pp promote`, and a
|
|
720
|
+
file pp cannot read is a blocker that offers `exclude`.
|
|
721
|
+
- A hook that leaves a process running no longer holds `pp promote`. Each
|
|
722
|
+
hook's output is a file beside the run's log.
|
|
723
|
+
- A release that `pp promote gc` cannot remove stays whole, and gc exits 1.
|
|
724
|
+
- `pp queue`: a job that cannot start fails on its own and the rest start.
|
|
725
|
+
A job whose wrapper is still ending reads running, not lost.
|
|
726
|
+
- `pp queue --json` and `pp queue show --json` give a job's variables by
|
|
727
|
+
name, with each value `***`.
|
|
728
|
+
- An empty duration such as `--timeout ""` is a usage error, and so is an
|
|
729
|
+
empty `pp kill` target, which selected every process you own.
|
|
730
|
+
- `pp http` never serves `.git`, serves a file whose name is not UTF-8, and
|
|
731
|
+
sorts by name when `?sort=` names anything else.
|
|
732
|
+
- pp's messages and the `pp cmd add` and `update` screens escape the text
|
|
733
|
+
they name. TAB completion runs nothing in a command's name: run
|
|
734
|
+
`pp completion bash` or `zsh` again to replace a saved script.
|
|
735
|
+
- A command file whose name is not UTF-8 no longer breaks `pp -h`.
|
|
736
|
+
- pp needs Python 3.11.4 or later, which `pp promote` always needed.
|
|
737
|
+
|
|
738
|
+
## v0.1.0
|
|
739
|
+
|
|
740
|
+
The first release.
|
|
741
|
+
|
|
742
|
+
- `pp queue` runs commands later, in named queues, when the GPU memory,
|
|
743
|
+
CPUs, RAM or counters they ask for are free. Jobs have timeouts, retries
|
|
744
|
+
for the failures you name, and hooks. Tags and ranges select groups of
|
|
745
|
+
jobs. A project's `.pp.toml` can run its jobs through a runner, such as a
|
|
746
|
+
container.
|
|
747
|
+
- `pp queue wait`, `watch` and `wait --mine` tell a person or an agent how
|
|
748
|
+
jobs ended, with the end of the log for a failure.
|
|
749
|
+
- `pp promote` releases a project from a git commit when its check passes
|
|
750
|
+
on that copy, and rolls back.
|
|
751
|
+
- `pp kill`, `pp batch` and `pp http` stop processes, rename or convert
|
|
752
|
+
files, and show project folders in a browser.
|
|
753
|
+
- `pp cmd` writes commands, and adds other people's from git, pinned to the
|
|
754
|
+
commit you read.
|
|
755
|
+
- Completion for zsh and bash.
|