From a877fa0fd809929b891299a9296215224af27fe3 Mon Sep 17 00:00:00 2001 From: James Kafader <jkafader@archive.org> Date: Tue, 26 Sep 2017 15:51:11 -0700 Subject: [PATCH] Adds cron garbage collector --- doublethink/services.py | 5 +++++ scripts/purge_stale_services.py | 35 +++++++++++++++++++++++++++++++++ setup.py | 1 + 3 files changed, 41 insertions(+) create mode 100644 scripts/purge_stale_services.py diff --git a/doublethink/services.py b/doublethink/services.py index 38a0f93..616b306 100644 --- a/doublethink/services.py +++ b/doublethink/services.py @@ -312,3 +312,8 @@ class ServiceRegistry(object): available_service = healthy_service available_services = healthy_services + def purge_stale_services(self, grace_period=0): + result = self.rr.table('services').filter( + lambda svc: r.now().sub(svc["last_heartbeat"]).gt(svc["ttl"] + grace_period) + ).delete().run() + return result diff --git a/scripts/purge_stale_services.py b/scripts/purge_stale_services.py new file mode 100644 index 0000000..31794c5 --- /dev/null +++ b/scripts/purge_stale_services.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +import sys +from optparse import OptionParser +from doublethink import Rethinker +from doublethink.services import ServiceRegistry + +usage = """usage: %prog [options] db +where 'db' is the the name of a RethinkDB database that contains a "services" table. + +This script can be used to periodically purge stale entries from the "services" table. + +It is designed to be used in conjunction with cron. + +Example: +%prog -s rethink-host0,rethink-host1,rethink-host2 doublethink_database""" +parser = OptionParser(usage=usage) +parser.add_option("-s", "--rethinkdb-servers", + metavar="SERVERS", dest="servers", + help="a comma-separated list of hostnames of rethinkdb servers. Required. [default: none]") +parser.add_option("-g", "--grace-period", + metavar="SECONDS", dest="grace_period", type="int", + help="leave records that have been stale for up to SECONDS seconds. [default: 0]") +(options, args) = parser.parse_args() + +if len(args) < 1: + sys.exit('"db" is a required argument and should be the name of a RethinkDB database that contains a "services" table. See "--help" for a list of options') + +if not options.servers: + sys.exit('--rethinkdb-servers (-s) is a required argument. It should be a comma-separated list of rethinkdb servers. See --help for more information') + +options.servers = [srv.strip() for srv in options.servers.split(",")] + +rethinker = Rethinker(servers=options.servers, db=args[0]) +registry = ServiceRegistry(rethinker) +registry.purge_stale_services(grace_period=options.grace_period) \ No newline at end of file diff --git a/setup.py b/setup.py index 48d7ea7..e16e560 100644 --- a/setup.py +++ b/setup.py @@ -18,4 +18,5 @@ setuptools.setup( description='rethinkdb python library', long_description=codecs.open( 'README.rst', mode='r', encoding='utf-8').read(), + scripts=glob.glob('scripts/*.py'), )