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

com.github.shoothzj.sdk.distribute.impl.mongo.MongoDistributeImpl Maven / Gradle / Ivy

package com.github.shoothzj.sdk.distribute.impl.mongo;

import com.github.shoothzj.javatool.util.CommonUtil;
import com.github.shoothzj.sdk.distribute.api.ElectionListener;
import com.github.shoothzj.sdk.distribute.api.IDistribute;
import com.github.shoothzj.sdk.distribute.impl.mongo.dao.ElectionId;
import com.github.shoothzj.sdk.distribute.impl.mongo.dao.MongoLock;
import com.github.shoothzj.sdk.distribute.impl.mongo.repo.ElectionIdRepo;
import com.github.shoothzj.sdk.distribute.impl.mongo.repo.MongoLockRepo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author hezhangjian
 */
@Slf4j
@Service
public class MongoDistributeImpl implements IDistribute {

    private static final int RETRY_TIME = 20;

    private static final int TIME_SLOP_MS = 10;

    private MongoLockRepo mongoLockRepo;

    private ElectionIdRepo electionIdRepo;

    public MongoDistributeImpl(@Autowired MongoLockRepo mongoLockRepo, @Autowired ElectionIdRepo electionIdRepo) {
        this.mongoLockRepo = mongoLockRepo;
        this.electionIdRepo = electionIdRepo;
    }

    @Override
    public void addElectionListener(String scene, ElectionListener listener) throws Exception {

    }

    @Override
    public String requireLock(String scene, long time) throws Exception {
        String uniqId = UUID.randomUUID().toString();
        MongoLock mongoLock = mongoLockRepo.findMongoLockByScene(scene);
        long expireTime = System.currentTimeMillis() + time;
        if (mongoLock == null) {
            //如果mongoLock存在,尝试插入,插入成功即获得了锁
            try {
                mongoLockRepo.insert(new MongoLock(scene, uniqId, expireTime));
                return uniqId;
            } catch (Exception e) {
                log.error("insert mongo data failed, ", e);
                throw new Exception("get lock failed", e);
            }
        } else {
            if (mongoLock.getExpireTime() < System.currentTimeMillis()) {
                //原来的锁过期,可以覆盖
                mongoLockRepo.findAndModify(scene, mongoLock.getUniqId(), uniqId, expireTime);
                return uniqId;
            }
        }
        throw new Exception("get lock failed");
    }

    @Override
    public void releaseLock(String scene, String uniqId) throws Exception {
        Long result = mongoLockRepo.deleteBySceneAndUniqId(scene, uniqId);
        log.debug("delete end result is [{}]", result);
    }

    @Override
    public long getNumber(String scene) throws Exception {
        for (int i = 0; i < RETRY_TIME; i++) {
            try {
                Long maxId = electionIdRepo.maxId(scene);
                electionIdRepo.insert(new ElectionId(scene, maxId + 1));
                return maxId + 1;
            } catch (Exception e) {
                log.error("id find or insert exception, retrying, cause is [{}]", e.getMessage());
                CommonUtil.sleep(TimeUnit.MILLISECONDS, TIME_SLOP_MS);
            }
        }
        throw new Exception("");
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy