ia64/xen-unstable

view tools/python/xen/xend/xenstore/xstransact.py @ 6844:eb6fbb3d0a7b

Add gather function and robustify class methods' failure handling.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Wed Sep 14 18:24:25 2005 +0000 (2005-09-14)
parents 574aeba9859d
children d5497a215660
line source
1 # Copyright (C) 2005 Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
3 # This file is subject to the terms and conditions of the GNU General
4 # Public License. See the file "COPYING" in the main directory of
5 # this archive for more details.
7 import errno
8 import threading
9 from xen.lowlevel import xs
10 from xen.xend.xenstore.xsutil import xshandle
12 class xstransact:
14 def __init__(self, path):
15 self.in_transaction = False
16 self.path = path.rstrip("/")
17 while True:
18 try:
19 xshandle().transaction_start(path)
20 self.in_transaction = True
21 return
22 except RuntimeError, ex:
23 if ex.args[0] == errno.ENOENT and path != "/":
24 path = "/".join(path.split("/")[0:-1]) or "/"
25 else:
26 raise
28 def __del__(self):
29 if self.in_transaction:
30 xshandle().transaction_end(True)
32 def commit(self):
33 if not self.in_transaction:
34 raise RuntimeError
35 self.in_transaction = False
36 return xshandle().transaction_end(False)
38 def abort(self):
39 if not self.in_transaction:
40 raise RuntimeError
41 self.in_transaction = False
42 return xshandle().transaction_end(True)
44 def _read(self, key):
45 path = "%s/%s" % (self.path, key)
46 return xshandle().read(path)
48 def read(self, *args):
49 if len(args) == 0:
50 raise TypeError
51 if len(args) == 1:
52 return self._read(args[0])
53 ret = []
54 for key in args:
55 ret.append(self._read(key))
56 return ret
58 def _write(self, key, data, create=True, excl=False):
59 path = "%s/%s" % (self.path, key)
60 xshandle().write(path, data, create=create, excl=excl)
62 def write(self, *args, **opts):
63 create = opts.get('create') or True
64 excl = opts.get('excl') or False
65 if len(args) == 0:
66 raise TypeError
67 if isinstance(args[0], dict):
68 for d in args:
69 if not isinstance(d, dict):
70 raise TypeError
71 for key in d.keys():
72 self._write(key, d[key], create, excl)
73 elif isinstance(args[0], list):
74 for l in args:
75 if not len(l) == 2:
76 raise TypeError
77 self._write(l[0], l[1], create, excl)
78 elif len(args) % 2 == 0:
79 for i in range(len(args) / 2):
80 self._write(args[i * 2], args[i * 2 + 1], create, excl)
81 else:
82 raise TypeError
84 def _remove(self, key):
85 path = "%s/%s" % (self.path, key)
86 return xshandle().rm(path)
88 def remove(self, *args):
89 if len(args) == 0:
90 raise TypeError
91 for key in args:
92 self._remove(key)
94 def _list(self, key):
95 path = "%s/%s" % (self.path, key)
96 l = xshandle().ls(path)
97 if l:
98 return map(lambda x: key + "/" + x, l)
99 return []
101 def list(self, *args):
102 if len(args) == 0:
103 raise TypeError
104 ret = []
105 for key in args:
106 ret.extend(self._list(key))
107 return ret
109 def gather(self, *args):
110 ret = []
111 for tup in args:
112 if len(tup) == 2:
113 (key, fn) = tup
114 defval = None
115 else:
116 (key, fn, defval) = tup
117 try:
118 val = fn(self.read(key))
119 except TypeError:
120 val = defval
121 ret.append(val)
122 if len(ret) == 1:
123 return ret[0]
124 return ret
127 def Read(cls, path, *args):
128 while True:
129 try:
130 t = cls(path)
131 v = t.read(*args)
132 t.commit()
133 return v
134 except RuntimeError, ex:
135 t.abort()
136 if ex.args[0] == errno.ETIMEDOUT:
137 pass
138 else:
139 raise
140 except:
141 t.abort()
142 raise
144 Read = classmethod(Read)
146 def Write(cls, path, *args, **opts):
147 while True:
148 try:
149 t = cls(path)
150 t.write(*args, **opts)
151 t.commit()
152 return
153 except RuntimeError, ex:
154 t.abort()
155 if ex.args[0] == errno.ETIMEDOUT:
156 pass
157 else:
158 raise
159 except:
160 t.abort()
161 raise
163 Write = classmethod(Write)
165 def Remove(cls, path, *args):
166 while True:
167 try:
168 t = cls(path)
169 t.remove(*args)
170 t.commit()
171 return
172 except RuntimeError, ex:
173 t.abort()
174 if ex.args[0] == errno.ETIMEDOUT:
175 pass
176 else:
177 raise
178 except:
179 t.abort()
180 raise
182 Remove = classmethod(Remove)
184 def List(cls, path, *args):
185 while True:
186 try:
187 t = cls(path)
188 v = t.list(*args)
189 t.commit()
190 return v
191 except RuntimeError, ex:
192 t.abort()
193 if ex.args[0] == errno.ETIMEDOUT:
194 pass
195 else:
196 raise
197 except:
198 t.abort()
199 raise
201 List = classmethod(List)
203 def Gather(cls, path, *args):
204 while True:
205 try:
206 t = cls(path)
207 v = t.gather(*args)
208 t.commit()
209 return v
210 except RuntimeError, ex:
211 t.abort()
212 if ex.args[0] == errno.ETIMEDOUT:
213 pass
214 else:
215 raise
216 except:
217 t.abort()
218 raise
220 Gather = classmethod(Gather)