The kennis service¶
Every command that reads or changes the corpus is answered by one process, the kennis service for that corpus. The command line, the graphical interface and the MCP server are its clients. You never start it yourself: the first command that needs it starts it, and it stops by itself when it has been idle for a while.
How it runs¶
The first kennis search, kennis corpus add, kennis gui or agent
request finds no service and starts one, detached from the terminal that
asked. The command then waits for it to answer, which takes a moment the
first time - starting Python and loading kennis - and nothing afterwards. Every later command, window and
agent talks to the same process.
There is one service per corpus. Two commands that start one at the same moment do not start two: the second finds the first holding the corpus and uses it.
The service listens on 127.0.0.1 only, on a port the operating system
chooses, and checks a token on every request. Its address, token and
process id are in a record in kennis's state directory. That record is how
a client finds it, and the token in it is what lets a client in, so it is
kept from other accounts on the machine: on Linux and macOS the file itself
is readable by your account alone; on Windows, which has no such file
setting, it is kept in your user profile, whose permissions do the same.
On every system an administrator can read it, as they can read anything of
yours.
It stops after service.idle_minutes (30 by default) with no task queued
or running, no request in progress and no window open. A window counts as
open because it holds one connection open for as long as it is: all the
kennis tabs of one browser share that connection, through a shared worker,
since a browser allows only six connections to one address across its tabs.
While a window is open the service holds what its searches loaded - about
425 MB for a corpus of some 11,700 chunks with the default local model.
When the service stops for any reason, an open window says so. The next
command starts it again.
kennis service status # whether it runs, where, and its unfinished tasks
kennis service stop # stop it now, unless it is running a task
kennis service stop and the interface's Quit both refuse while a task
is queued or running. The service also stops when the operating system
asks it to (SIGTERM), under the same condition.
Tasks wait their turn¶
A write - an add, an index build, a sync, a note - is a task in the
service. A task that arrives while another is running waits rather than
being refused: kennis corpus add says what it is waiting behind and then
carries on. Tasks that cannot interfere run side by side: an index build
does not hold up a note, and a project's bundle has its own queue.
Cancelling a task¶
Ctrl-C on a command cancels its task, and the command waits for it to stop
and says Cancelled: nothing was changed, exiting with status 130. In the
interface, a running or waiting task's panel has a Cancel task button.
A task stops at its next step - the next document, the next page, the next progress report - and a PDF being converted by MinerU is stopped at once. Until then it has written only in its copy of the collections (see below), which is thrown away, so the corpus is exactly as it was. Once a task has begun to place its changes in the corpus it finishes, and reports what it did; a cancel that arrives then is too late to take effect. A task cancelled while it waits for another never begins.
An index build is the one exception to "nothing". Each collection's index
is swapped in whole, so one finished before the cancel is a correct index of
the corpus and is kept, and the message names it: Cancelled: the docs index
was finished first and was kept.
To leave a task running and get the terminal back, press Ctrl-Z, which
suspends the command and not the task; kennis service watch <task>
follows the task again, from any terminal. Pressing Ctrl-C a second time
while a cancel is on its way stops the watching too. Windows has no Ctrl-Z;
there, open another terminal. The line under a task's progress bar says
which keys do what, with the task's id.
A write is all or nothing¶
Every change to the three collections is made whole or not at all, and every reader sees it whole or not at all.
The slow part of a write - converting a PDF, crawling a site, fetching a
paper - runs against a copy of the collections inside the corpus's .git
folder, made with hard links so it costs a fraction of a second. Nothing
the write does there is visible. When it finishes, the service places its
changes in the corpus and commits them, while holding every reader off for
the length of that step (a few milliseconds for a note). A read that
arrives then waits for it. A note is indexed after it is placed, so a
failure while indexing leaves the note held and says it is not yet
searchable; kennis corpus index builds it.
So a task that fails or is stopped part of the way through changes nothing in the corpus. Running it again starts over. A PDF converted by the failed attempt is not converted again: conversions are kept for a day, by the file's content, so a retry costs only the writing.
Before it places anything, the service writes down which files it is about
to change. If the process is killed while placing - a power cut, a
SIGKILL - the next service to start reads that note and puts those files
back as they were, before it answers anything. The first command to reach
it then says which operation was put back, and the log records it. A
change you made by hand elsewhere in the corpus is never touched by this.
One write is refused rather than kept waiting: if another write changed the same documents while this one was being prepared, what it prepared is out of date. Nothing is changed, and the command or the interface says to run it again.
Where it reports¶
The service has no terminal. What it would have printed goes to the kennis
log, the same file every command writes; its location is on the hint:
line of any error (see Inspect and recover).
A task's progress reaches the command or the window that started it as it
happens. Everything is also in the log, including a task nobody was
watching.
Another kennis process¶
A command run from an older or newer kennis finds a service of another version. If that service is idle, the command replaces it; if it is running a task, the command says it is waiting for that task and replaces it afterwards. Two versions never write to one corpus at once.