[entropy.client.interfaces/equo] add "equo repo mirrorsort" tool

There is a new method inside Entropy Client class, called
"reorder_mirrors". The aim is sorting repository mirrors automatically
basing on their response time and download speed of random data.
This commit is contained in:
Fabio Erculiani
2010-06-30 15:23:03 +02:00
parent 4a79f6e9cd
commit 9dddfabb4a
5 changed files with 106 additions and 3 deletions

View File

@@ -71,6 +71,7 @@ help_opts = [
(2, 'disable', 1, _('disable given repository')),
(2, 'add <string>', 1, _('add repository (pass repository string)')),
(2, 'remove <id>', 1, _('remove repository')),
(2, 'mirrorsort <id>', 0, _('reorder mirrors basing on response time')),
(1, 'notice [repos]', 1, _('repository notice board reader')),
(1, 'status', 2, _('show respositories status')),
None,

View File

@@ -83,6 +83,8 @@ def repositories(options):
rc = _add_repository(entropy_client, myopts)
elif repo_opt == "remove":
rc = _remove_repository(entropy_client, myopts)
elif repo_opt == "mirrorsort":
rc = _mirror_sort(entropy_client, myopts)
else:
rc = -10
@@ -201,6 +203,20 @@ def _disable_repositories(entropy_client, repos):
teal(repo), blue(_("repository disabled")),))
return 0
def _mirror_sort(entropy_client, repo_ids):
for repo_id in repo_ids:
try:
entropy_client.reorder_mirrors(repo_id, dry_run = etpUi['pretend'])
except KeyError:
print_warning("[%s] %s" % (
purple(repo_id), blue(_("repository not available")),))
continue
print_info("[%s] %s" % (
teal(repo_id), blue(_("mirrors sorted successfully")),))
return 0
def _show_repository_info(entropy_client, reponame):
repo_number = 0

View File

@@ -86,6 +86,10 @@ add repository (pass repository string)
remove repository
=item B<mirrorsort <id>>
reorder mirrors basing on response time
=back
=item B<notice [repos]>

View File

@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "EQUO 1"
.TH EQUO 1 "2010-05-22" "perl v5.10.1" "Entropy"
.TH EQUO 1 "2010-06-30" "perl v5.10.1" "Entropy"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -196,6 +196,9 @@ add repository (pass repository string)
.IP "\fBremove <id\fR>" 4
.IX Item "remove <id>"
remove repository
.IP "\fBmirrorsort <id\fR>" 4
.IX Item "mirrorsort <id>"
reorder mirrors basing on response time
.RE
.RS 4
.RE

View File

@@ -33,7 +33,8 @@ from entropy.cache import EntropyCacher
from entropy.client.interfaces.db import ClientEntropyRepositoryPlugin, \
InstalledPackagesRepository, AvailablePackagesRepository, GenericRepository
from entropy.client.mirrors import StatusInterface
from entropy.output import purple, bold, red, blue, darkgreen, darkred, brown
from entropy.output import purple, bold, red, blue, darkgreen, darkred, brown, \
teal
from entropy.db.exceptions import IntegrityError, OperationalError, \
DatabaseError
@@ -711,7 +712,8 @@ class RepositoryMixin:
return "%s%s%s_%sh%sm%ss" % (ts.year, ts.month, ts.day, ts.hour,
ts.minute, ts.second)
comp_dbname = "%s%s.%s.bz2" % (etpConst['dbbackupprefix'], dbname, get_ts(),)
comp_dbname = "%s%s.%s.bz2" % (etpConst['dbbackupprefix'],
dbname, get_ts(),)
comp_dbpath = os.path.join(backup_dir, comp_dbname)
if not silent:
mytxt = "%s: %s ..." % (
@@ -1307,6 +1309,83 @@ class MiscMixin:
return licenses
def reorder_mirrors(self, repository_id, dry_run = False):
"""
Reorder mirror list for given repository using ping statistics.
@param repository_id: repository identifier
@type repository_id: string
@keyword dry_run: do not actually change repository mirrors order
@type dry_run: bool
@raise KeyError: if repository_id is not available
@return: new repository metadata
@rtype: dict
"""
repo_data = None
avail_data = self._settings['repositories']['available']
excluded_data = self._settings['repositories']['excluded']
if repository_id in avail_data:
repo_data = avail_data[repository_id]
elif repository_id in excluded_data:
repo_data = excluded_data[repository_id]
if repo_data is None:
raise KeyError("repository_id not found")
pkg_mirrors = repo_data['plain_packages']
mirror_stats = {}
tmp_fd, tmp_path = tempfile.mkstemp()
os.close(tmp_fd)
retries = 3
for mirror in pkg_mirrors:
url_data = entropy.tools.spliturl(mirror)
mytxt = "%s: %s" % (
blue(_("Checking response time of")),
purple(url_data.hostname),
)
self.output(
mytxt,
importance = 1,
level = "info",
header = purple(" @@ "),
back = True
)
start_time = time.time()
for idx in range(retries):
fetcher = self.urlFetcher(mirror, tmp_path, resume = False,
show_speed = False)
fetcher.download()
end_time = time.time()
result_time = (end_time - start_time)/retries
mirror_stats[mirror] = result_time
mytxt = "%s: %s, %s" % (
blue(_("Mirror response time")),
purple(url_data.hostname),
teal(str(result_time)),
)
self.output(
mytxt,
importance = 1,
level = "info",
header = brown(" @@ ")
)
os.remove(tmp_path)
# calculate new order
new_pkg_mirrors = sorted(mirror_stats.keys(),
key = lambda x: mirror_stats[x], reverse = True)
repo_data['plain_packages'] = new_pkg_mirrors
self.remove_repository(repository_id)
self.add_repository(repo_data)
return repo_data
def set_branch(self, branch):
"""
Set new Entropy branch. This is NOT thread-safe.