Beispiel #1
0
    def remove_reference(self, name, expire=MARKER):
        file_path = self.get_reference_path(name)
        temporary_file_path = file_path + '.' + make_uuid_hash()
        move_file(file_path, temporary_file_path, retries=self.retries, retry_errno=self.retry_errno)

        references = self._get_references(temporary_file_path, name='')
        if name in references:
            references.remove(name)

        # Validate if references still exists
        if references:
            if expire is MARKER:
                # Dont use expire, we only need to know if file exists
                expire = None
            for name in references:
                path = self.get_file_path(name)
                if not self._contains(path, expire=expire):
                    references.remove(name)

            if references:
                references = maybe_list(references)
                references.append(b_linesep)

                put_binary_on_file(
                    file_path,
                    binary=bytes_join(b_linesep, references),
                    mode='ab',
                    retries=self.retries,
                    retry_errno=self.retry_errno)

        self._delete_path(temporary_file_path)
Beispiel #2
0
    def lock(self, name, timeout=MARKER, delete_lock_on_timeout=MARKER):
        name_256 = self.format_name(name)
        lock_code = make_uuid_hash()
        lock_name = '%s %s %s' % (DOMAIN_NAME, PROCESS_ID, lock_code)

        position = None
        while position is None:
            self.memcache.add(name_256, '0')
            position = self.memcache.incr(name_256)

        if position is 1:
            # Me first! Thank you!
            return None

        # Define expire time
        expire_time = None
        if timeout is MARKER:
            timeout = self.timeout
        if timeout:
            expire_time = NOW_TIME() + int(timeout)

        # Lock my wait position
        position_name_256 = self.format_position_name(name_256, position)
        self.memcache.set(position_name_256, lock_name)

        # Wait until my locked position is cleaned
        while self._contains(position_name_256):
            sleep(0.1)

            if expire_time and NOW_TIME() > expire_time:
                # Im done! No more wait for me!
                if not self.memcache.delete(position_name_256):
                    # Wait.. after all.. its show time!
                    return None

                if delete_lock_on_timeout is MARKER:
                    delete_lock_on_timeout = self.delete_lock_on_timeout
                if delete_lock_on_timeout:
                    self.unlock(name)
                    # Sorry, you need to do everything again
                    return self.lock(name, timeout=timeout, delete_lock_on_timeout=delete_lock_on_timeout)
                else:
                    # Clean invalid locks!
                    if self.clean_junk_locks(name_256):
                        # Go again
                        return self.lock(name, timeout=timeout, delete_lock_on_timeout=delete_lock_on_timeout)

                    message = 'Timeout (%ss) on lock "%s". Delete (%s*) to unlock' % (timeout, name, name_256)
                    raise LockTimeout(message, name_256)

        self.memcache.delete(position_name_256)
Beispiel #3
0
 def make_key(self):
     return make_uuid_hash()
Beispiel #4
0
    def lock(self, name, timeout=MARKER, delete_lock_on_timeout=MARKER):
        path = self.get_file_path(name)
        lock_code = make_uuid_hash()
        lock_name = '%s %s %s' % (DOMAIN_NAME, PROCESS_ID, lock_code)
        lock_name_to_file = lock_name + NEW_LINE

        position = None
        while position is None:
            # Enter on wait list
            put_binary_on_file(path, lock_name_to_file, mode='a', retries=self.retries, retry_errno=self.retry_errno)

            # Find my wait position
            binary = get_file_binary(path, mode='r', retries=self.retries, retry_errno=self.retry_errno)
            if binary:
                for i, code in enumerate(binary.splitlines()):
                    if code.split()[-1] == lock_code:
                        position = i
                        break

        if position is 0:
            # Me first! Thank you!
            return

        # Define expire time
        expire_time = None
        if timeout is MARKER:
            timeout = self.timeout
        if timeout:
            expire_time = NOW_TIME() + int(timeout)

        # Lock my wait position
        position_path = '%s.%s' % (path, position)
        put_binary_on_file(position_path, lock_name, retries=self.retries, retry_errno=self.retry_errno)

        # Wait until my locked position is cleaned
        while isfile(position_path):
            sleep(0.1)

            if expire_time and NOW_TIME() > expire_time:
                # Im done! No more wait for me!
                try:
                    remove_file(position_path)
                except OSError as error:
                    if error.errno is errno.ENOENT:
                        # Wait.. after all.. its show time!
                        return None
                    else:
                        raise

                if delete_lock_on_timeout is MARKER:
                    delete_lock_on_timeout = self.delete_lock_on_timeout
                if delete_lock_on_timeout:
                    self.unlock(name)
                    # Sorry, you need to do everything again
                    return self.lock(name, timeout=timeout, delete_lock_on_timeout=delete_lock_on_timeout)
                else:
                    # Clean locks!
                    self.clean_junk_locks_as_daemon()

                    message = 'Timeout (%ss) on lock "%s". Delete (%s*) to unlock' % (timeout, name, path)
                    raise LockTimeout(message, position_path)

        remove_file_quietly(position_path, retries=self.retries, retry_errno=self.retry_errno)