import random
import socket
import time
+import tornado.gen
import tornado.httpclient
import tornado.netutil
import urllib.parse
return iter(mirrors)
+ @tornado.gen.coroutine
def check_all(self):
for mirror in self:
- mirror.check()
+ with self.db.transaction():
+ yield mirror.check()
def get_for_download(self, filename, country_code=None):
# Try to find a good mirror for this country first
def disabled(self):
return not self.enabled
+ @tornado.gen.coroutine
def check(self):
logging.info("Running check for mirror %s" % self.hostname)
self.db.execute("UPDATE mirrors SET address = %s WHERE id = %s",
self.address, self.id)
- self.check_timestamp()
- self.check_filelist()
+ success = yield self.check_timestamp()
- def check_state(self):
+ if success:
+ yield self.check_filelist()
+
+ def check_state(self, last_update):
logging.debug("Checking state of mirror %s" % self.id)
if not self.enabled:
now = datetime.datetime.utcnow()
- time_delta = now - self.last_update
+ time_delta = now - last_update
time_diff = time_delta.total_seconds()
time_down = self.settings.get_int("mirrors_time_down", 3*24*60*60)
self.set_state("UP")
+ @tornado.gen.coroutine
def check_timestamp(self):
http = tornado.httpclient.AsyncHTTPClient()
- http.fetch(self.url + ".timestamp",
- headers={ "Pragma" : "no-cache" },
- callback=self.__check_timestamp_response)
+ try:
+ response = yield http.fetch(self.url + ".timestamp",
+ headers={ "Pragma" : "no-cache" })
+ except tornado.httpclient.HTTPError as e:
+ logging.error("Error getting timestamp from %s: %s" % (self.hostname, e))
+ self.set_state("DOWN")
+ return False
- def __check_timestamp_response(self, response):
if response.error:
logging.debug("Error getting timestamp from %s" % self.hostname)
self.set_state("DOWN")
self.db.execute("UPDATE mirrors SET last_update = %s WHERE id = %s",
timestamp, self.id)
- # Reload changed settings
- self.data["timestamp"] = timestamp
-
- self.check_state()
+ # Update state
+ self.check_state(timestamp)
logging.info("Successfully updated timestamp from %s" % self.hostname)
+ return True
+ @tornado.gen.coroutine
def check_filelist(self):
# XXX need to remove data from disabled mirrors
if not self.enabled:
http = tornado.httpclient.AsyncHTTPClient()
- http.fetch(self.url + ".filelist",
- headers={ "Pragma" : "no-cache" },
- callback=self.__check_filelist_response)
+ try:
+ response = yield http.fetch(self.url + ".filelist",
+ headers={ "Pragma" : "no-cache" })
+ except tornado.httpclient.HTTPError as e:
+ logging.error("Error getting filelist from %s: %s" % (self.hostname, e))
+ self.set_state("DOWN")
+ return
- def __check_filelist_response(self, response):
if response.error:
- logging.debug("Error getting timestamp from %s" % self.hostname)
+ logging.debug("Error getting filelist from %s" % self.hostname)
return
- files = self.filelist
+ # Drop the old filelist
+ self.db.execute("DELETE FROM mirror_files WHERE mirror = %s", self.id)
+ # Add them all again
for file in response.body.splitlines():
- file = os.path.join(self.prefix, file)
-
- if file in files:
- files.remove(file)
- continue
-
- self.db.execute("INSERT INTO mirror_files(mirror, filename) VALUES(%s, %s)",
- self.id, file)
+ file = os.path.join(self.prefix, file.decode())
- for file in files:
- self.db.execute("DELETE FROM mirror_files WHERE mirror=%s AND filename=%s",
- self.id, file)
+ self.db.execute("INSERT INTO mirror_files(mirror, filename) \
+ VALUES(%s, %s)", self.id, file)
logging.info("Successfully updated mirror filelist from %s" % self.hostname)