Package com.alipay.bluewhale.core.drpc

Source Code of com.alipay.bluewhale.core.drpc.Drpc$clearThreadcall

package com.alipay.bluewhale.core.drpc;

import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;

import org.apache.log4j.Logger;
import org.apache.thrift7.TException;

import com.alipay.bluewhale.core.callback.RunnableCallback;
import com.alipay.bluewhale.core.cluster.StormConfig;
import com.alipay.bluewhale.core.utils.AsyncLoopThread;
import com.alipay.bluewhale.core.utils.StormUtils;
import com.alipay.bluewhale.core.utils.TimeUtils;

import backtype.storm.Config;
import backtype.storm.daemon.Shutdownable;
import backtype.storm.generated.DRPCExecutionException;
import backtype.storm.generated.DRPCRequest;

import backtype.storm.generated.*;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.thrift7.protocol.TBinaryProtocol;
import org.apache.thrift7.server.*;
import org.apache.thrift7.transport.TNonblockingServerSocket;
import org.apache.thrift7.transport.TTransportException;

/**
* drpc��ʵ��
* @author yannian
*
*/
public class Drpc implements DistributedRPC.Iface, DistributedRPCInvocations.Iface,Shutdownable{
    private static Logger LOG = Logger.getLogger(Drpc.class);

