mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-03-23 04:05:15 +00:00
cli: factor out slow-http-operation to a separate module
This commit is contained in:
parent
5c3e153d0e
commit
9c866ada71
74
src/allmydata/scripts/slow_operation.py
Normal file
74
src/allmydata/scripts/slow_operation.py
Normal file
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user