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

io.nuls.core.rpc.modulebootstrap.NotifySender Maven / Gradle / Ivy

package io.nuls.core.rpc.modulebootstrap;

import io.nuls.core.basic.InitializingBean;
import io.nuls.core.core.annotation.Component;
import io.nuls.core.exception.NulsException;
import io.nuls.core.log.Log;
import io.nuls.core.thread.ThreadUtils;
import io.nuls.core.thread.commom.NulsThreadFactory;

import java.util.Queue;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zhoulijun
 * @Time: 2019-03-13 14:47
 * @Description: 模块依赖管理状态通知
 * 通过重试的方式确保通知成功。若失败等待1秒重新通知,直到成功为止
 */
@Component
public class NotifySender implements Runnable, InitializingBean {

    private class Sender {

        String key;

        int retry;

        int retryTotal;

        Callable caller;

        void retry(){
            this.retry++;
        }

        boolean canRetry(){
            return retry < retryTotal;
        }

        public Sender(String key, int retryTotal, Callable caller){
            this.retry = 0;
            this.retryTotal = retryTotal;
            this.key = key;
            this.caller = caller;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof Sender)) {
                return false;
            }

            Sender sender = (Sender) o;

            return key != null ? key.equals(sender.key) : sender.key == null;
        }

        @Override
        public int hashCode() {
            return key != null ? key.hashCode() : 0;
        }
    }

    ScheduledThreadPoolExecutor executor = ThreadUtils.createScheduledThreadPool(1, new NulsThreadFactory("notify-sender"));

    Queue notifyQueue = new ConcurrentLinkedQueue<>();

    @Override
    public void run() {
        while (true) {
            Queue temp = new ConcurrentLinkedQueue<>();
            while (!notifyQueue.isEmpty()) {
                Sender sender = notifyQueue.poll();
                Callable caller = sender.caller;
                try {
                    Boolean success = caller.call();
                    if (!success) {
                        retry(temp,sender);
                    }
                } catch (Exception e) {
                    retry(temp,sender);
                }
            }
            while(!temp.isEmpty()){
                notifyQueue.offer(temp.poll());
            }
            try {
                TimeUnit.SECONDS.sleep(1L);
            } catch (InterruptedException e) {
                Log.error("notify sender thread error", e);
            }
        }
    }

    private void retry(Queue temp, Sender sender){
        if(sender.canRetry()){
            Log.warn("notify {} fail, retry {}",sender.key,sender.retry);
            sender.retry();
            temp.offer(sender);
        }else{
            Log.error("rpc module notify fail :{}",sender.key);
        }
    }

    public void send(String key, int retryTotal, Callable caller) {
        this.notifyQueue.offer(new Sender(key,retryTotal,caller));
    }

    @Override
    public void afterPropertiesSet() throws NulsException {
        executor.execute(this);
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy