Skip to content

Commit aab2352

Browse files
author
burivuh
committed
make a copy of userinfo and eventtime structures (are created on the stack in C)
1 parent 4edde70 commit aab2352

File tree

2 files changed

+79
-50
lines changed

2 files changed

+79
-50
lines changed

snippets/pyaloha/ccode.py

+75-45
Original file line numberDiff line numberDiff line change
@@ -28,33 +28,43 @@ class CEVENTTIME(ctypes.Structure):
2828
('server_upload', ctypes.c_uint64)
2929
]
3030

31-
__slots__ = (
32-
'client_creation', 'server_upload',
33-
'dtime', 'is_accurate'
34-
)
35-
3631
delta_past = datetime.timedelta(days=6 * 30)
3732
delta_future = datetime.timedelta(days=1)
3833

39-
def _setup_time(self):
34+
def get_approx_time(self):
35+
if not self.dtime:
36+
self._setup_time()
37+
return self.dtime, self.is_accurate
38+
39+
def make_object(self):
4040
client_dtime = SerializableDatetime.utcfromtimestamp(
4141
self.client_creation / 1000. # timestamp is in millisecs
4242
)
4343
server_dtime = SerializableDatetime.utcfromtimestamp(
4444
self.server_upload / 1000. # timestamp is in millisecs
4545
)
4646

47-
self.dtime = server_dtime
48-
self.is_accurate = False
47+
dtime = server_dtime
4948
if client_dtime >= server_dtime - CEVENTTIME.delta_past and\
5049
client_dtime <= server_dtime + CEVENTTIME.delta_future:
51-
self.dtime = client_dtime
52-
self.is_accurate = True
50+
dtime = client_dtime
5351

54-
def get_approx_time(self):
55-
if not self.dtime:
56-
self._setup_time()
57-
return self.dtime, self.is_accurate
52+
pytime = PythonEventTime()
53+
pytime.client_creation = client_dtime
54+
pytime.server_upload = server_dtime
55+
pytime.dtime = dtime
56+
return pytime
57+
58+
59+
class PythonEventTime(object):
60+
__slots__ = (
61+
'client_creation', 'server_upload',
62+
'dtime', 'is_accurate'
63+
)
64+
65+
@property
66+
def is_accurate(self):
67+
return self.dtime == self.client_creation
5868

5969
def __dumpdict__(self):
6070
return {
@@ -72,20 +82,6 @@ class IDInfo(ctypes.Structure):
7282

7383
__slots__ = ('os', 'uid')
7484

75-
def __dumpdict__(self):
76-
return {
77-
'os': self.os
78-
}
79-
80-
def is_on_android(self):
81-
return self.os == 1
82-
83-
def is_on_ios(self):
84-
return self.os == 2
85-
86-
def is_on_unknown_os(self):
87-
return self.os == 0
88-
8985
def validate(self):
9086
if self.os not in IDInfo._os_valid_range:
9187
raise ValueError('Incorrect os value: %s' % self.os)
@@ -113,13 +109,6 @@ def get_location(self):
113109
return (self.lat, self.lon)
114110
return None
115111

116-
def __dumpdict__(self):
117-
dct = super(GeoIDInfo, self).__dumpdict__()
118-
if self.has_geo():
119-
dct['lat'] = round(self.lat, 6)
120-
dct['lon'] = round(self.lon, 6)
121-
return dct
122-
123112

124113
class CUSERINFO(GeoIDInfo):
125114
_fields_ = [
@@ -128,19 +117,60 @@ class CUSERINFO(GeoIDInfo):
128117

129118
__slots__ = ('raw_uid',)
130119

131-
def setup(self):
120+
def make_object(self):
132121
self.validate()
133-
setattr(self, 'uid', int(self.raw_uid, 16))
134122

135-
def stripped(self):
136123
if self.has_geo():
137-
return GeoIDInfo(
138-
uid=self.uid, os=self.os,
139-
lat=self.lat, lon=self.lon
140-
)
141-
return IDInfo(
142-
uid=self.uid, os=self.os
143-
)
124+
pyinfo = PythonGeoUserInfo()
125+
pyinfo.uid = int(self.raw_uid, 16)
126+
pyinfo.os = self.os
127+
pyinfo.lat = round(self.lat, 6)
128+
pyinfo.lon = round(self.lon, 6)
129+
return pyinfo
130+
131+
pyinfo = PythonUserInfo()
132+
pyinfo.uid = int(self.raw_uid, 16)
133+
pyinfo.os = self.os
134+
return pyinfo
135+
136+
137+
class PythonUserInfo(object):
138+
__slots__ = ('uid', 'os')
139+
140+
@property
141+
def has_geo(self):
142+
return False
143+
144+
def is_on_android(self):
145+
return self.os == 1
146+
147+
def is_on_ios(self):
148+
return self.os == 2
149+
150+
def is_on_unknown_os(self):
151+
return self.os == 0
152+
153+
def __dumpdict__(self):
154+
return {
155+
'os': self.os,
156+
'uid': self.uid
157+
}
158+
159+
160+
class PythonGeoUserInfo(PythonUserInfo):
161+
__slots__ = ('lat', 'lon')
162+
163+
@property
164+
def has_geo(self):
165+
return True
166+
167+
def __dumpdict__(self):
168+
d = super(PythonGeoUserInfo, self).__dumpdict__()
169+
d.update({
170+
'lat': self.lat,
171+
'lon': self.lon
172+
})
173+
return d
144174

145175

146176
CCALLBACK = ctypes.CFUNCTYPE(

snippets/pyaloha/event.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ def __init__(self,
55
if data_list_len:
66
self.data_list = data_list
77
self.data_list_len = data_list_len
8-
event_time._setup_time()
9-
self.event_time = event_time
10-
self.user_info = user_info
11-
self.user_info.setup()
8+
9+
self.event_time = event_time.make_object()
10+
self.user_info = user_info.make_object()
1211
self.key = key
1312

1413
def process_me(self, processor):
@@ -21,7 +20,7 @@ def __dumpdict__(self):
2120
return {
2221
'key': self.key,
2322
'type': self.__class__.__name__,
24-
'user_info': self.user_info.stripped(),
23+
'user_info': self.user_info,
2524
'event_time': self.event_time
2625
}
2726

0 commit comments

Comments
 (0)