Example #1
0
    def unlock(self, name):
        name_256 = make_sha256(name)
        pattern_name = name_256 + '.'
        folder_path = join_paths(self.path, name_256[0])

        # Lookup for locked positions
        files = []
        for filename in get_dir_filenames(folder_path):
            if filename.startswith(pattern_name):
                position = int(filename.split('.', 1)[1])
                files.append((position, filename))
        if files:
            files.sort()

            for position, filename in files:
                file_path = join_paths(folder_path, filename)
                if remove_file(
                        file_path,
                        retries=self.retries,
                        retry_errno=self.retry_errno):
                    return True

        # If no position found, delete base lock
        return remove_file_quietly(self.get_file_path(name), retries=self.retries, retry_errno=self.retry_errno)
Example #2
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)