-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSyncer.py
106 lines (88 loc) · 3.72 KB
/
Syncer.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from Structs import *
from UID import *
from LCP import *
STRUCT_UID = StructBase("!Bh")
class Syncer(LCP):
SINGLETON = None
def __init__(self, port=None):
if Syncer.SINGLETON: raise("Syncer SINGLETON already exists!")
Syncer.SINGLETON = self
LCP.__init__(self, port=port)
def _create_connection(self, addr):
conn = LCP._create_connection(self, addr)
conn['ufeed'] = ""
conn['rfeed'] = ""
return conn
def feed(self, instance):
data = STRUCT_UID.pack(instance.CID, instance.IID) + instance.get_data()
for addr, conn in self.connections.iteritems():
if instance.is_feed_to(conn):
conn["ufeed"] += data
def feed_reliable(self, instance):
data = STRUCT_UID.pack(instance.CID, instance.IID) + instance.get_data()
for addr, conn in self.connections.iteritems():
if instance.is_feed_to(conn):
conn["rfeed"] += data
def remove(self, instance):
data = STRUCT_UID.pack(instance.CID, -instance.IID)
for addr, conn in self.connections.iteritems():
if instance.is_remove_to(conn):
conn["ufeed"] += data
def remove_reliable(self, instance):
data = STRUCT_UID.pack(instance.CID, -instance.IID)
for addr, conn in self.connections.iteritems():
if instance.is_remove_to(conn):
conn["rfeed"] += data
def feed_direct(self, instance, conn):
data = STRUCT_UID.pack(instance.CID, instance.IID) + instance.get_data()
conn["ufeed"] += data
def feed_reliable_direct(self, instance, conn):
data = STRUCT_UID.pack(instance.CID, instance.IID) + instance.get_data()
conn["rfeed"] += data
def remove_direct(self, instance, conn):
data = STRUCT_UID.pack(instance.CID, -instance.IID)
conn["ufeed"] += data
def remove_reliable_direct(self, instance, conn):
data = STRUCT_UID.pack(instance.CID, -instance.IID)
conn["rfeed"] += data
def process(self):
for addr, conn in self.connections.iteritems():
if conn["ufeed"]:
self.send(conn["ufeed"], addr)
conn["ufeed"] = ""
if conn["rfeed"]:
self.send_reliable(conn["rfeed"], addr)
conn["rfeed"] = ""
LCP.process(self)
def receive(self, data, conn):
offset = 0
while offset < len(data):
(CID, IID), offset = STRUCT_UID.unpacking(data, offset)
# Positive feed
if IID > 0:
class_, instance = UID_request(CID, IID)
if class_:
if class_.is_feed_accepted(instance, conn):
if not instance:
instance = class_()
UID_register(instance, IID)
offset = instance.set_data(data, offset, conn)
else:
print "Received rejected feed!"
offset = len(data)
else:
print "Received unknown class feed!"
offset = len(data)
# Negative feed (instance removal)
else:
class_, instance = UID_request(CID, -IID)
if class_:
if instance:
if instance.is_remove_accepted(conn):
UID_remove(instance)
else:
print "Received rejected remove!"
offset = len(data)
else:
print "Received unknown class remove!"
offset = len(data)