package cn.reghao.tnb.message.app.rabbit.c;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

/**
 * @author reghao
 * @date 2021-08-24 17:43:14
 */
public class RpcListener implements Runnable {
    private final String controlBus = "MsgQueue.controlBus(AppId.crawler.name(), )";
    private final ConnectionFactory connFactory;
    private final Object monitor = new Object();

    public RpcListener(RabbitConfig config) {
        this.connFactory = new ConnectionFactory();
        this.connFactory.setHost(config.getHost());
        this.connFactory.setPort(5672);
        this.connFactory.setUsername(config.getUsername());
        this.connFactory.setPassword(config.getPassword());
        this.connFactory.setVirtualHost(config.getVhost());
    }

    @Override
    public void run() {
        try (Connection connection = connFactory.newConnection(); Channel channel = connection.createChannel()) {
            // TODO 设置队列中消息的 TTL
            channel.queueDeclare(controlBus, true, false, false, null);
            channel.queuePurge(controlBus);
            channel.basicQos(1);
            System.out.printf("RPC server 在 %s 线程中等待 RPC 请求...\n", Thread.currentThread().getName());

            DeliverCallback deliverCallback = new RpcListenerCallback(channel, monitor);
            channel.basicConsume(controlBus, false, deliverCallback, (consumerTag -> {}));

            // Wait and be prepared to consume the message from RPC client.
            while (!Thread.interrupted()) {
                synchronized (monitor) {
                    try {
                        // 等待 consumer 线程执行完成
                        monitor.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
