comparison orpg/networking/meta_server_lib.py @ 71:449a8900f9ac ornery-dev

Code refining almost completed, for this round. Some included files are still in need of some clean up, but this is test worthy.
author sirebral
date Thu, 20 Aug 2009 03:00:39 -0500
parents c54768cffbd4
children d1aff41c031b
comparison
equal deleted inserted replaced
70:52a5fa913008 71:449a8900f9ac
32 META_DEBUG = 0 32 META_DEBUG = 0
33 33
34 __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $" 34 __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $"
35 35
36 from orpg.orpg_version import PROTOCOL_VERSION 36 from orpg.orpg_version import PROTOCOL_VERSION
37 from orpg.orpgCore import * 37 from orpg.orpgCore import component
38 from orpg.tools.validate import validate
38 from orpg.dirpath import dir_struct 39 from orpg.dirpath import dir_struct
39 import urllib 40 import urllib
40 import orpg.minidom 41 import orpg.minidom
41 from threading import * 42 from threading import *
42 import time 43 import time
66 file.close() 67 file.close()
67 68
68 # Remove any leading or trailing data. This can happen on some satellite connections 69 # Remove any leading or trailing data. This can happen on some satellite connections
69 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE) 70 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE)
70 mo = p.search(data) 71 mo = p.search(data)
71 if mo: 72 if mo: data = mo.group(0)
72 data = mo.group(0)
73 73
74 if META_DEBUG: 74 if META_DEBUG:
75 print 75 print
76 print "Got this string from the Meta at " + path + ":" 76 print "Got this string from the Meta at " + path + ":"
77 print "===============================================" 77 print "==============================================="
82 xml_dom = xml.parseXml(data) 82 xml_dom = xml.parseXml(data)
83 xml_dom = xml_dom._get_documentElement() 83 xml_dom = xml_dom._get_documentElement()
84 return xml_dom 84 return xml_dom
85 85
86 def post_server_data( name, realHostName=None): 86 def post_server_data( name, realHostName=None):
87 # build POST data
88 ## data = urllib.urlencode( {"server_data[name]":name,
89 ## "server_data[version]":PROTOCOL_VERSION,
90 ## "act":"new"} )
91 ##
92 if realHostName: 87 if realHostName:
93 data = urllib.urlencode( {"server_data[name]":name, 88 data = urllib.urlencode( {"server_data[name]":name,
94 "server_data[version]":PROTOCOL_VERSION, 89 "server_data[version]":PROTOCOL_VERSION,
95 "act":"new", 90 "act":"new",
96 "REMOTE_ADDR": realHostName } ) 91 "REMOTE_ADDR": realHostName } )
99 #print "Letting meta server decide the hostname to list..." 94 #print "Letting meta server decide the hostname to list..."
100 data = urllib.urlencode( {"server_data[name]":name, 95 data = urllib.urlencode( {"server_data[name]":name,
101 "server_data[version]":PROTOCOL_VERSION, 96 "server_data[version]":PROTOCOL_VERSION,
102 "act":"new"} ) 97 "act":"new"} )
103 98
104 xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php") 99 #xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")#Sourceforge still?
100 path = component.get('settings').get_setting('MetaServerBaseURL') #getMetaServerBaseURL()
101 xml_dom = get_server_dom(data, path)
105 ret_val = int( xml_dom.getAttribute( "id" ) ) 102 ret_val = int( xml_dom.getAttribute( "id" ) )
106 return ret_val 103 return ret_val
107 104
108 def post_failed_connection(id,meta=None,address=None,port=None): 105 def post_failed_connection(id,meta=None,address=None,port=None):
109 # For now, turning this off. This needs to be re-vamped for 106 # For now, turning this off. This needs to be re-vamped for
110 # handling multiple Metas. 107 # handling multiple Metas.
111 return 0 108 return 0
112 # data = urllib.urlencode({"id":id,"act":"failed"}); 109 #data = urllib.urlencode({"id":id,"act":"failed"});
113 # xml_dom = get_server_dom(data) 110 #xml_dom = get_server_dom(data)
114 # ret_val = int(xml_dom.getAttribute("return")) 111 #ret_val = int(xml_dom.getAttribute("return"))
115 # return ret_val 112 #return ret_val
116 113
117 def remove_server(id): 114 def remove_server(id):
118 data = urllib.urlencode({"id":id,"act":"del"}); 115 data = urllib.urlencode({"id":id,"act":"del"});
119 xml_dom = get_server_dom(data) 116 xml_dom = get_server_dom(data)
120 ret_val = int(xml_dom.getAttribute("return")) 117 ret_val = int(xml_dom.getAttribute("return"))
123 120
124 def byStartAttribute(first,second): 121 def byStartAttribute(first,second):
125 # This function is used to easily sort a list of nodes 122 # This function is used to easily sort a list of nodes
126 # by their start time 123 # by their start time
127 124
128 if first.hasAttribute("start"): 125 if first.hasAttribute("start"): first_start = int(first.getAttribute("start"))
129 first_start = int(first.getAttribute("start")) 126 else: first_start = 0
130 else: 127
131 first_start = 0 128 if second.hasAttribute("start"): second_start = int(second.getAttribute("start"))
132 129 else: second_start = 0
133 if second.hasAttribute("start"):
134 second_start = int(second.getAttribute("start"))
135 else:
136 second_start = 0
137 130
138 # Return the result of the cmp function on the two strings 131 # Return the result of the cmp function on the two strings
139 return cmp(first_start,second_start) 132 return cmp(first_start,second_start)
140 133
141 def byNameAttribute(first,second): 134 def byNameAttribute(first,second):
142 # This function is used to easily sort a list of nodes 135 # This function is used to easily sort a list of nodes
143 # by their name attribute 136 # by their name attribute
144 137
145 # Ensure there is something to sort with for each 138 # Ensure there is something to sort with for each
146 139
147 if first.hasAttribute("name"): 140 if first.hasAttribute("name"): first_name = str(first.getAttribute("name")).lower()
148 first_name = str(first.getAttribute("name")).lower() 141 else: first_name = ""
149 else: 142
150 first_name = "" 143 if second.hasAttribute("name"): second_name = str(second.getAttribute("name")).lower()
151 144 else: second_name = ""
152 if second.hasAttribute("name"):
153 second_name = str(second.getAttribute("name")).lower()
154 else:
155 second_name = ""
156 145
157 # Return the result of the cmp function on the two strings 146 # Return the result of the cmp function on the two strings
158
159 return cmp(first_name,second_name) 147 return cmp(first_name,second_name)
160 148
161 149
162 def get_server_list(versions = None,sort_by="start"): 150 def get_server_list(versions = None,sort_by="start"):
163 data = urllib.urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) 151 data = urllib.urlencode({"version":PROTOCOL_VERSION,"ports":"%"})
169 157
170 return_hash = {} # this will end up with an amalgamated list of servers 158 return_hash = {} # this will end up with an amalgamated list of servers
171 159
172 for meta in all_metas: # check all of the metas 160 for meta in all_metas: # check all of the metas
173 161
174 # get the server's xml from the current meta 162 #get the server's xml from the current meta
175 bad_meta = 0 163 bad_meta = 0
176 #print "Getting server list from " + meta + "..." 164 #print "Getting server list from " + meta + "..."
177 try: 165 try: xml_dom = get_server_dom(data=data,path=meta)
178 xml_dom = get_server_dom(data=data,path=meta)
179 except: 166 except:
180 #print "Trouble getting servers from " + meta + "..." 167 #print "Trouble getting servers from " + meta + "..."
181 bad_meta = 1 168 bad_meta = 1
182 169
183 if bad_meta: 170 if bad_meta:
222 return_list = return_hash.values() 209 return_list = return_hash.values()
223 210
224 # sort them by their name attribute. Uses byNameAttribute() 211 # sort them by their name attribute. Uses byNameAttribute()
225 # defined above as a comparison function 212 # defined above as a comparison function
226 213
227 if sort_by == "start": 214 if sort_by == "start": return_list.sort(byStartAttribute)
228 return_list.sort(byStartAttribute) 215 elif sort_by == "name": return_list.sort(byNameAttribute)
229 elif sort_by == "name":
230 return_list.sort(byNameAttribute)
231 216
232 # Add each node to the DOM 217 # Add each node to the DOM
233 for n in return_list: 218 for n in return_list: return_dom.appendChild(n)
234 return_dom.appendChild(n)
235 return return_dom 219 return return_dom
236 220
237 ## List Format: 221 ## List Format:
238 ## <servers> 222 ## <servers>
239 ## <server address=? id=? name=? failed_count=? > 223 ## <server address=? id=? name=? failed_count=? >
267 def getRawMetaList(): 251 def getRawMetaList():
268 try: 252 try:
269 try: 253 try:
270 metacache_lock.acquire() 254 metacache_lock.acquire()
271 # Read in the metas 255 # Read in the metas
272 component.get('validate').config_file("metaservers.cache","metaservers.cache") 256 validate.config_file("metaservers.cache","metaservers.cache")
273 ini = open(dir_struct["user"]+"metaservers.cache","r") 257 ini = open(dir_struct["user"]+"metaservers.cache","r")
274 metas = ini.readlines() 258 metas = ini.readlines()
275 ini.close() 259 ini.close()
276 return metas 260 return metas
277 finally: 261 finally:
280 if META_DEBUG: traceback.print_exc() 264 if META_DEBUG: traceback.print_exc()
281 print "Meta Server Lib: getRawMetaList(): " + str(e) 265 print "Meta Server Lib: getRawMetaList(): " + str(e)
282 return [] 266 return []
283 267
284 def getMetaServers(versions = None, pick_random=0): 268 def getMetaServers(versions = None, pick_random=0):
285 # get meta server URLs as a list 269 """
286 270 get meta server URLs as a list
287 # versions is a list of acceptable version numbers. 271
288 # A False truth value will use getMetaServerBaseURL() 272 versions is a list of acceptable version numbers.
289 273 A False truth value will use getMetaServerBaseURL()
290 # set a default if we have weird reading problems 274
291 # default_url = "http://www.openrpg.com/openrpg_servers.php" 275 set a default if we have weird reading problems
276 default_url = "http://www.openrpg.com/openrpg_servers.php"
277 """
292 278
293 meta_names = [] 279 meta_names = []
294 280
295 if(versions): # If versions are supplied, then look in metaservers.conf 281 if(versions): # If versions are supplied, then look in metaservers.conf
296 try: 282 try:
297 # read in the metas from file 283 """
298 # format of file is one meta entry per line 284 read in the metas from file
299 # each entry will be the meta url, followed by one or more version numbers that it 285 format of file is one meta entry per line
300 # handle. Generally, this will be either a 1 for the original Meta format, or 286 each entry will be the meta url, followed by one or more version numbers that it
301 # 2 for the new one. 287 handle. Generally, this will be either a 1 for the original Meta format, or
288 2 for the new one.
289 """
302 290
303 # Read in the metas 291 # Read in the metas
304 metas = getRawMetaList() 292 metas = getRawMetaList()
305 #print str(metas) 293 #print str(metas)
306 294
309 for meta in metas: 297 for meta in metas:
310 298
311 # split the line on whitespace 299 # split the line on whitespace
312 # obviously, your meta servers urls shouldn't contain whitespace. duh. 300 # obviously, your meta servers urls shouldn't contain whitespace. duh.
313 words = meta.split() 301 words = meta.split()
314
315 success = 0 # init success flag for version check 302 success = 0 # init success flag for version check
316
317 for version in versions: # run through each allowed version from caller 303 for version in versions: # run through each allowed version from caller
318 if version in words[1:]: # if the allowed version token was found 304 if version in words[1:]: # if the allowed version token was found
319 success += 1 # then increment the success indicator 305 success += 1 # then increment the success indicator
320
321 if success: # if the meta entry is acceptable to the caller 306 if success: # if the meta entry is acceptable to the caller
322 meta_names.append(words[0]) # add the entry 307 meta_names.append(words[0]) # add the entry
323 if META_DEBUG: print "adding metaserver " + meta 308 if META_DEBUG: print "adding metaserver " + meta
324 309
325 # at this point, we should have at least one name from the cache. If not ... 310 # at this point, we should have at least one name from the cache. If not ...
326 if not meta_names: 311 if not meta_names:
327 default_meta = getMetaServerBaseURL() # grab the meta from ini.xml 312 default_meta = getMetaServerBaseURL() # grab the meta from ini.xml
328 meta_names.append(default_meta) # add it to the return list 313 meta_names.append(default_meta) # add it to the return list
329 # print "Warning!!\nNo valid metaservers cached." 314 # print "Warning!!\nNo valid metaservers cached."
330 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" 315 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n"
331 # if we have more than one and want a random one 316 # if we have more than one and want a random one
332 elif pick_random: 317 elif pick_random:
333 if META_DEBUG: print "choosing random meta from: " + str(meta_names) 318 if META_DEBUG: print "choosing random meta from: " + str(meta_names)
334 i = int(random.uniform(0,len(meta_names))) 319 i = int(random.uniform(0,len(meta_names)))
335 #meta = meta_names[i] 320 #meta = meta_names[i]
362 node_list = tree.getElementsByTagName("MetaServerBaseURL") 347 node_list = tree.getElementsByTagName("MetaServerBaseURL")
363 if node_list: 348 if node_list:
364 url = node_list[0].getAttribute("value") 349 url = node_list[0].getAttribute("value")
365 350
366 # allow tree to be collected 351 # allow tree to be collected
367 try: 352 try: tree.unlink()
368 tree.unlink() 353 except: pass
369 except:
370 pass
371 354
372 except Exception,e: 355 except Exception,e:
373 print e 356 print e
374 # print "using meta server URI: " + url 357 #print "using meta server URI: " + url
375 return url 358 return url
376 359
377 ####################################################################################### 360 """
378 # Beginning of Class registerThread 361 Beginning of Class registerThread
379 # 362
380 # A Class to Manage Registration with the Meta2 363 A Class to Manage Registration with the Meta2
381 # Create an instance and call it's start() method 364 Create an instance and call it's start() method
382 # if you want to be (and stay) registered. This class 365 if you want to be (and stay) registered. This class
383 # will take care of registering and re-registering as 366 will take care of registering and re-registering as
384 # often as necessary to stay in the Meta list. 367 often as necessary to stay in the Meta list.
385 # 368
386 # You may call register() yourself if you wish to change your 369 You may call register() yourself if you wish to change your
387 # server's name. It will immediately update the Meta. There 370 server's name. It will immediately update the Meta. There
388 # is no need to unregister first. 371 is no need to unregister first.
389 # 372
390 # Call unregister() when you no longer want to be registered. 373 Call unregister() when you no longer want to be registered.
391 # This will result in the registerThread dying after 374 This will result in the registerThread dying after
392 # attempting to immediately remove itself from the Meta. 375 attempting to immediately remove itself from the Meta.
393 # 376
394 # If you need to become registered again after that, you 377 If you need to become registered again after that, you
395 # must create a new instance of class registerThread. Don't 378 must create a new instance of class registerThread. Don't
396 # just try to call register() on the old, dead thread class. 379 just try to call register() on the old, dead thread class.
397 380 """
398 381
399 class registerThread(Thread): 382 class registerThread(Thread):
400 # Originally, I wrote this as a sub-class of wxThread, but 383 """
401 # A) I couldn't get it to import right 384 Originally, I wrote this as a sub-class of wxThread, but
402 # B) I realized that I want this to be used in a server, 385 A) I couldn't get it to import right
403 # which I don't want needing wxWindows to run! 386 B) I realized that I want this to be used in a server,
404 # 387 which I don't want needing wxWindows to run!
405 # Because of this fact, there are some methods from wxThread 388
406 # that I implemented to minimize changes to the code I had 389 Because of this fact, there are some methods from wxThread
407 # just written, i.e. TestDeleteStatus() and Delete() 390 that I implemented to minimize changes to the code I had
391 just written, i.e. TestDeleteStatus() and Delete()
392 """
408 393
409 def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None): 394 def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None):
410 395
411 Thread.__init__(self,name="registerThread") 396 Thread.__init__(self,name="registerThread")
412 self.rlock = RLock() # Re-entrant lock used to make this class thread safe 397 self.rlock = RLock() # Re-entrant lock used to make this class thread safe
424 # indicates a new registration. 409 # indicates a new registration.
425 self.interval = 0 # interval returned from Meta. Is how often to 410 self.interval = 0 # interval returned from Meta. Is how often to
426 # re-register, in minutes. 411 # re-register, in minutes.
427 self.destroy = 0 # Used to flag that this thread should die 412 self.destroy = 0 # Used to flag that this thread should die
428 self.port = str(port) 413 self.port = str(port)
429 self.register_callback = register_callback # set a method to call to report result of register 414 self.register_callback = register_callback # set a method to call to report result of register
430 # This thread will communicate with one and only one 415 """
431 # Meta. If the Meta in ini.xml is changed after 416 This thread will communicate with one and only one
432 # instantiation, then this instance must be 417 Meta. If the Meta in ini.xml is changed after
433 # unregistered and a new instance instantiated. 418 instantiation, then this instance must be
434 # 419 unregistered and a new instance instantiated.
435 # Also, if MetaPath is specified, then use that. Makes 420
436 # it easier to have multiple registerThreads going to keep the server registered 421 Also, if MetaPath is specified, then use that. Makes
437 # on multiple (compatible) Metas. 422 it easier to have multiple registerThreads going to keep the server registered
423 on multiple (compatible) Metas.
424 """
438 425
439 if MetaPath == None: 426 if MetaPath == None:
440 self.path = getMetaServerBaseURL() # Do this if no Meta specified 427 self.path = getMetaServerBaseURL() # Do this if no Meta specified
441 else: 428 else:
442 self.path = MetaPath 429 self.path = MetaPath
457 self.die_event.set() 444 self.die_event.set()
458 finally: 445 finally:
459 self.rlock.release() 446 self.rlock.release()
460 447
461 def run(self): 448 def run(self):
462 # This method gets called by Thread implementation 449 """
463 # when self.start() is called to begin the thread's 450 This method gets called by Thread implementation
464 # execution 451 when self.start() is called to begin the thread's
465 # 452 execution
466 # We will basically enter a loop that continually 453
467 # re-registers this server and sleeps Interval 454 We will basically enter a loop that continually
468 # minutes until the thread is ordered to die in place 455 re-registers this server and sleeps Interval
456 minutes until the thread is ordered to die in place
457 """
469 while(not self.TestDeleteStatus()): # Loop while until told to die 458 while(not self.TestDeleteStatus()): # Loop while until told to die
470 # Otherwise, call thread safe register(). 459 # Otherwise, call thread safe register().
471 self.register(self.name, self.realHostName, self.num_users) 460 self.register(self.name, self.realHostName, self.num_users)
472 if META_DEBUG: print "Sent Registration Data" 461 if META_DEBUG: print "Sent Registration Data"
473
474 # register() will end up setting the state variables 462 # register() will end up setting the state variables
475 # for us, including self.interval. 463 # for us, including self.interval.
476 try: 464 try:
477 self.rlock.acquire() # Serialize access to this state information 465 self.rlock.acquire() # Serialize access to this state information
478 466
491 # If we get past the while loop, it's because we've been asked to die, 479 # If we get past the while loop, it's because we've been asked to die,
492 # so just let run() end. Once this occurs, the thread is dead and 480 # so just let run() end. Once this occurs, the thread is dead and
493 # calls to Thread.isAlive() return False. 481 # calls to Thread.isAlive() return False.
494 482
495 def unregister(self): 483 def unregister(self):
496 # This method can (I hope) be called from both within the thread 484 """
497 # and from other threads. It will attempt to unregister this 485 This method can (I hope) be called from both within the thread
498 # server from the Meta database 486 and from other threads. It will attempt to unregister this
499 # When this is either accomplished or has been tried hard enough 487 server from the Meta database
500 # (after which it just makes sense to let the Meta remove the 488 When this is either accomplished or has been tried hard enough
501 # entry itself when we don't re-register using this id), 489 (after which it just makes sense to let the Meta remove the
502 # this method will either cause the thread to immediately die 490 entry itself when we don't re-register using this id),
503 # (if called from this thread's context) or set the Destroy flag 491 this method will either cause the thread to immediately die
504 # (if called from the main thread), a positive test for which will cause 492 (if called from this thread's context) or set the Destroy flag
505 # the code in Entry() to exit() when the thread wakes up and 493 (if called from the main thread), a positive test for which will cause
506 # checks TestDeleteStatus(). 494 the code in Entry() to exit() when the thread wakes up and
507 # lock the critical section. The unlock will 495 checks TestDeleteStatus().
508 # automatically occur at the end of the function in the finally clause 496 lock the critical section. The unlock will
497 automatically occur at the end of the function in the finally clause
498 """
509 try: 499 try:
510 self.rlock.acquire() 500 self.rlock.acquire()
511 if not self.isAlive(): # check to see if this thread is dead 501 if not self.isAlive(): # check to see if this thread is dead
512 return 1 # If so, return an error result 502 return 1 # If so, return an error result
513 # Do the actual unregistering here 503 # Do the actual unregistering here
526 # No special handling is required. If the de-registration worked we're done. If 516 # No special handling is required. If the de-registration worked we're done. If
527 # not, then it's because we've already been removed or have a bad cookie. Either 517 # not, then it's because we've already been removed or have a bad cookie. Either
528 # way, we can't do anything else, so die. 518 # way, we can't do anything else, so die.
529 self.Delete() # This will cause the registerThread to die in register() 519 self.Delete() # This will cause the registerThread to die in register()
530 # prep xml_dom for garbage collection 520 # prep xml_dom for garbage collection
531 try: 521 try: xml_dom.unlink()
532 xml_dom.unlink() 522 except: pass
533 except:
534 pass
535 return 0 523 return 0
536 finally: 524 finally: self.rlock.release()
537 self.rlock.release()
538 525
539 def register(self, name=None, realHostName=None, num_users=None): 526 def register(self, name=None, realHostName=None, num_users=None):
540 # Designed to handle the registration, both new and 527 """
541 # repeated. 528 Designed to handle the registration, both new and
542 # 529 repeated.
543 # It is intended to be called once every interval 530
544 # (or interval - delta) minutes. 531 It is intended to be called once every interval
545 532 (or interval - delta) minutes.
546 # lock the critical section. The unlock will 533
547 # automatically occur at the end of the function in the finally clause 534 lock the critical section. The unlock will
535 automatically occur at the end of the function in the finally clause
536 """
548 try: 537 try:
549 self.rlock.acquire() 538 self.rlock.acquire()
550 if not self.isAlive(): # check to see if this thread is dead 539 if not self.isAlive(): # check to see if this thread is dead
551 return 1 # If so, return an error result 540 return 1 # If so, return an error result
552 541
553 # Set the server's attibutes, if specified. 542 # Set the server's attibutes, if specified.
554 if name: 543 if name: self.name = name
555 self.name = name 544 if num_users != None: self.num_users = num_users
556 if num_users != None: 545 if realHostName: self.realHostName = realHostName
557 self.num_users = num_users
558 if realHostName:
559 self.realHostName = realHostName
560 # build POST data 546 # build POST data
561 if self.realHostName: 547 if self.realHostName:
562 data = urllib.urlencode( {"server_data[id]":self.id, 548 data = urllib.urlencode( {"server_data[id]":self.id,
563 "server_data[cookie]":self.cookie, 549 "server_data[cookie]":self.cookie,
564 "server_data[name]":self.name, 550 "server_data[name]":self.name,
581 except: 567 except:
582 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." 568 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..."
583 if META_DEBUG: print data 569 if META_DEBUG: print data
584 if META_DEBUG: print 570 if META_DEBUG: print
585 self.interval = 0 571 self.interval = 0
586 # If we are in the registerThread thread, then setting interval to 0 572 """
587 # will end up causing a retry in about 6 seconds (see self.run()) 573 If we are in the registerThread thread, then setting interval to 0
588 # If we are in the main thread, then setting interval to 0 will do one 574 will end up causing a retry in about 6 seconds (see self.run())
589 # of two things: 575 If we are in the main thread, then setting interval to 0 will do one
590 # 1) Do the same as if we were in the registerThread 576 of two things:
591 # 2) Cause the next, normally scheduled register() call to use the values 577 1) Do the same as if we were in the registerThread
592 # provided in this call. 578 2) Cause the next, normally scheduled register() call to use the values
593 # 579 provided in this call.
594 # Which case occurs depends on where the registerThread thread is when 580
595 # the main thread calls register(). 581 Which case occurs depends on where the registerThread thread is when
582 the main thread calls register().
583 """
596 return 0 # indicates that it was okay to call, not that no errors occurred 584 return 0 # indicates that it was okay to call, not that no errors occurred
585
597 # If there is a DOM returned .... 586 # If there is a DOM returned ....
598 if xml_dom: 587 if xml_dom:
599 # If there's an error, echo it to the console 588 # If there's an error, echo it to the console
600 if xml_dom.hasAttribute("errmsg"): 589 if xml_dom.hasAttribute("errmsg"):
601 print "Error durring registration: " + xml_dom.getAttribute("errmsg") 590 print "Error durring registration: " + xml_dom.getAttribute("errmsg")
602 if META_DEBUG: print data 591 if META_DEBUG: print data
603 if META_DEBUG: print 592 if META_DEBUG: print
604 # No special handling is required. If the registration worked, id, cookie, and interval 593 """
605 # can be stored and used for the next time. 594 No special handling is required. If the registration worked, id, cookie, and interval
606 # If an error occurred, then the Meta will delete us and we need to re-register as 595 can be stored and used for the next time.
607 # a new server. The way to indicate this is with a "0" id and "0" cookie sent to 596 If an error occurred, then the Meta will delete us and we need to re-register as
608 # the server during the next registration. Since that's what the server returns to 597 a new server. The way to indicate this is with a "0" id and "0" cookie sent to
609 # us on an error anyway, we just store them and the next registration will 598 the server during the next registration. Since that's what the server returns to
610 # automatically be set up as a new one. 599 us on an error anyway, we just store them and the next registration will
611 # 600 automatically be set up as a new one.
612 # Unless the server calls register() itself in the meantime. Of course, that's okay 601
613 # too, because a success on THAT register() call will set up the next one to use 602 Unless the server calls register() itself in the meantime. Of course, that's okay
614 # the issued id and cookie. 603 too, because a success on THAT register() call will set up the next one to use
615 # 604 the issued id and cookie.
616 # The interval is stored unconditionally for similar reasons. If there's an error, 605
617 # the interval will be less than 1, and the main thread's while loop will reset it 606 The interval is stored unconditionally for similar reasons. If there's an error,
618 # to 6 seconds for the next retry. 607 the interval will be less than 1, and the main thread's while loop will reset it
619 # Is it wrong to have a method where there's more comments than code? :) 608 to 6 seconds for the next retry.
609 Is it wrong to have a method where there's more comments than code? :)
610 """
620 try: 611 try:
621 self.interval = int(xml_dom.getAttribute("interval")) 612 self.interval = int(xml_dom.getAttribute("interval"))
622 self.id = xml_dom.getAttribute("id") 613 self.id = xml_dom.getAttribute("id")
623 self.cookie = xml_dom.getAttribute("cookie") 614 self.cookie = xml_dom.getAttribute("cookie")
624 if not xml_dom.hasAttribute("errmsg"): 615 if not xml_dom.hasAttribute("errmsg"):