[
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)