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

com.godmao.mqbroker.DeadLetterQueue Maven / Gradle / Ivy

There is a newer version: 0.2.7.RELEASE
Show newest version
package com.godmao.mqbroker;


import io.netty.util.concurrent.DefaultEventExecutor;
import io.netty.util.concurrent.DefaultThreadFactory;
import io.netty.util.concurrent.EventExecutor;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * 延时死信队列
 */
public class DeadLetterQueue {

    private final List queue;
    private final EventExecutor executor;

    public DeadLetterQueue(int initialCapacity) {
        this.queue = new ArrayList<>(initialCapacity);
        this.executor = new DefaultEventExecutor(new DefaultThreadFactory(this.getClass()));
    }


    public static class Message {
        /**
         * 消息
         */
        private final Object message;
        /**
         * 消息到期时间 到期自动删除
         */
        private       long   endTime;

        public Message(Object message, long delay) {
            this.endTime = System.currentTimeMillis() + delay;
            this.message = message;
        }

        public Message(Object message) {
            this(message, TimeUnit.MINUTES.toMillis(10));
        }


        public Object getMessage() {
            return message;
        }

        public void remove() {
            this.endTime = -1L;
        }

        public boolean isRemoved() {
            return this.endTime <= System.currentTimeMillis();
        }

        @Override
        public String toString() {
            return "[" +
                    "message=" + message +
                    ", endTime=" + endTime +
                    ']';
        }
    }

    public void add(long delay, Object message) {
        add0((Message) new Message(message, delay));
    }

    public void add(Object message) {
        add0((Message) new Message(message));
    }

    private void add0(Message message) {
        executor.execute(() -> {
            queue.add(message);
            //
            queue.removeIf(Message::isRemoved);
        });
    }

    public void forEach(Consumer action) {
        Objects.requireNonNull(action);
        executor.execute(() -> {
            for (Message message : queue) {
                if (message.isRemoved()) {
                    continue;
                }
                action.accept(message);
            }
            //
            queue.removeIf(Message::isRemoved);
        });
    }

    public void shutdown() {
        if (!this.executor.isShutdown()) {
            this.executor.shutdownGracefully().addListener(future -> {
                if (!future.isSuccess()) {
                    future.cause().printStackTrace();
                } else {
                    queue.clear();
                }
            });
        }
    }

    @Override
    public String toString() {
        return queue.stream().filter(message -> !message.isRemoved()).collect(Collectors.toList()).toString();
    }

    public static void main(String[] args) throws InterruptedException {
        DeadLetterQueue deadLetterQueue = new DeadLetterQueue(1000);
        deadLetterQueue.add("godmao1");
        deadLetterQueue.add(10000L, "godmao2");

        deadLetterQueue.forEach(message -> {
            System.out.println(message);
        });
        System.out.println(deadLetterQueue);


        Thread.sleep(10000L);
        deadLetterQueue.forEach(message -> {
            System.err.println(message);
        });
        System.err.println(deadLetterQueue);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy