|
@@ -25,6 +25,7 @@ from isc.datasrc import *
|
|
|
import isc.util.process
|
|
|
import isc.log
|
|
|
from isc.log_messages.loadzone_messages import *
|
|
|
+from datetime import timedelta
|
|
|
|
|
|
isc.util.process.rename()
|
|
|
|
|
@@ -113,6 +114,8 @@ class LoadZoneRunner:
|
|
|
self._log_severity = 'INFO'
|
|
|
self._log_debuglevel = 0
|
|
|
self._report_interval = LOAD_INTERVAL_DEFAULT
|
|
|
+ self._start_time = None
|
|
|
+ self._get_time = time.time
|
|
|
|
|
|
self._config_log()
|
|
|
|
|
@@ -200,16 +203,37 @@ class LoadZoneRunner:
|
|
|
logger.info(LOADZONE_SQLITE3_USING_DEFAULT_CONFIG, default_db_file)
|
|
|
return '{"database_file": "' + default_db_file + '"}'
|
|
|
|
|
|
- def _report_progress(self, loaded_rrs):
|
|
|
+ def _report_progress(self, loaded_rrs, progress, dump=True):
|
|
|
'''Dump the current progress report to stdout.
|
|
|
|
|
|
This is essentially private, but defined as "protected" for tests.
|
|
|
+ Normally dump is True, but tests will set it False to get the
|
|
|
+ text to be reported. Tests may also fake self._get_time (which
|
|
|
+ is set to time.time() by default) and self._start_time for control
|
|
|
+ time related conditions.
|
|
|
|
|
|
'''
|
|
|
- elapsed = time.time() - self.__start_time
|
|
|
- sys.stdout.write("\r" + (80 * " "))
|
|
|
- sys.stdout.write("\r%d RRs loaded in %.2f seconds" %
|
|
|
- (loaded_rrs, elapsed))
|
|
|
+ elapsed = self._get_time() - self._start_time
|
|
|
+ speed = int(loaded_rrs / elapsed) if elapsed > 0 else 0
|
|
|
+ etc = None # calculate estimated time of completion
|
|
|
+ if progress != ZoneLoader.PROGRESS_UNKNOWN:
|
|
|
+ etc = (1 - progress) * (elapsed / progress)
|
|
|
+
|
|
|
+ # Build report text
|
|
|
+ report_txt = '\r%d RRs' % loaded_rrs
|
|
|
+ if progress != ZoneLoader.PROGRESS_UNKNOWN:
|
|
|
+ report_txt += ' (%.1f%%)' % (progress * 100)
|
|
|
+ report_txt += ' in %s, %d RRs/sec' % \
|
|
|
+ (str(timedelta(seconds=int(elapsed))), speed)
|
|
|
+ if etc is not None:
|
|
|
+ report_txt += ', %s ETC' % str(timedelta(seconds=int(etc)))
|
|
|
+
|
|
|
+ # Dump or return the report text.
|
|
|
+ if dump:
|
|
|
+ sys.stdout.write("\r" + (80 * " "))
|
|
|
+ sys.stdout.write(report_txt)
|
|
|
+ else:
|
|
|
+ return report_txt
|
|
|
|
|
|
def _do_load(self):
|
|
|
'''Main part of the load logic.
|
|
@@ -230,7 +254,7 @@ class LoadZoneRunner:
|
|
|
self._zone_class)
|
|
|
loader = ZoneLoader(datasrc_client, self._zone_name,
|
|
|
self._zone_file)
|
|
|
- self.__start_time = time.time()
|
|
|
+ self._start_time = time.time()
|
|
|
if self._report_interval > 0:
|
|
|
limit = self._report_interval
|
|
|
else:
|
|
@@ -241,7 +265,8 @@ class LoadZoneRunner:
|
|
|
not loader.load_incremental(limit)):
|
|
|
self._loaded_rrs += self._report_interval
|
|
|
if self._report_interval > 0:
|
|
|
- self._report_progress(self._loaded_rrs)
|
|
|
+ self._report_progress(self._loaded_rrs,
|
|
|
+ loader.get_progress())
|
|
|
if self.__interrupted:
|
|
|
raise LoadFailure('loading interrupted by signal')
|
|
|
|
|
@@ -275,7 +300,7 @@ class LoadZoneRunner:
|
|
|
self._set_signal_handlers()
|
|
|
self._parse_args()
|
|
|
self._do_load()
|
|
|
- total_elapsed_txt = "%.2f" % (time.time() - self.__start_time)
|
|
|
+ total_elapsed_txt = "%.2f" % (time.time() - self._start_time)
|
|
|
logger.info(LOADZONE_DONE, self._loaded_rrs, self._zone_name,
|
|
|
self._zone_class, total_elapsed_txt)
|
|
|
return 0
|