From 9c866ada71c5b0f42ae04be8e96beec3838c68d2 Mon Sep 17 00:00:00 2001 From: Brian Warner Date: Tue, 18 Nov 2008 19:11:13 -0700 Subject: [PATCH] cli: factor out slow-http-operation to a separate module --- src/allmydata/scripts/slow_operation.py | 74 +++++++++++++++++++++++ src/allmydata/scripts/tahoe_manifest.py | 80 +++---------------------- 2 files changed, 81 insertions(+), 73 deletions(-) create mode 100644 src/allmydata/scripts/slow_operation.py diff --git a/src/allmydata/scripts/slow_operation.py b/src/allmydata/scripts/slow_operation.py new file mode 100644 index 00000000..1f8a99a1 --- /dev/null +++ b/src/allmydata/scripts/slow_operation.py @@ -0,0 +1,74 @@ + +import os, time +from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path +from allmydata.scripts.common_http import do_http +from allmydata.util import base32 +import urllib +import simplejson + +class SlowOperationRunner: + + def run(self, options): + stderr = options.stderr + self.options = options + self.ophandle = ophandle = base32.b2a(os.urandom(16)) + nodeurl = options['node-url'] + if not nodeurl.endswith("/"): + nodeurl += "/" + self.nodeurl = nodeurl + where = options.where + rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) + if path == '/': + path = '' + url = nodeurl + "uri/%s" % urllib.quote(rootcap) + if path: + url += "/" + escape_path(path) + # todo: should it end with a slash? + url = self.make_url(url, ophandle) + resp = do_http("POST", url) + if resp.status not in (200, 302): + print >>stderr, "ERROR", resp.status, resp.reason, resp.read() + return 1 + # now we poll for results. We nominally poll at t=1, 5, 10, 30, 60, + # 90, k*120 seconds, but if the poll takes non-zero time, that will + # be slightly longer. I'm not worried about trying to make up for + # that time. + + return self.wait_for_results() + + def poll_times(self): + for i in (1,5,10,30,60,90): + yield i + i = 120 + while True: + yield i + i += 120 + + def wait_for_results(self): + last = 0 + for next in self.poll_times(): + delay = next - last + time.sleep(delay) + last = next + if self.poll(): + return 0 + + def poll(self): + url = self.nodeurl + "operations/" + self.ophandle + url += "?t=status&output=JSON&release-after-complete=true" + stdout = self.options.stdout + stderr = self.options.stderr + resp = do_http("GET", url) + if resp.status != 200: + print >>stderr, "ERROR", resp.status, resp.reason, resp.read() + return True + jdata = resp.read() + data = simplejson.loads(jdata) + if not data["finished"]: + return False + if self.options.get("raw"): + print >>stdout, jdata + return True + self.write_results(data) + return True + diff --git a/src/allmydata/scripts/tahoe_manifest.py b/src/allmydata/scripts/tahoe_manifest.py index 7f3696f3..c7aac42c 100644 --- a/src/allmydata/scripts/tahoe_manifest.py +++ b/src/allmydata/scripts/tahoe_manifest.py @@ -1,80 +1,12 @@ -import os, time -from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path -from allmydata.scripts.common_http import do_http from allmydata.util import base32 from allmydata import uri -import urllib -import simplejson - -class SlowOperationRunner: - - def run(self, options): - stderr = options.stderr - self.options = options - self.ophandle = ophandle = base32.b2a(os.urandom(16)) - nodeurl = options['node-url'] - if not nodeurl.endswith("/"): - nodeurl += "/" - self.nodeurl = nodeurl - where = options.where - rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS) - if path == '/': - path = '' - url = nodeurl + "uri/%s" % urllib.quote(rootcap) - if path: - url += "/" + escape_path(path) - # todo: should it end with a slash? - url += "?t=%s&ophandle=%s" % (self.operation, ophandle) - resp = do_http("POST", url) - if resp.status not in (200, 302): - print >>stderr, "ERROR", resp.status, resp.reason, resp.read() - return 1 - # now we poll for results. We nominally poll at t=1, 5, 10, 30, 60, - # 90, k*120 seconds, but if the poll takes non-zero time, that will - # be slightly longer. I'm not worried about trying to make up for - # that time. - - return self.wait_for_results() - - def poll_times(self): - for i in (1,5,10,30,60,90): - yield i - i = 120 - while True: - yield i - i += 120 - - def wait_for_results(self): - last = 0 - for next in self.poll_times(): - delay = next - last - time.sleep(delay) - last = next - if self.poll(): - return 0 - - def poll(self): - url = self.nodeurl + "operations/" + self.ophandle - url += "?t=status&output=JSON&release-after-complete=true" - stdout = self.options.stdout - stderr = self.options.stderr - resp = do_http("GET", url) - if resp.status != 200: - print >>stderr, "ERROR", resp.status, resp.reason, resp.read() - return True - jdata = resp.read() - data = simplejson.loads(jdata) - if not data["finished"]: - return False - if self.options.get("raw"): - print >>stdout, jdata - return True - self.write_results(data) - return True +from allmydata.scripts.slow_operation import SlowOperationRunner class ManifestGrabber(SlowOperationRunner): - operation = "start-manifest" + + def make_url(self, base, ophandle): + return base + "?t=start-manifest&ophandle=" + ophandle def write_results(self, data): stdout = self.options.stdout @@ -97,7 +29,9 @@ def manifest(options): return ManifestGrabber().run(options) class StatsGrabber(SlowOperationRunner): - operation = "start-deep-stats" + + def make_url(self, base, ophandle): + return base + "?t=start-deep-stats&ophandle=" + ophandle def write_results(self, data): stdout = self.options.stdout -- 2.45.2