Skip to content

Commit 561cfb5

Browse files
committedSep 14, 2014
Move server list management functions into a class
1 parent e93a04f commit 561cfb5

File tree

1 file changed

+99
-87
lines changed

1 file changed

+99
-87
lines changed
 

‎server.py

+99-87
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,14 @@
66
from apscheduler.scheduler import Scheduler
77
from flask import Flask, request, send_from_directory
88

9-
serverList = []
10-
maxServers = 0
11-
maxClients = 0
12-
listLock = RLock()
139

1410
sched = Scheduler()
1511
sched.start()
1612

1713
app = Flask(__name__, static_url_path = "")
1814
app.config.from_pyfile("config.py")
1915

16+
2017
@app.route("/")
2118
def index():
2219
return app.send_static_file("index.html")
@@ -71,13 +68,13 @@ def announce():
7168
server["port"] = int(server["port"])
7269
#### End compatability code ####
7370

74-
old = getServer(server["ip"], server["port"])
71+
old = serverList.get(server["ip"], server["port"])
7572

7673
if server["action"] == "delete":
7774
if not old:
7875
return "Server not found.", 500
79-
removeServer(old)
80-
saveList()
76+
serverList.remove(old)
77+
serverList.save()
8178
return "Removed from server list."
8279
elif not checkRequest(server):
8380
return "Invalid JSON data.", 400
@@ -117,7 +114,7 @@ def announce():
117114
# Popularity
118115
if old:
119116
server["updates"] = old["updates"] + 1
120-
# This is actally a count of all the client numbers we've received,
117+
# This is actually a count of all the client numbers we've received,
121118
# it includes clients that were on in the previous update.
122119
server["total_clients"] = old["total_clients"] + server["clients"]
123120
else:
@@ -130,6 +127,11 @@ def announce():
130127
return "Thanks, your request has been filed.", 202
131128

132129

130+
@sched.interval_schedule(minutes=1, coalesce=True, max_instances=1)
131+
def purgeOld():
132+
serverList.purgeOld()
133+
134+
133135
# Returns ping time in seconds (up), False (down), or None (error).
134136
def serverUp(address, port):
135137
try:
@@ -153,75 +155,6 @@ def serverUp(address, port):
153155
return None
154156

155157

