cocoindex-io / cocoindex-io/cocoindex-code
Killing a stale daemon deletes the live daemon's socket
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 2.7k
- Forks
- 217
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 4
Description
A daemon unlinks daemon.sock on shutdown without checking whether the node at that path is still its own. So killing a stranded daemon removes the live daemon's socket: that daemon keeps running but is unreachable, and the next client spawns a replacement. kill / pkill cleanup raises the process count instead of lowering it.
S=~/.cocoindex_code/daemon.sock
ccc daemon status # a daemon is live (not passive — self-starts)
A=$(cat ~/.cocoindex_code/daemon.pid)
ls -i $S # 179763394 ...daemon.sock <- A's node
nohup ccc run-daemon >/dev/null 2>&1 & sleep 5
B=$(cat ~/.cocoindex_code/daemon.pid)
ls -i $S # 179763419 ...daemon.sock <- B unlinked A's node, bound its own
Both daemons still hold a socket, and both report the same path — but they are different objects, and only B's is the one at the path:
$ lsof -p $A -p $B | grep daemon.sock
python3.1 40288 ... 12u unix 0x31379fddf5fa3701 ... /Users/…/daemon.sock <- A, unlinked
python3.1 40341 ... 14u unix 0x72f981a44d8e296f ... /Users/…/daemon.sock <- B, at the path
Now SIGTERM the displaced daemon:
kill $A; sleep 2
ls -i $S # No such file or directory — A deleted B's node
kill -0 $B && echo "B alive, no socket"
The shutdown block guards one artifact and not the other (daemon.py, 0.2.32):
if sys.platform != "win32":
try:
Path(sock_path).unlink(missing_ok=True) # unconditional
except Exception:
pass
try:
stored = pid_path.read_text().strip()
if stored == str(os.getpid()): # guarded
pid_path.unlink(missing_ok=True)
The PID file has the "am I still the owner?" test; the socket doesn't. Recording the socket's inode at bind time and unlinking only on a match would close it.
Separate from #243, which serializes client startup but doesn't touch this path.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in daemon.py at the shutdown block for ccc run-daemon and trace where the Unix socket is bound. Reproduce the two-daemon scenario from the issue, then verify that stopping a displaced daemon leaves the live daemon's socket available while its own cleanup still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100