Пример #1
0
    def __init__(self, context):
        super().__init__()
        self.context = context

        self.logger = logging.getLogger(utils.logger_str(__class__) \
                        + " " + context)
        # self.logger.setLevel(logging.INFO)
        self.config = config.Config.instance()
        self.copies = int(self.config.get(self.context, "copies", 2))
        self.path = config.path_for(self.config.get(self.context, "source"))
        self.scanner = scanner.Scanner(self.context, self.path)

        lazy_write = utils.str_to_duration(
            self.config.get(context, "LAZY WRITE", 5))
        # TODO: support expiration
        self.rescan = utils.str_to_duration(
            self.config.get(self.context, "rescan"))
        self.clients = persistent_dict.PersistentDict(
            f"/tmp/cb.s{context}.json.bz2",
            lazy_write=lazy_write,
            cls=lock.Lock,
            expiry=self.rescan)
        self.drains = elapsed.ExpiringDict(300)  # NOT persistent!
        self.locks = locker.Locker(5)
        # TODO: timers should relate to a configurable cycle time
        self.bailout = False
        self.stats = {'claims': 0, 'drops': 0}
        self.handling = False
Пример #2
0
 def test_durations(self):
     self.assertEquals(utils.str_to_duration("42"), 42)
     self.assertEquals(utils.str_to_duration("60m"), 60*60)
     self.assertEquals(utils.str_to_duration("27h5m"), 27*3600+5*60)
     self.assertEquals(utils.str_to_duration("2d5m8"), 2*24*3600+5*60+8)
     self.assertEquals(utils.duration_to_str(60*60),"60m")
     self.assertEquals(utils.duration_to_str(3*60*60+11),"3h11s")
     self.assertEquals(utils.duration_to_str(8*60+3*60*60*24+11),"3d8m11s")
 def get_interval(self, interval_name):
     interval = utils.str_to_duration( \
                     self.config.get(self.context, interval_name))
     for source_context in self.random_source_list:
         interval = min(interval,
                 utils.str_to_duration( \
                     self.config.get(source_context, interval_name)))
     return interval
Пример #4
0
    def __init__(self, context):
        super().__init__()
        self.context = context
        self.config = config.Config.instance()
        self.logger = logging.getLogger(logger_str(__class__) + " " + context)
        self.logger.info(f"Creating clientlet {self.context}")

        self.path = config.path_for(self.config.get(self.context, "backup"))
        assert os.path.exists(self.path), f"{self.path} does not exist!"

        # ALL source contexts (we care a lot)
        self.sources = {}
        self.scanners = {}
        self.random_source_list = []
        self.build_sources()

        lazy_write = utils.str_to_duration(
            self.config.get(context, "LAZY WRITE", 5))
        # TODO: my cache of claims should expire in rescan/2
        self.rescan = self.get_interval("rescan") // 2
        self.claims = PersistentDict(f"/tmp/cb.c{context}.json.bz2",
                                     lazy_write=5,
                                     expiry=self.rescan)
        self.drops = 0  # count the number of times I drop a file
        self.stats = stats.Stats()

        self.update_allocation()
        self.bailing = False
        self.datagrams = {}
Пример #5
0
    def __init__(self, context, path, **kwargs):
        self.context = context
        self.path = os.path.expanduser(path)
        if "name" in kwargs:
            name = kwargs["name"]
        else:
            name = context

        if "checksums" in kwargs:
            self.checksums = kwargs['checksums']
        else:
            self.checksums = True

        self.config = config.Config.instance()
        self.pd_filename = f".cb.{context}.json.bz2"
        lazy_write = utils.str_to_duration(
            self.config.get(context, "LAZY WRITE", 5))
        super().__init__(f"{self.path}/{self.pd_filename}",
                         lazy_write=lazy_write,
                         **kwargs)
        self.logger = logging.getLogger(logger_str(__class__) + " " + name)
        # self.logger.setLevel(logging.INFO)
        self.ignored_suffixes = {}
        self.report_timer = elapsed.ElapsedTimer()
        self.stat = stats.Statistic(buckets=(0, 5, 10, 30))
Пример #6
0
 def state_latency(self, states):
     latency = time.time() - self.newest_checksum(states)
     if latency < str_to_duration(self.config.getOption("cycle", "24h")):
         msg = "Current"
     else:
         msg = "Stale"
     msg += f"; last update {duration_to_str(latency)} ago"
     return msg
