Esempio n. 1
0
    def _try_lock(self, requirements, candidate):
        """ Function that tries to lock given candidate resource """
        resource_id = candidate.get("id")
        try:
            pid_file = f"{resource_id}.pid"
            self.logger.debug('Trying lock using: %s',
                              os.path.join(self._lock_folder, pid_file))

            _lockable = PidFile(pidname=pid_file, piddir=self._lock_folder)
            _lockable.create()
            self.logger.info('Allocated: %s, lockfile: %s', resource_id,
                             pid_file)

            def release():
                nonlocal self, resource_id, _lockable
                self.logger.info('Release resource: %s', resource_id)
                _lockable.close()
                del self._allocations[resource_id]

            return Allocation(requirements=requirements,
                              resource_info=candidate,
                              _release=release,
                              pid_file=_lockable.filename)
        except PidFileError as error:
            raise AssertionError('no success') from error
Esempio n. 2
0
def acquire_lock(name):
    """
    Attempts to acquire a lock for the name provided.
    """
    lock = PidFile(
        pidname="%s.LOCK" % name,
        piddir=LOCK_ROOT,
        enforce_dotpid_postfix=False)
    lock.create()
class Index:
    """
    There's a file on disc called "local state file" and it says when was the last timestamp pulled from Slack.
    """
    def __init__(self, index_path: Path):
        self._index_path = index_path
        self._data = None
        self._pidfile = PidFile("index", piddir="/tmp", lock_pidfile=True)

    def __enter__(self):
        if self._data is not None:
            raise Exception("can only enter once")
        self._index_path.parent.mkdir(exist_ok=True, parents=True)
        self._pidfile.create()
        if not self._index_path.exists():
            self._index_path.write_text("{}")
        self._data = json.load(self._index_path.open("r"))
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        if exception_type is None:
            json.dump(self._data, self._index_path.open("w"), indent=4)
        self._pidfile.close()
        self._data = None

    def ts(self, channel: Conversation) -> Optional[datetime.datetime]:
        serialized = self._timestamps.get(repr(channel))
        if serialized:
            return self._str_to_ts(serialized)

    def set_ts(self, channel: Conversation, ts: datetime.datetime) -> None:
        self._timestamps[repr(channel)] = self._ts_to_str(ts)

    def set_all(self, ts):
        for k in self._timestamps:
            self._timestamps[k] = self._ts_to_str(ts)

    @classmethod
    def _ts_to_str(cls, ts: datetime.datetime) -> str:
        return ts.strftime(cls.datetime_format)

    @classmethod
    def _str_to_ts(cls, str_datetime: str) -> datetime.datetime:
        return datetime.datetime.strptime(str_datetime, cls.datetime_format)

    @property
    def _timestamps(self):
        return self._data.setdefault('timestamps', {})

    datetime_format = "%Y-%m-%d_%H:%M:%S.%f_%z"
Esempio n. 4
0
def start(args, logger, baseguess):
    global routes, static_path, timers
    pidfile = config.get('papercup', 'pidfile')
    if (pidfile[0] == '/'):
        piddir = os.path.dirname(pidfile)
        pidfile = os.path.basename(pidfile)
    else:
        piddir = baseguess
    logger.info("")
    logger.info("Writing pid file: %s/%s" % (piddir, pidfile))
    pf_handler = PidFile(pidname=pidfile, piddir=piddir)

    passed = False
    for _ in range(0, 10):
        try:
            pf_handler.create()
            tornado.autoreload.add_reload_hook(pf_handler.close)
            passed = True
            break
        except PidFileAlreadyRunningError:
            logger.info("Pid file already running, retrying...")
            time.sleep(0.5)
        except PidFileAlreadyLockedError:
            logger.info("Pid file already locked, retrying...")
            time.sleep(0.5)
    if not passed:
        logger.info("Giving up")
        return

    logger.info("")
    config.init_modules()
    config.prerun_modules()

    import traceback
    import fnmatch
    from importlib import import_module
    import inspect
    from papercup import handlers
    client = None
    sentry_client = None

    logger.info("")
    logger.info("Base routes...")
    routes = []
    from papercup import handlers
    for route, c, tkwargs in handlers.routes:
        routes.append(tornado.web.URLSpec(route, c, tkwargs, None))

    route_text = "Base Routes:\n"
    for k in routes:
        if isinstance(k, tornado.web.URLSpec):
            cname = getattr(k.handler_class, "unbound_repr", None)
            if cname:
                cname = cname()
            else:
                cname = k.handler_class
            route_text += "  -- URLSpec(%-25s\t%s, kwargs=%r, name=%r)\n" % (
                "%r," % k.regex.pattern, cname, k.kwargs, k.name)
        else:
            route_text += "  -- %s\n" % str(k)
    logger.info(route_text)

    application = tornado.web.Application(routes,
                                          **config.get('papercup', 'tornado'))
    application.sentry_client = sentry_client
    application.listen(config.get('papercup', 'port'),
                       xheaders=config.get('papercup', 'tornado', 'xheaders'))

    # Tornado requires a settings entry for 'static_path' in order to make use of its static_url() method within template files, even though a separate handler was defined above.  However just adding the setting to the config, even though it's not used, will allow access to proper caching behavior.
    application.settings['static_path'] = static_path

    logger.info("")
    logger.info("Running...")
    logger.info("")
    try:
        tornado.ioloop.IOLoop.instance().start()
    finally:
        for f in exit_hooks:
            f()