156-
def getServerAndIndex(ip, port):
157-
with listLock:
158-
for i, server in enumerate(serverList):
159-
if server["ip"] == ip and server["port"] == port:
160-
return (i, server)
161-
162-
163-
def getServer(ip, port):
164-
server = getServerAndIndex(ip, port)
165-
return server and server[1]
166-
167-
168-
def removeServer(server):
169-
with listLock:
170-
try:
171-
serverList.remove(server)
172-
except:
173-
pass
174-
175-
176-
def sortList():
177-
with listLock:
178-
serverList.sort(key=itemgetter("clients", "start"), reverse=True)
179-
180-
@sched.interval_schedule(minutes=1, coalesce=True, max_instances=1)
181-
def purgeOld():
182-
with listLock:
183-
for server in serverList:
184-
if server["update_time"] < time.time() - app.config["PURGE_TIME"]:
185-
serverList.remove(server)
186-
saveList()
187-
188-
189-
def loadList():
190-
global serverList, maxServers, maxClients
191-
try:
192-
with open(os.path.join("static", app.config["FILENAME"]), "r") as fd:
193-
data = json.load(fd)
194-
except FileNotFoundError:
195-
return
196-
if not data:
197-
return
198-
with listLock:
199-
serverList = data["list"]
200-
maxServers = data["total_max"]["servers"]
201-
maxClients = data["total_max"]["clients"]
202-
203-
204-
def saveList():
205-
global maxServers, maxClients
206-
with listLock:
207-
servers = len(serverList)
208-
clients = 0
209-
for server in serverList:
210-
clients += server["clients"]
211-
212-
maxServers = max(servers, maxServers)
213-
maxClients = max(clients, maxClients)
214-
215-
with open(os.path.join("static", app.config["FILENAME"]), "w") as fd:
216-
json.dump({
217-
"total": {"servers": servers, "clients": clients},
218-
"total_max": {"servers": maxServers, "clients": maxClients},
219-
"list": serverList
220-
},
221-
fd,
222-
indent = "\t" if app.config["DEBUG"] else None)
223-
224-
225158
# fieldName: (Required, Type, SubType)
226159
fields = {
227160
"action": (True, "str"),
@@ -312,23 +245,102 @@ def asyncFinishThread(server):
312245

313246
server["ping"] = serverUp(server["address"], server["port"])
314247
if not server["ping"]:
248+
app.logger.warning("Server %s:%d has no ping."
249+
% (server["address"], server["port"]))
315250
return
316251

317252
del server["action"]
318253

319-
with listLock:
320-
old = getServerAndIndex(server["ip"], server["port"])
321-
if old:
322-
serverList[old[0]] = server
323-
else:
324-
serverList.append(server)
254+
serverList.update(server)
255+
256+
257+
class ServerList:
258+
def __init__(self):
259+
self.list = []
260+
self.maxServers = 0
261+
self.maxClients = 0
262+
self.lock = RLock()
263+
self.load()
264+
self.purgeOld()
265+
266+
def getWithIndex(self, ip, port):
267+
with self.lock:
268+
for i, server in enumerate(self.list):
269+
if server["ip"] == ip and server["port"] == port:
270+
return (i, server)
271+
return (None, None)
272+
273+
def get(self, ip, port):
274+
i, server = self.getWithIndex(ip, port)
275+
return server
276+
277+
def removeServer(self, server):
278+
with lock:
279+
try:
280+
self.list.remove(server)
281+
except:
282+
pass
283+
284+
def sort(self):
285+
with self.lock:
286+
self.list.sort(key=itemgetter("clients", "start"), reverse=True)
287+
288+
def purgeOld(self):
289+
with self.lock:
290+
for server in self.list:
291+
if server["update_time"] < time.time() - app.config["PURGE_TIME"]:
292+
self.list.remove(server)
293+
self.save()
294+
295+
def load(self):
296+
try:
297+
with open(os.path.join("static", app.config["FILENAME"]), "r") as fd:
298+
data = json.load(fd)
299+
except FileNotFoundError:
300+
return
325301

326-
sortList()
327-
saveList()
302+
if not data:
303+
return
328304

305+
with self.lock:
306+
self.list = data["list"]
307+
self.maxServers = data["total_max"]["servers"]
308+
self.maxClients = data["total_max"]["clients"]
309+
310+
def save(self):
311+
with self.lock:
312+
servers = len(self.list)
313+
clients = 0
314+
for server in self.list:
315+
clients += server["clients"]
316+
317+
self.maxServers = max(servers, self.maxServers)
318+
self.maxClients = max(clients, self.maxClients)
319+
320+
with open(os.path.join("static", app.config["FILENAME"]), "w") as fd:
321+
json.dump({
322+
"total": {"servers": servers, "clients": clients},
323+
"total_max": {"servers": self.maxServers, "clients": self.maxClients},
324+
"list": self.list
325+
},
326+
fd,
327+
indent = "\t" if app.config["DEBUG"] else None
328+
)
329+
330+
def update(self, server):
331+
with self.lock:
332+
i, old = self.getWithIndex(server["ip"], server["port"])
333+
if i is not None:
334+
self.list[i] = server
335+
else:
336+
self.list.append(server)
337+
338+
self.sort()
339+
self.save()
340+
341+
serverList = ServerList()
329342

330-
loadList()
331-
purgeOld()
332343

333344
if __name__ == "__main__":
334345
app.run(host = app.config["HOST"], port = app.config["PORT"])
346+

0 commit comments

Comments
 (0)
Please sign in to comment.