    public static void main(String[] args) throws TTransportException {
        Map conf=StormConfig.read_storm_config();
        final Drpc service=new Drpc();
        int port =StormUtils.parseInt(conf.get(Config.DRPC_PORT));
        TNonblockingServerSocket socket=new TNonblockingServerSocket(port);
        THsHaServer.Args targs = new THsHaServer.Args(socket);
        targs.workerThreads(64);
        targs.protocolFactory(new TBinaryProtocol.Factory());
        targs.processor(new DistributedRPC.Processor<DistributedRPC.Iface>(service));
       
        final THsHaServer handler_server = new THsHaServer(targs);
       
        int portinvoke =StormUtils.parseInt(conf.get(Config.DRPC_INVOCATIONS_PORT));
        TNonblockingServerSocket socketInvoke=new TNonblockingServerSocket(portinvoke);
        THsHaServer.Args targsInvoke = new THsHaServer.Args(socketInvoke);
        targsInvoke.workerThreads(64);
        targsInvoke.protocolFactory(new TBinaryProtocol.Factory());
        targsInvoke.processor(new DistributedRPCInvocations.Processor<DistributedRPCInvocations.Iface>(service));
       
        final THsHaServer invoke_server = new THsHaServer(targsInvoke);

        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                service.shutdown();
                handler_server.stop();
                invoke_server.stop();
            }

        });
       
        LOG.info("Starting Distributed RPC servers...");
        new Thread(new Runnable() {
            @Override
            public void run() {
                invoke_server.serve();               
            }
        }).start();
        handler_server.serve();
    }
   
    private AtomicInteger ctr=new AtomicInteger(0);
    private ConcurrentHashMap<String,Semaphore> idtoSem=new ConcurrentHashMap<String,Semaphore>();
    private ConcurrentHashMap<String,Object> idtoResult=new ConcurrentHashMap<String,Object>();
    private ConcurrentHashMap<String,Integer> idtoStart=new ConcurrentHashMap<String,Integer>();
    private ConcurrentHashMap<String,ConcurrentLinkedQueue<DRPCRequest>> requestQueues=new ConcurrentHashMap<String,ConcurrentLinkedQueue<DRPCRequest>>();

    private void cleanup(String id)
    {
        LOG.debug("clean id " +id+" @ "+(System.currentTimeMillis()));

  idtoSem.remove(id);
        idtoResult.remove(id);
        idtoStart.remove(id);
    }
   

    AsyncLoopThread clearthread;
    public Drpc()
    {
        clearthread=this.clearThread();
    }
   
    public class clearThreadcall extends RunnableCallback
    {
        private static final int REQUEST_TIMEOUT_SECS=60;
        private static final int TIMEOUT_CHECK_SECS=5;
        private java.util.HashSet<String> lastclean=new HashSet<String>();
        @Override
        public void run() {
            for(String id:this.lastclean)
            {
                Drpc.this.cleanup(id);
            }
           
            java.util.HashSet<String> set=new HashSet<String>();
            for(Entry<String,Integer> e: Drpc.this.idtoStart.entrySet())
            {
                if(TimeUtils.time_delta(e.getValue())>clearThreadcall.REQUEST_TIMEOUT_SECS)
                {
                    String id=e.getKey();
                    Drpc.this.idtoResult.put(id, new DRPCExecutionException("Request timed out"));
                    Semaphore s=Drpc.this.idtoSem.get(id);
                    if(s!=null)
                    {
                        s.release();
                    }
                    set.add(id);
                }
            }
   
            this.lastclean=set;
           
        }
       
        public Object getResult() {
            return clearThreadcall.TIMEOUT_CHECK_SECS;
        }
    }
   
    private AsyncLoopThread clearThread()
    {
       return  new AsyncLoopThread(new clearThreadcall());
    }
   

    @Override
    public String execute(String function, String args)
            throws DRPCExecutionException, TException {
        LOG.debug("Received DRPC request for " +function+ " " +args+ " at " +(System.currentTimeMillis()));
        int idinc=this.ctr.incrementAndGet();
        int maxvalue=1000000000;
        int newid=idinc%maxvalue;
        if(idinc!=newid)
        {
            this.ctr.compareAndSet(idinc, newid);
        }
       
        String strid=String.valueOf(newid);
        Semaphore sem=new Semaphore(0);
       
        DRPCRequest req=new DRPCRequest(args, strid);
        this.idtoStart.put(strid, TimeUtils.current_time_secs());
        this.idtoSem.put(strid, sem);
        ConcurrentLinkedQueue<DRPCRequest> queue=this.acquire_queue(this.requestQueues, function);
        queue.add(req);
        LOG.debug("Waiting for DRPC request for " +function+ " " +args+ " at " +(System.currentTimeMillis()));
        try {
            sem.acquire();
        } catch (InterruptedException e) {
            LOG.error("acquire fail " ,e);
        }
        LOG.debug("Acquired for DRPC request for " +function+ " " +args+ " at " +(System.currentTimeMillis()));

       
        Object result=this.idtoResult.get(strid);
        LOG.debug("Returning for DRPC request for " +function+ " " +args+ " at " +(System.currentTimeMillis()));

        this.cleanup(strid);

        if(result instanceof DRPCExecutionException)
        {
            throw (DRPCExecutionException)result;
        }
        return String.valueOf(result);
    }

    @Override
    public void result(String id, String result) throws TException {
        Semaphore sem =this.idtoSem.get(id);
        LOG.debug("Received result " +result+ " for id " +id+ " at " +(System.currentTimeMillis()));
        if(sem!=null)
        {
            this.idtoResult.put(id,result);
            sem.release();
        }

    }

    @Override
    public DRPCRequest fetchRequest(String functionName) throws TException {

        ConcurrentLinkedQueue<DRPCRequest> queue=this.acquire_queue(this.requestQueues, functionName);
        DRPCRequest req=queue.poll();
        if(req!=null)
        {
            LOG.debug("Fetched request for " +functionName+ " at " +(System.currentTimeMillis()));
            return req;
        }
        return new DRPCRequest("", "");
    }

    @Override
    public void failRequest(String id) throws TException {
        Semaphore sem =this.idtoSem.get(id);
        LOG.debug("failRequest result  for id " +id+ " at " +(System.currentTimeMillis()));
        if(sem!=null)
        {
            this.idtoResult.put(id,new DRPCExecutionException( "Request failed"));
            sem.release();
        }       
    }

    @Override
    public void shutdown() {
        this.clearthread.interrupt();
    }
   

    private ConcurrentLinkedQueue<DRPCRequest> acquire_queue(ConcurrentHashMap<String,ConcurrentLinkedQueue<DRPCRequest>> queues,String function)
    {
            if(!queues.containsKey(function))
            {
                queues.putIfAbsent(function, new ConcurrentLinkedQueue<DRPCRequest>());
            }
            return queues.get(function);
    }
}
TOP

Related Classes of com.alipay.bluewhale.core.drpc.Drpc$clearThreadcall

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.