Skip to content

Instantly share code, notes, and snippets.

@maphew
Last active March 17, 2020 04:53
Show Gist options
  • Save maphew/b46aac7687ace48a6467e2dc84ed6fbd to your computer and use it in GitHub Desktop.
Save maphew/b46aac7687ace48a6467e2dc84ed6fbd to your computer and use it in GitHub Desktop.
Leo scripts to manage History Tracer plugin daemon

An edited excerpt from the console which started Leo

don't forget to launch leo-ver-serv!!!
==== @int history-tracer-port=8088 ====
Looking for 'leo-ver-serv' processes...
   PID   Name                   Status    
  3815   leo-ver-serv           sleeping  
========================================

This is just after Leo startup. The first thing I did was run the list services script. Sleeping is normal status for the server.

But let's pretend we don't know this and we attempt to start the service:

Running: leo-ver-serv /home/matt/.leo/.leoRecentFiles.txt 8088
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 98, kind: AddrInUse, message: "Address already in use" }', src/libcore/result.rs:1188:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

Uhoh. List the services again:

==== @int history-tracer-port=8088 ====
Looking for 'leo-ver-serv' processes...
   PID   Name                   Status    
  3815   leo-ver-serv           sleeping  
  5335   leo-ver-serv           zombie    
========================================

So we still have our first real servivce, and a new zombie because of the crash above.

Let's try and shut them down gracefully, and then list again:

process psutil.Process(pid=5335, status='terminated') terminated with exit code 101
process psutil.Process(pid=3815, status='terminated') terminated with exit code None
==== @int history-tracer-port=8088 ====
Looking for 'leo-ver-serv' processes...
   PID   Name                   Status    
========================================

The double bar immediately following 'Status' indicates no services found. In the next version we should have it say None and remove guesswork.

@language python
g.es_print("====", c.p.h, "====")
g.es_print("Looking for 'leo-ver-serv' processes...")
import psutil
process = [proc for proc in psutil.process_iter() if proc.name() == "leo-ver-serv"]
# g.es_print(f"Process: {process}") # debug
g.es_print("{:>6} {:<20} {:<10}".format('PID', 'Name', 'Status'))
for p in process:
g.es_print("{:>6} {:<20} {:<10}".format(p.pid, p.name(), p.status()))
# g.es_print(p.open_files()) # raises AccessDenied if not run as root
#g.es_print(p.children()) # not needed, always empty (so far)
g.es_print("=" * 40)
@language python
'''Start 'leo-ver-serv' for History Tracer plugin'''
import os
watchfiles = os.path.join(g.computeHomeDir(), '.leo/.leoRecentFiles.txt')
if os.path.exists(watchfiles):
g.es_print(f"Running: leo-ver-serv {watchfiles} 8088")
os.spawnlp(os.P_NOWAIT, 'leo-ver-serv', watchfiles, '8088')
else:
g.es_print(f"Couldn't find {watchfiles}")
'''TODO: see if can use psutils instead for better communication/monitoring
https://psutil.readthedocs.io/en/latest/#popen-class'''
@language python
'''Gracefully shutdown any processes named 'leo-ver-serv'
Adapted from https://psutil.readthedocs.io/en/latest/#psutil.wait_procs
'''
import psutil
def on_terminate(proc):
print("process {} terminated with exit code {}".format(proc, proc.returncode))
procs = [proc for proc in psutil.process_iter() if proc.name() == "leo-ver-serv"]
for p in procs:
p.terminate()
gone, alive = psutil.wait_procs(procs, timeout=3, callback=on_terminate)
for p in alive:
p.kill()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment