-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.py
141 lines (124 loc) · 4.7 KB
/
server.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'carlo'
import time
from SimpleXMLRPCServer import SimpleXMLRPCServer
# In case of test we must put on False bind_and_activate on SimpleXMLRPCServer
TEST_MODE = False
NORMAL_USE = True
class CacheServer(object):
def __init__(self, addr='localhost', port=8080, mode=NORMAL_USE):
self.key_container = {}
self.server_state = True
self.server = SimpleXMLRPCServer((addr, port), allow_none=True, bind_and_activate=mode)
self.server.register_function(self.set)
self.server.register_function(self.get)
self.server.register_function(self.delete)
self.server.register_function(self.set_many)
self.server.register_function(self.get_many)
self.server.register_function(self.delete_many)
self.server.register_function(self.incr)
self.server.register_function(self.decr)
self.server.register_function(self.quit)
def get(self, key):
"""
Get method that search a key in self.key_container.
If the key is present and not expired the relative value is returned
:param key: The searched key
:return: The value relative of key if the key is present and not expired
"""
if key in self.key_container:
searched = self.key_container[key]
if searched[1] is not None and searched[1] <= time.time():
self.key_container.pop(key, None)
return None
else:
return searched[0]
return None
def set(self, key, value, timeout=None):
"""
Allow to set a key with a value and optional timeout
:param key: The name of key to be entered
:param value: the value relative the entered key
:param timeout: Optional timeout of value entered
"""
if timeout is not None:
time_key = time.time() + timeout
else:
time_key = None
self.key_container[key] = [value, time_key]
def delete(self, key):
"""
Delete the key entered if it exist
:param key: The name of the key deleted
"""
try:
self.key_container.pop(key)
except KeyError:
pass
def set_many(self, received_keys):
"""
Allow to set of many key
:param received_keys: A dictionary contain key and relative value
"""
for key, value in received_keys.iteritems():
self.set(key, value)
def get_many(self, searched_list):
"""
Receive an array of searched key and return an array with the relative key if they are present.
If some/all key are missing the result array contain None in the same spot of missing key.
:param searched_list: Array containing searched keys
:return: Array with value relative of entered keys
"""
response = []
for key in searched_list:
if key in self.key_container:
response.append(self.get(key))
else:
response.append(None)
return response
def delete_many(self, delete_list):
"""
Receive an array of key and delete all relative value if present.
:param delete_list: A list of key to be deleted
"""
for key in delete_list:
self.delete(key)
def incr(self, key, val=1):
"""
Increment the value relative key by the same value received in val, default 1.
if the key is not present, or the relative value is not a number or the received val is not a number
raise ValueError.
:param key: The key incremented
:param val: The value incremented
"""
try:
self.key_container[key][0] += val
except (TypeError, KeyError, ValueError):
raise ValueError
def decr(self, key, val=1):
"""
Decrement the value relative key by the same value received in val, default 1.
if the key is not present, or the relative value is not a number or the received val is not a number
raise ValueError.
:param key: The key decremented
:param val: The value decremented
"""
try:
self.key_container[key][0] -= val
except (TypeError, KeyError, ValueError):
raise ValueError
def quit(self):
self.server_state = False
def start_server(self):
try:
while self.server_state:
self.server.handle_request()
print '\nKey_container contain:', self.key_container, '\n'
except KeyboardInterrupt:
pass
def main():
server = CacheServer()
server.start_server()
if __name__ == '__main__':
main()