source: trunk/src/allmydata/scripts/slow_operation.py @ 11077ea7

Last change on this file since 11077ea7 was 11077ea7, checked in by david-sarah <david-sarah@…>, at 2010-07-12T00:30:15Z

Rename stringutils to encodingutil, and drop listdir_unicode and open_unicode (since the Python stdlib functions work fine with Unicode paths). Also move some utility functions to fileutil.

  • Property mode set to 100644
File size: 2.7 KB
Line 
1
2import os, time
3from allmydata.scripts.common import get_alias, DEFAULT_ALIAS, escape_path, \
4                                     UnknownAliasError
5from allmydata.scripts.common_http import do_http, format_http_error
6from allmydata.util import base32
7from allmydata.util.encodingutil import quote_output, is_printable_ascii
8import urllib
9import simplejson
10
11class SlowOperationRunner:
12
13    def run(self, options):
14        stderr = options.stderr
15        self.options = options
16        self.ophandle = ophandle = base32.b2a(os.urandom(16))
17        nodeurl = options['node-url']
18        if not nodeurl.endswith("/"):
19            nodeurl += "/"
20        self.nodeurl = nodeurl
21        where = options.where
22        try:
23            rootcap, path = get_alias(options.aliases, where, DEFAULT_ALIAS)
24        except UnknownAliasError, e:
25            e.display(stderr)
26            return 1
27        if path == '/':
28            path = ''
29        url = nodeurl + "uri/%s" % urllib.quote(rootcap)
30        if path:
31            url += "/" + escape_path(path)
32        # todo: should it end with a slash?
33        url = self.make_url(url, ophandle)
34        resp = do_http("POST", url)
35        if resp.status not in (200, 302):
36            print >>stderr, format_http_error("ERROR", resp)
37            return 1
38        # now we poll for results. We nominally poll at t=1, 5, 10, 30, 60,
39        # 90, k*120 seconds, but if the poll takes non-zero time, that will
40        # be slightly longer. I'm not worried about trying to make up for
41        # that time.
42
43        return self.wait_for_results()
44
45    def poll_times(self):
46        for i in (1,5,10,30,60,90):
47            yield i
48        i = 120
49        while True:
50            yield i
51            i += 120
52
53    def wait_for_results(self):
54        last = 0
55        for next in self.poll_times():
56            delay = next - last
57            time.sleep(delay)
58            last = next
59            if self.poll():
60                return 0
61
62    def poll(self):
63        url = self.nodeurl + "operations/" + self.ophandle
64        url += "?t=status&output=JSON&release-after-complete=true"
65        stdout = self.options.stdout
66        stderr = self.options.stderr
67        resp = do_http("GET", url)
68        if resp.status != 200:
69            print >>stderr, format_http_error("ERROR", resp)
70            return True
71        jdata = resp.read()
72        data = simplejson.loads(jdata)
73        if not data["finished"]:
74            return False
75        if self.options.get("raw"):
76            if is_printable_ascii(jdata):
77                print >>stdout, jdata
78            else:
79                print >>stderr, "The JSON response contained unprintable characters:\n%s" % quote_output(jdata)
80            return True
81        self.write_results(data)
82        return True
83
Note: See TracBrowser for help on using the repository browser.