-
Notifications
You must be signed in to change notification settings - Fork 0
/
storage.py
47 lines (38 loc) · 1.48 KB
/
storage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import gravel_master
import graveldb
import re
PATH = '/gravel/system/master'
class Box(graveldb.Table('boxes', PATH)):
default = dict(type=None, active=None, backups=[], new=True, ready=False,
options={})
autocreate = False
def validate(self):
if not re.match('^[a-zA-Z0-9:_.]+$', self.name):
raise ValueError('invalid name')
def set_active(self, target):
if self.data.ready and self.data.active == target.name:
return
if self.data.active and self.data.active != target.name:
gravel_master.Node(self.data.active).call('storage', 'deactivate', self.name)
self.data.active = None
self.save()
with self:
if self.data.active:
raise graveldb.RaceConditionError('somebody took over Box, before we managed to')
self.data.active = target.name
self.data.ready = False
self.save()
target.call('storage', 'activate', self.name)
self.data.new = False
self.data.ready = True
self.save()
def get_fetchinfo(self):
if self.data.new:
return dict(new=True)
elif self.data.active:
target_node = self.data.active
elif self.data.backups:
date, target_node = sorted(self.data.backups)[0]
else:
raise Exception('zero replicas')
return gravel_master.Node(target_node).arrange_p2p('storage', 'transfer', self.name)