def open(self, r, path, flags): # FIXME: the checks below make open quite slow, as we travel down the # path components. This should be done in a single pipeline. r.logger.debug("redis_ns_entry.open %s" % path) # make sure parent dir exists try: parent_path = redis_ns_parent(path) # go down the rabbit hole parent = self.opendir(r, parent_path, flags) except Exception as e: raise rse.BadParameter("Cannot open parent %s (%s)" % (parent, e)) # try to open entry itself e = redis_ns_entry(r, path) try: e.fetch() except Exception: if c.CREATE & flags: e.node[TYPE] = ENTRY e.create(flags) else: raise rse.BadParameter("Cannot open %s (no such entry)" % path) return e
def mkdir(self, flags): """ Don't call this directly -- to create a dir, call opendir with 'create'/'create_parents' and 'exclusive'. If called, assumes that entry is invalid (and thus does not yet exist). """ path = self.path if self.valid: raise rse.IncorrectState("mkdir %s failed, entry exists" % path) self.logger.debug("redis_ns_entry.mkdir %s" % path) # if / does not exist, we always create it - no need for checks if path != '/': # if CREATE_PARENTS is set, we need to check all parents, and need # to create them as needed. We go top down, and terminate once # a parent is found if c.CREATE_PARENTS & flags: # this will recursively travel down the chimney hole, and stop # whenever it finds an existing directory parent = redis_ns_parent(path) pe = redis_ns_entry.opendir(self.r, parent, c.CREATE_PARENTS) else: # if 'CREATE_PARENTS is not set, parent must exist. parent = redis_ns_parent(path) pe = None try: pe = redis_ns_entry(self.r, parent) pe.fetch() except Exception as e: raise rse.BadParameter( "mkdir %s fails, parent does not exist: %s" % (path, e)) if not pe.is_dir(): raise rse.BadParameter( "mkdir %s fails, parent is no directory: %s" % (path, parent)) self.node[TYPE] = DIR self.create(flags)
def __init__(self, url): if url.scheme != 'redis': raise rse.BadParameter("unsupported url scheme (%s)" % url) self.url = url self.host = 'localhost' self.port = 6379 self.db = 0 self.password = None self.errors = 'strict' if url.host: self.host = url.host if url.port: self.port = url.port if url.username: self.username = url.username if url.password: self.password = url.password # create redis client t1 = time.time() redis.Redis.__init__(self, host=self.host, port=self.port, db=self.db, password=self.password, errors=self.errors) t2 = time.time() # add a logger self.logger = ru.Logger('radical.saga') # create a cache dict and attach to redis client instance. Cache # lifetime is set to 10 times the redis-connect latency. self.cache = redis_cache.Cache(logger=self.logger, ttl=((t2 - t1) * 10)) # create a second client to manage the (blocking) # pubsub communication for event notifications self.r2 = redis.Redis(host=self.host, port=self.port, db=self.db, password=self.password, errors=self.errors) # set up pubsub endpoint, and start a thread to monitor channels self.callbacks = dict() self.pub = self.r2.pubsub() self.pub.subscribe(MON) # FIXME: create one pubsub channel per path (for paths which have # callbacks registered) self.monitor = redis_ns_monitor(self, self.pub) self.monitor.start()
def get_key(self, key): self.logger.debug("redis_ns_entry.get_key %s" % (key)) self.fetch() # refresh cache/state as needed if key not in self.data: raise rse.BadParameter("no such attribute (%s)" % key) val = self.data[key] if key == 'foo' and val == 'stop': self.cache._dump() return val
def opendir(self, r, path, flags): r.logger.debug("redis_ns_entry.opendir %s" % path) e = redis_ns_entry(r, path) try: e.fetch() except Exception as e: if c.CREATE & flags or \ c.CREATE_PARENTS & flags : e = redis_ns_entry(r, path) e.mkdir(flags) else: raise rse.BadParameter("Cannot open %s (does not exist)" % path) if not e.is_dir(): raise rse.BadParameter("Cannot open %s (not a directory)" % path) return e