All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.sadstool.redissonaspectlock.lock.LockCollection Maven / Gradle / Ivy

The newest version!
package com.github.sadstool.redissonaspectlock.lock;

import com.github.sadstool.redissonaspectlock.attributes.LockAttributes;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

public class LockCollection {
    private static final Logger LOGGER = LoggerFactory.getLogger(LockCollection.class);

    private Map locks;
    private Function errorFactory;

    public LockCollection(Map locks, Function errorFactory) {
        this.locks = locks;
        this.errorFactory = errorFactory;
    }

    public Object proceed(ProceedingJoinPoint joinPoint) throws Throwable {
        acquire();
        try {
            return joinPoint.proceed();
        } finally {
            release();
        }
    }

    private void acquire() throws Exception {
        List acquiredLocks = new ArrayList<>();
        Optional failed = Optional.empty();

        for (Lock lock : locks.keySet()) {
            if (!acquire(lock)) {
                failed = Optional.of(lock);
                break;
            } else {
                acquiredLocks.add(lock);
            }
        }

        if (failed.isPresent()) {
            LockAttributes failedLockAttributes = locks.get(failed.get());
            LOGGER.debug("Locking failed: {}", failedLockAttributes.getPath());
            acquiredLocks.forEach(this::release);

            throw errorFactory.apply(failedLockAttributes);
        } else {
            LOGGER.trace("Locked");
        }
    }

    private boolean acquire(Lock lock) {
        LOGGER.debug("Locking: {}", locks.get(lock).getPath());

        return lock.acquire();
    }

    private void release() {
        locks.keySet().forEach(this::release);
    }

    private void release(Lock lock) {
        LOGGER.debug("Unlocking: {}", locks.get(lock).getPath());

        lock.release();
    }

    public static class Builder {
        private List attributes;
        private Function lockProvider;
        private Function errorFactory;

        public Builder setAttributes(List attributes) {
            this.attributes = attributes;

            return this;
        }

        public Builder setLockProvider(Function lockProvider) {
            this.lockProvider = lockProvider;

            return this;
        }

        public Builder setErrorFactory(Function errorFactory) {
            this.errorFactory = errorFactory;

            return this;
        }

        public LockCollection build() {
            Map map = attributes.stream()
                    .collect(Collectors.toMap(attributes -> lockProvider.apply(attributes), Function.identity()));

            return new LockCollection(map, errorFactory);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy