[ 
https://issues.apache.org/jira/browse/HBASE-16445?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15447835#comment-15447835
 ] 

Duo Zhang commented on HBASE-16445:
-----------------------------------

Let me explain. The first goal is to share code between different rpc 
implementation as much as possible, the second is to revise the lockings.

In general, the flow of an rpc call is
 1. Find or create an connection. There is a lock when fetching or creating 
connection, so we do not setup the real connection to remote at this step.
 2. send the call with this connection. Setup connection if necessary.
 3. Wait for the response of this call.

I added a RpcCallback for the Call object, it will be notified after the call 
finished, normal or exceptional, or cancelled.

For the async callMethod, the exception will be set into the PCRC. And for the 
callBlockingMethod, we just use a BlockingRpcCallback to call the callMethod, 
and rethrow the exception in PCRC if any.

For the locking schema
  1. There is a lock in AbstractRpcClient to protect the fetching or creating 
connection.
  2. There is a lock in Call to make sure that we can only finish the call once.
  3. Same as Call for PCRC. And PCRC, there is another troublesome operation, 
'cancel'. The connection implementation must guarantee that the setup of a call 
will not overlap with a cancel operation. This can be archived by holding a 
lock when register cancelationCallback and setup a call.
  4. There is no forced locking schema for a connection implementation.
  5. For the locking order, the Call and PCRC's lock should be held at last. So 
the callbacks in Call and PCRC should be execute outside the lock in Call and 
PCRC which means the implementations of the callbacks are free to hold any lock.

For AsyncConnection, the locking schema is straight-forward. Most operations 
are executed in the netty handlers so no locking is needed. There is a lock to 
protect the creation and destroy of Channel.

For RpcClientImpl, I just use a big lock to protect every thing. I can find 
some better locking schemas, but the problem is the CallSender thread.The 
locking schema will be completely different with or without a CallSender 
thread. But I think it is OK to optimize it later since in 2.0 the 
AsyncRpcClient is our default rpc implementation. Will finish the optimization 
before backport these stuffs to branch-1.

And I have also opened several issues to commit some individual code in this 
patch to make the patch a little small. See HBASE-16510, HBASE-16516 and 
HBASE-16526.

Thanks [~stack].

> Refactor and reimplement RpcClient
> ----------------------------------
>
>                 Key: HBASE-16445
>                 URL: https://issues.apache.org/jira/browse/HBASE-16445
>             Project: HBase
>          Issue Type: Sub-task
>    Affects Versions: 2.0.0
>            Reporter: Duo Zhang
>            Assignee: Duo Zhang
>             Fix For: 2.0.0
>
>         Attachments: HBASE-16445-v1.patch, HBASE-16445.patch
>
>
> There are lots of common logics between RpcClientImpl and AsyncRpcClient. We 
> should have much less code comparing to the current implementations.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to