Пример #7
0
 def start(self):
     while True:
         self.logger.info("Starting")
         self.config.load()
         sources = self.config.get_sources_for_host(self.hostname)
         print(f"sources: {sources}")
         if len(sources.items()) > 0:
             for context, source in sources.items():
                 self.logger.info(f"{context}: {source}")
                 gcm = GhettoClusterSource(context)
                 gcm.scan()
                 self.get_status(context, source, False)
             self.logger.info("sources are complete.")
         else:
             self.logger.info("source of None")
         replicas = self.config.get_replicas_for_host(self.hostname)
         if len(replicas.items()) > 0:
             for context, replica in replicas.items():
                 self.logger.info(f"{context}: {replica}")
                 source = self.config.get_source_for_context(context)
                 dest = config.path_for(replica)
                 gcs = GhettoClusterReplica(context, replica, source)
                 # gcs.pull()
                 # gcs.scan()
                 puller = Thread(target=gcs.pull)
                 self.logger.info("Starting pull thread")
                 puller.start()
                 timer = elapsed.ElapsedTimer()
                 while puller.is_alive():
                     if timer.once_every(15):
                         scanner = Thread(target=gcs.scan)
                         self.logger.debug("Starting scan thread")
                         scanner.start()
                         scanner.join()
                         self.logger.debug("Scan thread finished")
                     else:
                         time.sleep(1)  # spin, but not hard
                 gcs.scan()
             self.logger.info("Replicas are complete")
         else:
             self.logger.info("replica to noone")
         try:
             signal.signal(signal.SIGHUP, self.wakeup)
             CYCLE = str_to_duration(self.config.getOption("CYCLE", "24h"))
             self.logger.info(f"Sleeping for {duration_to_str(CYCLE)}" + \
                                 f" in PID {os.getpid()}")
             self.logger.debug("send SIGHUP to wake up")
             time.sleep(CYCLE)
         except WakeupException:
             self.logger.warn(f"Restarting as requested (SIGHUP)")
             signal.signal(signal.SIGHUP, signal.SIG_DFL)
 def run(self):
     self.bailout = False
     # TODO: turbo prescan
     self.scanner.scan(turbo=True)
     self.logger.info("Ready to serve")
     self.handling = True
     while not self.bailout:
         self.config.load()
         self.scanner.scan()
         self.update_files()
         self.heartbeat()
         sleep_time = utils.str_to_duration( \
                         self.config.get(self.context, "rescan"))
         self.logger.info("Scanning complete; will re-scan in " \
                             + f"{utils.duration_to_str(sleep_time)}")
         time.sleep(sleep_time)
Пример #9
0
 def run_forever(self, deleting=False):
     try:
         signal.signal(signal.SIGHUP, self.wakeup)
         signal.signal(signal.SIGTERM, self.go_peacefully)
         while True:
             self.run(deleting=deleting)
             CYCLE = str_to_duration(self.config.getOption("cycle", "24h"))
             self.logger.info(f"Sleeping for {duration_to_str(CYCLE)}" + \
                                 f" in PID {os.getpid()}")
             self.logger.debug("send SIGHUP to wake up")
             time.sleep(CYCLE)
     except WakeupException:
         self.logger.warn(f"Restarting as requested (SIGHUP)")
         signal.signal(signal.SIGHUP, signal.SIG_DFL)
     except TermException:
         self.logger.warn(f"Exiting for SIGTERM")
         sys.exit()
     except KeyboardInterrupt:
         self.logger.warn(f" Exiting...")
         sys.exit()
Пример #10
0
    def __init__(self, context):
        super().__init__()
        self.context = context

        logger_str = f"{utils.logger_str(__class__)} {context}"
        self.logger = logging.getLogger(logger_str)
        # self.logger.setLevel(logging.INFO)

        self.config = config.Config.instance()
        self.copies = int(self.config.get(self.context, "copies", 2))
        self.path = config.path_for(self.config.get(self.context, "source"))
        self.scanner = scanner.ScannerLite(self.context, self.path)
        self.rescan = utils.get_interval(self.config, "rescan", self.context)

        lazy_write = self.config.get(context, "LAZY WRITE", 5)
        lazy_write = utils.str_to_duration(lazy_write)
        # self.clients: { filename : { client: expiry_time, } }
        clients_state = f"/tmp/cb.{context}-clients.json.bz2"
        self.clients = PersistentDict(clients_state, lazy_write=5)
        self.stats = stats.Stats()
        self.handling = False
Пример #11
0
 def replica_is_current(self, latency):
     return latency < str_to_duration(self.config.getOption("cycle", "24h"))