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

com.alibaba.rocketmq.research.rpc.DefaultRPCClient Maven / Gradle / Ivy

There is a newer version: 3.1.8
Show newest version
/**
 * $Id: DefaultRPCClient.java 1831 2013-05-16 01:39:51Z shijia.wxr $
 */
package com.alibaba.rocketmq.research.rpc;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * 客户端实现
 * 
 * @author shijia.wxr
 */
public class DefaultRPCClient implements RPCClient {
    // private Connection connection;
    private List connectionList = new ArrayList();
    private final AtomicInteger requestId = new AtomicInteger(0);

    private final ConcurrentHashMap callRepTable =
            new ConcurrentHashMap(1000000);

    private final ClientRPCProcessor clientRPCProcessor = new ClientRPCProcessor();

    class ClientRPCProcessor implements RPCProcessor {

        @Override
        public byte[] process(int repId, ByteBuffer response) {
            CallResponse cr = DefaultRPCClient.this.callRepTable.get(repId);
            if (cr != null) {
                cr.setReponseId(repId);
                cr.setResponseBody(response);
                cr.getCountDownLatch().countDown();
            }
            return null;
        }
    }

    class CallResponse {
        private int reponseId;
        private ByteBuffer responseBody;
        private CountDownLatch countDownLatch = new CountDownLatch(1);


        public int getReponseId() {
            return reponseId;
        }


        public void setReponseId(int reponseId) {
            this.reponseId = reponseId;
        }


        public ByteBuffer getResponseBody() {
            return responseBody;
        }


        public void setResponseBody(ByteBuffer responseBody) {
            this.responseBody = responseBody;
        }


        public CountDownLatch getCountDownLatch() {
            return countDownLatch;
        }


        public void setCountDownLatch(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }


        public CallResponse(int reponseId) {
            this.reponseId = reponseId;
        }
    }


    public DefaultRPCClient() {

    }


    @Override
    public void start() {
        for (Connection c : this.connectionList) {
            c.start();
        }
    }


    @Override
    public void shutdown() {
        for (Connection c : this.connectionList) {
            c.shutdown();
        }
    }


    private Connection findConnection(int id) {
        int pos = Math.abs(id) % this.connectionList.size();
        return this.connectionList.get(pos);
    }


    @Override
    public ByteBuffer call(byte[] request) throws InterruptedException {
        int id = this.requestId.incrementAndGet();
        CallResponse response = new CallResponse(id);
        this.callRepTable.put(id, response);
        this.findConnection(id).putRequest(id, request);
        boolean waitOK = response.getCountDownLatch().await(5000, TimeUnit.MILLISECONDS);
        ByteBuffer result = null;
        if (waitOK) {
            result = response.getResponseBody();
        }
        else {
            System.out.println("timeout, reqId = " + id);
        }

        this.callRepTable.remove(id);
        return result;
    }


    public boolean connect(InetSocketAddress remote) {
        SocketChannel sc = null;
        try {
            sc = SocketChannel.open();
            sc.configureBlocking(true);
            sc.socket().setSoLinger(false, -1);
            sc.socket().setTcpNoDelay(true);

            boolean connected = sc.connect(remote);
            if (connected) {
                sc.configureBlocking(false);
                Connection c = new Connection(sc, this.clientRPCProcessor, null);
                this.connectionList.add(c);
            }
            else {
                sc.close();
            }

            return connected;
        }
        catch (IOException e) {
            if (sc != null) {
                try {
                    sc.close();
                }
                catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }

        return false;
    }


    @Override
    public boolean connect(InetSocketAddress remote, int cnt) {
        int i;

        for (i = 0; i < cnt && this.connect(remote); i++) {
        }

        return i == cnt;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy