示例#1
0
    def __init__(self, rootDir, resolver):
        """
        @type rootDir: str
        @param rootDir: root directory of the cache. will be created if it does not exist.
        @type resolver: FileResolver
        @param resolver: Pluggable component to retrieve (resolve) files.
        """
        self.rootDir = rootDir
        self.resolver = resolver
        self.locksByResource = SynchronizedDict()

        requireDir(rootDir)
        if not os.path.isdir(rootDir):
            raise Exception, 'File cache root dir already exists as a file: %s' % rootDir
示例#2
0
 def __init__(self, rootDir, resolver):
     """
     @type rootDir: str
     @param rootDir: root directory of the cache. will be created if it does not exist.
     @type resolver: FileResolver
     @param resolver: Pluggable component to retrieve (resolve) files.
     """
     self.rootDir = rootDir
     self.resolver = resolver
     self.locksByResource = SynchronizedDict()
     
     requireDir(rootDir)
     if not os.path.isdir(rootDir):
         raise Exception, 'File cache root dir already exists as a file: %s' % rootDir
示例#3
0
class FileCache(object):
    """File cache which uses a FileResolver to populate the cache on-demand"""
    def __init__(self, rootDir, resolver):
        """
        @type rootDir: str
        @param rootDir: root directory of the cache. will be created if it does not exist.
        @type resolver: FileResolver
        @param resolver: Pluggable component to retrieve (resolve) files.
        """
        self.rootDir = rootDir
        self.resolver = resolver
        self.locksByResource = SynchronizedDict()

        requireDir(rootDir)
        if not os.path.isdir(rootDir):
            raise Exception, 'File cache root dir already exists as a file: %s' % rootDir

    def _mapToPath(self, fileUrl):
        return os.path.join(self.rootDir, self.resolver.hash(fileUrl))

    def contains(self, fileUrl):
        return os.path.exists(self._mapToPath(fileUrl))

    def get(self, fileUrl):
        """
        @return: local path if file resolution was successful, None otherwise
        """
        filepath = self._mapToPath(fileUrl)
        if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
            log.debug('Cache MISS %s' % safe_str(fileUrl))

            self.lockResource(fileUrl)
            try:
                if not self.contains(fileUrl):
                    self.resolver.store(fileUrl, filepath)
            finally:
                self.unlockResource(fileUrl)

            # Don't cache zero byte files
            if not os.path.exists(filepath):
                log.warn('File could not be resolved: %s and not at path: %s' %
                         (safe_str(fileUrl), filepath))
                return None

            if os.path.getsize(filepath) == 0:
                log.warn('file %s resulted in zero byte file...removing...' %
                         safe_str(fileUrl))
                self.remove(fileUrl)
                return None
        else:
            if log.isEnabledFor(logging.DEBUG):
                if hasattr(fileUrl, 'title'):
                    s = fileUrl.title()
                elif hasattr(fileUrl, 'getChannelName'):
                    s = fileUrl.getChannelName()
                else:
                    s = fileUrl
                #log.debug('Cache HIT %s ' % safe_str(s))
        return filepath

    @sync_instance
    def createAndClaimLock(self, resource):
        if not self.locksByResource.has_key(resource):
            #log.debug('Thread created lock %s' % threading.currentThread().getName())
            lock = threading.RLock()
            lock.acquire()
            self.locksByResource.put(resource, lock)
        else:
            #log.debug('Thread nearly createdlock %s' % threading.currentThread().getName())
            lock = self.locksByResource.get(resource)
            lock.acquire()

    def lockResource(self, resource):
        if self.locksByResource.has_key(resource):
            #log.debug('Thread waiting for lock %s' % threading.currentThread().getName())
            lock = self.locksByResource.get(resource)
            lock.acquire()
        else:
            self.createAndClaimLock(resource)

    def unlockResource(self, resource):
        lock = self.locksByResource.get(resource)
        #log.debug('lock = %s'%lock)
        lock.release()

    def remove(self, fileUrl):
        filepath = self._mapToPath(fileUrl)
        if os.path.exists(filepath):
            os.remove(filepath)

    def clear(self):
        shutil.rmtree(self.rootDir, True)
        requireDir(self.rootDir)
        self.locksByResource.clear()
示例#4
0
class FileCache(object):
    """File cache which uses a FileResolver to populate the cache on-demand"""
    
    def __init__(self, rootDir, resolver):
        """
        @type rootDir: str
        @param rootDir: root directory of the cache. will be created if it does not exist.
        @type resolver: FileResolver
        @param resolver: Pluggable component to retrieve (resolve) files.
        """
        self.rootDir = rootDir
        self.resolver = resolver
        self.locksByResource = SynchronizedDict()
        
        requireDir(rootDir)
        if not os.path.isdir(rootDir):
            raise Exception, 'File cache root dir already exists as a file: %s' % rootDir

    def _mapToPath(self, fileUrl):
        return os.path.join(self.rootDir, self.resolver.hash(fileUrl))
        
    def contains(self, fileUrl):
        return os.path.exists(self._mapToPath(fileUrl))
     
    def get(self, fileUrl):
        """
        @return: local path if file resolution was successful, None otherwise
        """
        filepath = self._mapToPath(fileUrl) 
        if not os.path.exists(filepath) or os.path.getsize(filepath) == 0:
            log.debug('Cache MISS %s' % safe_str(fileUrl))
            
            self.lockResource(fileUrl)
            try:
                if not self.contains(fileUrl): 
                    self.resolver.store(fileUrl, filepath)
            finally:
                self.unlockResource(fileUrl)
            
            # Don't cache zero byte files
            if not os.path.exists(filepath):
                log.warn('File could not be resolved: %s and not at path: %s' % (safe_str(fileUrl), filepath) )
                return None
            
            if os.path.getsize(filepath) == 0:
                log.warn('file %s resulted in zero byte file...removing...' % safe_str(fileUrl))
                self.remove(fileUrl)
                return None
        else:
            if log.isEnabledFor(logging.DEBUG):
                if hasattr(fileUrl, 'title'):
                    s = fileUrl.title()
                elif hasattr(fileUrl, 'getChannelName'):
                    s = fileUrl.getChannelName()
                else:
                    s = fileUrl
                #log.debug('Cache HIT %s ' % safe_str(s))
        return filepath

    @sync_instance
    def createAndClaimLock(self, resource):
        if not self.locksByResource.has_key(resource):
            #log.debug('Thread created lock %s' % threading.currentThread().getName())
            lock = threading.RLock()
            lock.acquire()
            self.locksByResource.put(resource, lock)
        else:
            #log.debug('Thread nearly createdlock %s' % threading.currentThread().getName())
            lock = self.locksByResource.get(resource)
            lock.acquire()
            
    
    def lockResource(self, resource):
        if self.locksByResource.has_key(resource):
            #log.debug('Thread waiting for lock %s' % threading.currentThread().getName())
            lock = self.locksByResource.get(resource)
            lock.acquire()
        else:
            self.createAndClaimLock(resource)
    
    def unlockResource(self, resource):
        lock = self.locksByResource.get(resource)
        #log.debug('lock = %s'%lock)
        lock.release()
    
    def remove(self, fileUrl):
        filepath = self._mapToPath(fileUrl)
        if os.path.exists(filepath):
            os.remove(filepath)
            
    def clear(self):
        shutil.rmtree(self.rootDir, True)
        requireDir(self.rootDir)
        self.locksByResource.clear()