Avro used in Flume

Define the interface of RpcClient

  1. public interface RpcClient {
  2. public int getBatchSize();
  3. public void append(Event event) throws EventDeliveryException;
  4. public void appendBatch(List<Event> events) throws
  5. EventDeliveryException;
  6. public void close() throws FlumeException;
  7. }

Define Avro RpcClient extending from RpcClient, using Netty as socket communication.

  1. public class NettyAvroRpcClient extends AbstractRpcClient implements RpcClient {
  2. private Transceiver transceiver;
  3. private AvroSourceProtocol.Callback avroClient;
  4.  
  5. private void connect(long timeout, TimeUnit tu) throws FlumeException {
  6. callTimeoutPool = Executors.newCachedThreadPool(
  7. new TransceiverThreadFactory("Flume Avro RPC Client Call Invoker"));
  8. NioClientSocketChannelFactory socketChannelFactory = null;
  9.  
  10. try {
  11. ExecutorService bossExecutor =
  12. Executors.newCachedThreadPool(new TransceiverThreadFactory(
  13. "Avro " + NettyTransceiver.class.getSimpleName() + " Boss"));
  14. ExecutorService workerExecutor =
  15. Executors.newCachedThreadPool(new TransceiverThreadFactory(
  16. "Avro " + NettyTransceiver.class.getSimpleName() + " I/O Worker"));
  17.  
  18. if (enableDeflateCompression || enableSsl) {
  19. if (maxIoWorkers >= 1) {
  20. socketChannelFactory = new SSLCompressionChannelFactory(
  21. bossExecutor, workerExecutor,
  22. enableDeflateCompression, enableSsl, trustAllCerts,
  23. compressionLevel, truststore, truststorePassword, truststoreType,
  24. excludeProtocols, maxIoWorkers);
  25. } else {
  26. socketChannelFactory = new SSLCompressionChannelFactory(
  27. bossExecutor, workerExecutor,
  28. enableDeflateCompression, enableSsl, trustAllCerts,
  29. compressionLevel, truststore, truststorePassword, truststoreType,
  30. excludeProtocols);
  31. }
  32. } else {
  33. if (maxIoWorkers >= 1) {
  34. socketChannelFactory = new NioClientSocketChannelFactory(
  35. bossExecutor, workerExecutor, maxIoWorkers);
  36. } else {
  37. socketChannelFactory = new NioClientSocketChannelFactory(
  38. bossExecutor, workerExecutor);
  39. }
  40. }
  41.  
  42. transceiver = new NettyTransceiver(this.address,
  43. socketChannelFactory,
  44. tu.toMillis(timeout));
  45. avroClient =
  46. SpecificRequestor.getClient(AvroSourceProtocol.Callback.class,
  47. transceiver);
  48. } catch (Throwable t) {
  49. if (callTimeoutPool != null) {
  50. callTimeoutPool.shutdownNow();
  51. }
  52. if (socketChannelFactory != null) {
  53. socketChannelFactory.releaseExternalResources();
  54. }
  55. if (t instanceof IOException) {
  56. throw new FlumeException(this + ": RPC connection error", t);
  57. } else if (t instanceof FlumeException) {
  58. throw (FlumeException) t;
  59. } else if (t instanceof Error) {
  60. throw (Error) t;
  61. } else {
  62. throw new FlumeException(this + ": Unexpected exception", t);
  63. }
  64. }
  65.  
  66. setState(ConnState.READY);
  67. }
  68.  
  69. }
  1. Define NettyTransceiver to read and write with socket programming
  1. /**
  2. * A Netty-based {@link Transceiver} implementation.
  3. */
  4. public class NettyTransceiver extends Transceiver {
  5. /** If not specified, the default connection timeout will be used (60 sec). */
  6. public static final long DEFAULT_CONNECTION_TIMEOUT_MILLIS = 60 * 1000L;
  7. public static final String NETTY_CONNECT_TIMEOUT_OPTION =
  8. "connectTimeoutMillis";
  9. public static final String NETTY_TCP_NODELAY_OPTION = "tcpNoDelay";
  10. public static final boolean DEFAULT_TCP_NODELAY_VALUE = true;
  11.  
  12. private static final Logger LOG = LoggerFactory.getLogger(NettyTransceiver.class
  13. .getName());
  14.  
  15. private final AtomicInteger serialGenerator = new AtomicInteger(0);
  16. private final Map<Integer, Callback<List<ByteBuffer>>> requests =
  17. new ConcurrentHashMap<Integer, Callback<List<ByteBuffer>>>();
  18.  
  19. private final ChannelFactory channelFactory;
  20. private final long connectTimeoutMillis;
  21. private final ClientBootstrap bootstrap;
  22. private final InetSocketAddress remoteAddr;
  23.  
  24. volatile ChannelFuture channelFuture;
  25. volatile boolean stopping;
  26. private final Object channelFutureLock = new Object();
  27.  
  28. /**
  29. * Read lock must be acquired whenever using non-final state.
  30. * Write lock must be acquired whenever modifying state.
  31. */
  32. private final ReentrantReadWriteLock stateLock = new ReentrantReadWriteLock();
  33. private Channel channel; // Synchronized on stateLock
  34. private Protocol remote; // Synchronized on stateLock
  35.  
  36. NettyTransceiver() {
  37. channelFactory = null;
  38. connectTimeoutMillis = 0L;
  39. bootstrap = null;
  40. remoteAddr = null;
  41. channelFuture = null;
  42. }
  43.  
  44. /**
  45. * Creates a NettyTransceiver, and attempts to connect to the given address.
  46. * {@link #DEFAULT_CONNECTION_TIMEOUT_MILLIS} is used for the connection
  47. * timeout.
  48. * @param addr the address to connect to.
  49. * @throws IOException if an error occurs connecting to the given address.
  50. */
  51. public NettyTransceiver(InetSocketAddress addr) throws IOException {
  52. this(addr, DEFAULT_CONNECTION_TIMEOUT_MILLIS);
  53. }
  54.  
  55. /**
  56. * Creates a NettyTransceiver, and attempts to connect to the given address.
  57. * @param addr the address to connect to.
  58. * @param connectTimeoutMillis maximum amount of time to wait for connection
  59. * establishment in milliseconds, or null to use
  60. * {@link #DEFAULT_CONNECTION_TIMEOUT_MILLIS}.
  61. * @throws IOException if an error occurs connecting to the given address.
  62. */
  63. public NettyTransceiver(InetSocketAddress addr,
  64. Long connectTimeoutMillis) throws IOException {
  65. this(addr, new NioClientSocketChannelFactory(
  66. Executors.newCachedThreadPool(new NettyTransceiverThreadFactory(
  67. "Avro " + NettyTransceiver.class.getSimpleName() + " Boss")),
  68. Executors.newCachedThreadPool(new NettyTransceiverThreadFactory(
  69. "Avro " + NettyTransceiver.class.getSimpleName() + " I/O Worker"))),
  70. connectTimeoutMillis);
  71. }
  72.  
  73. /**
  74. * Creates a NettyTransceiver, and attempts to connect to the given address.
  75. * {@link #DEFAULT_CONNECTION_TIMEOUT_MILLIS} is used for the connection
  76. * timeout.
  77. * @param addr the address to connect to.
  78. * @param channelFactory the factory to use to create a new Netty Channel.
  79. * @throws IOException if an error occurs connecting to the given address.
  80. */
  81. public NettyTransceiver(InetSocketAddress addr, ChannelFactory channelFactory)
  82. throws IOException {
  83. this(addr, channelFactory, buildDefaultBootstrapOptions(null));
  84. }
  85.  
  86. /**
  87. * Creates a NettyTransceiver, and attempts to connect to the given address.
  88. * @param addr the address to connect to.
  89. * @param channelFactory the factory to use to create a new Netty Channel.
  90. * @param connectTimeoutMillis maximum amount of time to wait for connection
  91. * establishment in milliseconds, or null to use
  92. * {@link #DEFAULT_CONNECTION_TIMEOUT_MILLIS}.
  93. * @throws IOException if an error occurs connecting to the given address.
  94. */
  95. public NettyTransceiver(InetSocketAddress addr, ChannelFactory channelFactory,
  96. Long connectTimeoutMillis) throws IOException {
  97. this(addr, channelFactory,
  98. buildDefaultBootstrapOptions(connectTimeoutMillis));
  99. }
  100.  
  101. /**
  102. * Creates a NettyTransceiver, and attempts to connect to the given address.
  103. * It is strongly recommended that the {@link #NETTY_CONNECT_TIMEOUT_OPTION}
  104. * option be set to a reasonable timeout value (a Long value in milliseconds)
  105. * to prevent connect/disconnect attempts from hanging indefinitely. It is
  106. * also recommended that the {@link #NETTY_TCP_NODELAY_OPTION} option be set
  107. * to true to minimize RPC latency.
  108. * @param addr the address to connect to.
  109. * @param channelFactory the factory to use to create a new Netty Channel.
  110. * @param nettyClientBootstrapOptions map of Netty ClientBootstrap options
  111. * to use.
  112. * @throws IOException if an error occurs connecting to the given address.
  113. */
  114. public NettyTransceiver(InetSocketAddress addr, ChannelFactory channelFactory,
  115. Map<String, Object> nettyClientBootstrapOptions) throws IOException {
  116. if (channelFactory == null) {
  117. throw new NullPointerException("channelFactory is null");
  118. }
  119.  
  120. // Set up.
  121. this.channelFactory = channelFactory;
  122. this.connectTimeoutMillis = (Long)
  123. nettyClientBootstrapOptions.get(NETTY_CONNECT_TIMEOUT_OPTION);
  124. bootstrap = new ClientBootstrap(channelFactory);
  125. remoteAddr = addr;
  126.  
  127. // Configure the event pipeline factory.
  128. bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
  129. @Override
  130. public ChannelPipeline getPipeline() throws Exception {
  131. ChannelPipeline p = Channels.pipeline();
  132. p.addLast("frameDecoder", new NettyFrameDecoder());
  133. p.addLast("frameEncoder", new NettyFrameEncoder());
  134. p.addLast("handler", new NettyClientAvroHandler());
  135. return p;
  136. }
  137. });
  138.  
  139. if (nettyClientBootstrapOptions != null) {
  140. LOG.debug("Using Netty bootstrap options: " +
  141. nettyClientBootstrapOptions);
  142. bootstrap.setOptions(nettyClientBootstrapOptions);
  143. }
  144.  
  145. // Make a new connection.
  146. stateLock.readLock().lock();
  147. try {
  148. getChannel();
  149. } finally {
  150. stateLock.readLock().unlock();
  151. }
  152. }
  153.  
  154. /**
  155. * Creates the default options map for the Netty ClientBootstrap.
  156. * @param connectTimeoutMillis connection timeout in milliseconds, or null
  157. * if no timeout is desired.
  158. * @return the map of Netty bootstrap options.
  159. */
  160. private static Map<String, Object> buildDefaultBootstrapOptions(
  161. Long connectTimeoutMillis) {
  162. Map<String, Object> options = new HashMap<String, Object>(2);
  163. options.put(NETTY_TCP_NODELAY_OPTION, DEFAULT_TCP_NODELAY_VALUE);
  164. options.put(NETTY_CONNECT_TIMEOUT_OPTION,
  165. connectTimeoutMillis == null ? DEFAULT_CONNECTION_TIMEOUT_MILLIS :
  166. connectTimeoutMillis);
  167. return options;
  168. }
  169.  
  170. /**
  171. * Tests whether the given channel is ready for writing.
  172. * @return true if the channel is open and ready; false otherwise.
  173. */
  174. private static boolean isChannelReady(Channel channel) {
  175. return (channel != null) &&
  176. channel.isOpen() && channel.isBound() && channel.isConnected();
  177. }
  178.  
  179. /**
  180. * Gets the Netty channel. If the channel is not connected, first attempts
  181. * to connect.
  182. * NOTE: The stateLock read lock *must* be acquired before calling this
  183. * method.
  184. * @return the Netty channel
  185. * @throws IOException if an error occurs connecting the channel.
  186. */
  187. private Channel getChannel() throws IOException {
  188. if (!isChannelReady(channel)) {
  189. // Need to reconnect
  190. // Upgrade to write lock
  191. stateLock.readLock().unlock();
  192. stateLock.writeLock().lock();
  193. try {
  194. if (!isChannelReady(channel)) {
  195. synchronized(channelFutureLock) {
  196. if (!stopping) {
  197. LOG.debug("Connecting to " + remoteAddr);
  198. channelFuture = bootstrap.connect(remoteAddr);
  199. }
  200. }
  201. if (channelFuture != null) {
  202. channelFuture.awaitUninterruptibly(connectTimeoutMillis);
  203.  
  204. synchronized(channelFutureLock) {
  205. if (!channelFuture.isSuccess()) {
  206. throw new IOException("Error connecting to " + remoteAddr,
  207. channelFuture.getCause());
  208. }
  209. channel = channelFuture.getChannel();
  210. channelFuture = null;
  211. }
  212. }
  213. }
  214. } finally {
  215. // Downgrade to read lock:
  216. stateLock.readLock().lock();
  217. stateLock.writeLock().unlock();
  218. }
  219. }
  220. return channel;
  221. }
  222.  
  223. /**
  224. * Closes the connection to the remote peer if connected.
  225. */
  226. private void disconnect() {
  227. disconnect(false, false, null);
  228. }
  229.  
  230. /**
  231. * Closes the connection to the remote peer if connected.
  232. * @param awaitCompletion if true, will block until the close has completed.
  233. * @param cancelPendingRequests if true, will drain the requests map and
  234. * send an IOException to all Callbacks.
  235. * @param cause if non-null and cancelPendingRequests is true, this Throwable
  236. * will be passed to all Callbacks.
  237. */
  238. private void disconnect(boolean awaitCompletion, boolean cancelPendingRequests,
  239. Throwable cause) {
  240. Channel channelToClose = null;
  241. Map<Integer, Callback<List<ByteBuffer>>> requestsToCancel = null;
  242. boolean stateReadLockHeld = stateLock.getReadHoldCount() != 0;
  243.  
  244. synchronized(channelFutureLock) {
  245. if (stopping && channelFuture != null) {
  246. channelFuture.cancel();
  247. }
  248. }
  249. if (stateReadLockHeld) {
  250. stateLock.readLock().unlock();
  251. }
  252. stateLock.writeLock().lock();
  253. try {
  254. if (channel != null) {
  255. if (cause != null) {
  256. LOG.debug("Disconnecting from " + remoteAddr, cause);
  257. }
  258. else {
  259. LOG.debug("Disconnecting from " + remoteAddr);
  260. }
  261. channelToClose = channel;
  262. channel = null;
  263. remote = null;
  264. if (cancelPendingRequests) {
  265. // Remove all pending requests (will be canceled after relinquishing
  266. // write lock).
  267. requestsToCancel =
  268. new ConcurrentHashMap<Integer, Callback<List<ByteBuffer>>>(requests);
  269. requests.clear();
  270. }
  271. }
  272. } finally {
  273. if (stateReadLockHeld) {
  274. stateLock.readLock().lock();
  275. }
  276. stateLock.writeLock().unlock();
  277. }
  278.  
  279. // Cancel any pending requests by sending errors to the callbacks:
  280. if ((requestsToCancel != null) && !requestsToCancel.isEmpty()) {
  281. LOG.debug("Removing " + requestsToCancel.size() + " pending request(s).");
  282. for (Callback<List<ByteBuffer>> request : requestsToCancel.values()) {
  283. request.handleError(
  284. cause != null ? cause :
  285. new IOException(getClass().getSimpleName() + " closed"));
  286. }
  287. }
  288.  
  289. // Close the channel:
  290. if (channelToClose != null) {
  291. ChannelFuture closeFuture = channelToClose.close();
  292. if (awaitCompletion && (closeFuture != null)) {
  293. closeFuture.awaitUninterruptibly(connectTimeoutMillis);
  294. }
  295. }
  296. }
  297.  
  298. /**
  299. * Netty channels are thread-safe, so there is no need to acquire locks.
  300. * This method is a no-op.
  301. */
  302. @Override
  303. public void lockChannel() {
  304.  
  305. }
  306.  
  307. /**
  308. * Netty channels are thread-safe, so there is no need to acquire locks.
  309. * This method is a no-op.
  310. */
  311. @Override
  312. public void unlockChannel() {
  313.  
  314. }
  315.  
  316. public void close() {
  317. try {
  318. // Close the connection:
  319. stopping = true;
  320. disconnect(true, true, null);
  321. } finally {
  322. // Shut down all thread pools to exit.
  323. channelFactory.releaseExternalResources();
  324. }
  325. }
  326.  
  327. @Override
  328. public String getRemoteName() throws IOException {
  329. stateLock.readLock().lock();
  330. try {
  331. return getChannel().getRemoteAddress().toString();
  332. } finally {
  333. stateLock.readLock().unlock();
  334. }
  335. }
  336.  
  337. /**
  338. * Override as non-synchronized method because the method is thread safe.
  339. */
  340. @Override
  341. public List<ByteBuffer> transceive(List<ByteBuffer> request)
  342. throws IOException {
  343. try {
  344. CallFuture<List<ByteBuffer>> transceiverFuture = new CallFuture<List<ByteBuffer>>();
  345. transceive(request, transceiverFuture);
  346. return transceiverFuture.get();
  347. } catch (InterruptedException e) {
  348. LOG.debug("failed to get the response", e);
  349. return null;
  350. } catch (ExecutionException e) {
  351. LOG.debug("failed to get the response", e);
  352. return null;
  353. }
  354. }
  355.  
  356. @Override
  357. public void transceive(List<ByteBuffer> request,
  358. Callback<List<ByteBuffer>> callback) throws IOException {
  359. stateLock.readLock().lock();
  360. try {
  361. int serial = serialGenerator.incrementAndGet();
  362. NettyDataPack dataPack = new NettyDataPack(serial, request);
  363. requests.put(serial, callback);
  364. writeDataPack(dataPack);
  365. } finally {
  366. stateLock.readLock().unlock();
  367. }
  368. }
  369.  
  370. @Override
  371. public void writeBuffers(List<ByteBuffer> buffers) throws IOException {
  372. stateLock.readLock().lock();
  373. try {
  374. writeDataPack(
  375. new NettyDataPack(serialGenerator.incrementAndGet(), buffers));
  376. } finally {
  377. stateLock.readLock().unlock();
  378. }
  379. }
  380.  
  381. /**
  382. * Writes a NettyDataPack, reconnecting to the remote peer if necessary.
  383. * NOTE: The stateLock read lock *must* be acquired before calling this
  384. * method.
  385. * @param dataPack the data pack to write.
  386. * @throws IOException if an error occurs connecting to the remote peer.
  387. */
  388. private void writeDataPack(NettyDataPack dataPack) throws IOException {
  389. getChannel().write(dataPack);
  390. }
  391.  
  392. @Override
  393. public List<ByteBuffer> readBuffers() throws IOException {
  394. throw new UnsupportedOperationException();
  395. }
  396.  
  397. @Override
  398. public Protocol getRemote() {
  399. stateLock.readLock().lock();
  400. try {
  401. return remote;
  402. } finally {
  403. stateLock.readLock().unlock();
  404. }
  405. }
  406.  
  407. @Override
  408. public boolean isConnected() {
  409. stateLock.readLock().lock();
  410. try {
  411. return remote!=null;
  412. } finally {
  413. stateLock.readLock().unlock();
  414. }
  415. }
  416.  
  417. @Override
  418. public void setRemote(Protocol protocol) {
  419. stateLock.writeLock().lock();
  420. try {
  421. this.remote = protocol;
  422. } finally {
  423. stateLock.writeLock().unlock();
  424. }
  425. }
  426.  
  427. /**
  428. * Avro client handler for the Netty transport
  429. */
  430. class NettyClientAvroHandler extends SimpleChannelUpstreamHandler {
  431.  
  432. @Override
  433. public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e)
  434. throws Exception {
  435. if (e instanceof ChannelStateEvent) {
  436. LOG.debug(e.toString());
  437. ChannelStateEvent cse = (ChannelStateEvent)e;
  438. if ((cse.getState() == ChannelState.OPEN) && (Boolean.FALSE.equals(cse.getValue()))) {
  439. // Server closed connection; disconnect client side
  440. LOG.debug("Remote peer " + remoteAddr + " closed connection.");
  441. disconnect(false, true, null);
  442. }
  443. }
  444. super.handleUpstream(ctx, e);
  445. }
  446.  
  447. @Override
  448. public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e)
  449. throws Exception {
  450. // channel = e.getChannel();
  451. super.channelOpen(ctx, e);
  452. }
  453.  
  454. @Override
  455. public void messageReceived(ChannelHandlerContext ctx, final MessageEvent e) {
  456. NettyDataPack dataPack = (NettyDataPack)e.getMessage();
  457. Callback<List<ByteBuffer>> callback = requests.get(dataPack.getSerial());
  458. if (callback==null) {
  459. throw new RuntimeException("Missing previous call info");
  460. }
  461. try {
  462. callback.handleResult(dataPack.getDatas());
  463. } finally {
  464. requests.remove(dataPack.getSerial());
  465. }
  466. }
  467.  
  468. @Override
  469. public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
  470. disconnect(false, true, e.getCause());
  471. }
  472.  
  473. }
  474.  
  475. /**
  476. * Creates threads with unique names based on a specified name prefix.
  477. */
  478. private static class NettyTransceiverThreadFactory implements ThreadFactory {
  479. private final AtomicInteger threadId = new AtomicInteger(0);
  480. private final String prefix;
  481.  
  482. /**
  483. * Creates a NettyTransceiverThreadFactory that creates threads with the
  484. * specified name.
  485. * @param prefix the name prefix to use for all threads created by this
  486. * ThreadFactory. A unique ID will be appended to this prefix to form the
  487. * final thread name.
  488. */
  489. public NettyTransceiverThreadFactory(String prefix) {
  490. this.prefix = prefix;
  491. }
  492.  
  493. @Override
  494. public Thread newThread(Runnable r) {
  495. Thread thread = new Thread(r);
  496. thread.setName(prefix + " " + threadId.incrementAndGet());
  497. return thread;
  498. }
  499. }
  500. }

Use proxy as RpcClient

SpecificRequestor.getClient(AvroSourceProtocol.Callback.class,transceiver)

  1. public class SpecificRequestor extends Requestor implements InvocationHandler {
  2. /** Create a proxy instance whose methods invoke RPCs. */
  3. @SuppressWarnings("unchecked")
  4. public static <T> T getClient(Class<T> iface, Transceiver transciever,
  5. SpecificData data)
  6. throws IOException {
  7. Protocol protocol = data.getProtocol(iface);
  8. return (T)Proxy.newProxyInstance
  9. (data.getClassLoader(),
  10. new Class[] { iface },
  11. new SpecificRequestor(protocol, transciever, data));
  12. }
  13.  
  14. /** Create a proxy instance whose methods invoke RPCs. */
  15. @SuppressWarnings("unchecked")
  16. public static <T> T getClient(Class<T> iface, SpecificRequestor requestor)
  17. throws IOException {
  18. return (T)Proxy.newProxyInstance(requestor.data.getClassLoader(),
  19. new Class[] { iface }, requestor);
  20. }
  21. /** Create a proxy instance whose methods invoke RPCs. */
  22. public static <T> T getClient(Class<T> iface, Transceiver transciever)
  23. throws IOException {
  24. return getClient(iface, transciever,
  25. new SpecificData(iface.getClassLoader()));
  26. }
  27. @Override
  28. public Object invoke(Object proxy, Method method, Object[] args)
  29. throws Throwable {
  30. try {
  31. // Check if this is a callback-based RPC:
  32. Type[] parameterTypes = method.getParameterTypes();
  33. if ((parameterTypes.length > 0) &&
  34. (parameterTypes[parameterTypes.length - 1] instanceof Class) &&
  35. Callback.class.isAssignableFrom(((Class<?>)parameterTypes[parameterTypes.length - 1]))) {
  36. // Extract the Callback from the end of of the argument list
  37. Object[] finalArgs = Arrays.copyOf(args, args.length - 1);
  38. Callback<?> callback = (Callback<?>)args[args.length - 1];
  39. request(method.getName(), finalArgs, callback);
  40. return null;
  41. }
  42. else {
  43. return request(method.getName(), args);
  44. }
  45. } catch (Exception e) {
  46. // Check if this is a declared Exception:
  47. for (Class<?> exceptionClass : method.getExceptionTypes()) {
  48. if (exceptionClass.isAssignableFrom(e.getClass())) {
  49. throw e;
  50. }
  51. }
  52.  
  53. // Next, check for RuntimeExceptions:
  54. if (e instanceof RuntimeException) {
  55. throw e;
  56. }
  57.  
  58. // Not an expected Exception, so wrap it in AvroRemoteException:
  59. throw new AvroRemoteException(e);
  60. }
  61. }
  62.  
  63. }

Request method to remote

  1. /** Writes a request message and returns the result through a Callback. */
  2. <T> void request(Request request, Callback<T> callback)
  3. throws Exception {
  4. Transceiver t = getTransceiver();
  5. if (!t.isConnected()) {
  6. // Acquire handshake lock so that only one thread is performing the
  7. // handshake and other threads block until the handshake is completed
  8. handshakeLock.lock();
  9. try {
  10. if (t.isConnected()) {
  11. // Another thread already completed the handshake; no need to hold
  12. // the write lock
  13. handshakeLock.unlock();
  14. } else {
  15. CallFuture<T> callFuture = new CallFuture<T>(callback);
  16. t.transceive(request.getBytes(),
  17. new TransceiverCallback<T>(request, callFuture));
  18. // Block until handshake complete
  19. callFuture.await();
  20. if (request.getMessage().isOneWay()) {
  21. Throwable error = callFuture.getError();
  22. if (error != null) {
  23. if (error instanceof Exception) {
  24. throw (Exception) error;
  25. } else {
  26. throw new AvroRemoteException(error);
  27. }
  28. }
  29. }
  30. return;
  31. }
  32. } finally{
  33. if (handshakeLock.isHeldByCurrentThread()) {
  34. handshakeLock.unlock();
  35. }
  36. }
  37. }
  38.  
  39. if (request.getMessage().isOneWay()) {
  40. t.lockChannel();
  41. try {
  42. t.writeBuffers(request.getBytes());
  43. if (callback != null) {
  44. callback.handleResult(null);
  45. }
  46. } finally {
  47. t.unlockChannel();
  48. }
  49. } else {
  50. t.transceive(request.getBytes(),
  51. new TransceiverCallback<T>(request, callback));
  52. }
  53.  
  54. }

Now look at avro protocl

  1. @org.apache.avro.specific.AvroGenerated
  2. public interface AvroSourceProtocol {
  3. public static final org.apache.avro.Protocol PROTOCOL = org.apache.avro.Protocol.parse("{\"protocol\":\"AvroSourceProtocol\",\"namespace\":\"org.apache.flume.source.avro\",\"doc\":\"* Licensed to the Apache Software Foundation (ASF) under one\\n * or more contributor license agreements. See the NOTICE file\\n * distributed with this work for additional information\\n * regarding copyright ownership. The ASF licenses this file\\n * to you under the Apache License, Version 2.0 (the\\n * \\\"License\\\"); you may not use this file except in compliance\\n * with the License. You may obtain a copy of the License at\\n *\\n * http://www.apache.org/licenses/LICENSE-2.0\\n *\\n * Unless required by applicable law or agreed to in writing,\\n * software distributed under the License is distributed on an\\n * \\\"AS IS\\\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\n * KIND, either express or implied. See the License for the\\n * specific language governing permissions and limitations\\n * under the License.\",\"types\":[{\"type\":\"enum\",\"name\":\"Status\",\"symbols\":[\"OK\",\"FAILED\",\"UNKNOWN\"]},{\"type\":\"record\",\"name\":\"AvroFlumeEvent\",\"fields\":[{\"name\":\"headers\",\"type\":{\"type\":\"map\",\"values\":\"string\"}},{\"name\":\"body\",\"type\":\"bytes\"}]}],\"messages\":{\"append\":{\"request\":[{\"name\":\"event\",\"type\":\"AvroFlumeEvent\"}],\"response\":\"Status\"},\"appendBatch\":{\"request\":[{\"name\":\"events\",\"type\":{\"type\":\"array\",\"items\":\"AvroFlumeEvent\"}}],\"response\":\"Status\"}}}");
  4. org.apache.flume.source.avro.Status append(org.apache.flume.source.avro.AvroFlumeEvent event) throws org.apache.avro.AvroRemoteException;
  5. org.apache.flume.source.avro.Status appendBatch(java.util.List<org.apache.flume.source.avro.AvroFlumeEvent> events) throws org.apache.avro.AvroRemoteException;
  6.  
  7. @SuppressWarnings("all")
  8. public interface Callback extends AvroSourceProtocol {
  9. public static final org.apache.avro.Protocol PROTOCOL = org.apache.flume.source.avro.AvroSourceProtocol.PROTOCOL;
  10. void append(org.apache.flume.source.avro.AvroFlumeEvent event, org.apache.avro.ipc.Callback<org.apache.flume.source.avro.Status> callback) throws java.io.IOException;
  11. void appendBatch(java.util.List<org.apache.flume.source.avro.AvroFlumeEvent> events, org.apache.avro.ipc.Callback<org.apache.flume.source.avro.Status> callback) throws java.io.IOException;
  12. }
  13. }

Avro-RPC client in Flume的更多相关文章

  1. 又一个半成品库 weblog rpc client

    我基本上属于半成品专业户,去看我的github就知道. 下午又撸了一个weblog rpc client库,而这又一次证明了一个有技术但没有产品能力的程序员是没有卵用的. 因为当做好了库的雏形,但与具 ...

  2. 用NFS挂载root出现:NFS: failed to create MNT RPC client, status=-101(-110)

      2014-02-18 08:06:17 By Ly #Linux 阅读(78) 评论(0) 错误信息如下: Root-NFS: nfsroot=/home/zenki/nfs/rootfs NFS ...

  3. Thrift-RPC client in Flume

    Get RpcClient from RpcClientFactory with Reflection programming Message or Event definition in Flum ...

  4. Python自动化之rabbitmq rpc client端代码分析(原创)

    RPC调用client端解析 import pika import uuid # 建立连接 class FibonacciRpcClient(object): def __init__(self): ...

  5. Avro RPC 之 Protocol 定义和代码生成

    摘自http://avro.apache.org/docs/current/spec.html#Protocol+Declaration,1.7.6版 Protocol Declaration Avr ...

  6. Flume的Avro Sink和Avro Source研究之二 : Avro Sink

    啊,AvroSink要复杂好多:< 好吧,先确定主要问题: AvroSink为啥这么多代码?有必要吗?它都有哪些逻辑需要实现? 你看,avro-rpc-quickstart里是这么建client ...

  7. 【翻译】Flume 1.8.0 User Guide(用户指南) Processors

    翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...

  8. Hadoop生态圈-Flume的主流Sinks源配置

    Hadoop生态圈-Flume的主流Sinks源配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是配置的是Flume主流的Sinks,想要了解更详细的配置信息请参考官 ...

  9. Flume实战案例运维篇

    Flume实战案例运维篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Flume概述 1>.什么是Flume Flume是一个分布式.可靠.高可用的海量日志聚合系统,支 ...

随机推荐

  1. Sql server inner join......on

    --查询的时候,如果表中有重名的列,此时,应该在通过 表名.列名 的方式来限定指定的列是哪张表中的.select PhoneNum.pid, PhoneNum.pname, PhoneNum.pcel ...

  2. js 自定义属性

     html标签中有没有什么自带的属性可以存储成绩的----没有  本身html标签没有这个属性,自己(程序员)添加的,----自定义属性---为了存储一些数据  在html标签中添加的自定义属性,如果 ...

  3. Jmeter HTTPS接口测试的证书导入

    HTTP和HTTPS测试时稍有不同,HTTPS需要加载证书,端口也不一样,操作如下: 1. 下载被测网址证书导入 测试时用的是谷歌浏览器 生成.cer后缀的文件 2. 把导出的证书转换成.store格 ...

  4. Django-admin 的使用

    admin 组件的使用 Django 提供功能十分强大的后台管理组件 admin 来实现自动管理. admin 是一个组件,与 APP 一样,项目启动一开始就加载了.在 setting.py 中的 I ...

  5. FLUENT 流体计算应用教程

    温正 清华大学出版 2013.1                                          子谓颜渊曰,用之则行,舍之则藏,惟我与尔有是夫!         非常合适的一本书. ...

  6. 剑指offer——面试题7:重建二叉树

    // 面试题7:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1, // 2, ...

  7. python 获取子目录下的所有文件的路径

    import os pathss=[] for root, dirs, files in os.walk(tarpath): path = [os.path.join(root, name) for ...

  8. Mastering the Game of Go 论文阅读笔记

    主要思想:用状态评估减少搜索深度,用动作采样减少搜索宽度. 参考文献:https://blog.csdn.net/songrotek/article/details/51065143

  9. GreenPlum 大数据平台--运维(二)

    .如何获取查询运行时和已用时间. 例子: Select tstart, tfinish, (tfinish-tstart) as total_time, trim(query_text) from q ...

  10. (转)IPC相关的命令

    IPC相关的命令 原文:http://www.cnblogs.com/jjzd/p/6773090.html 进程间通信概述 进程间通信有如下的目的: 1.数据传输,一个进程需要将它的数据发送给另一个 ...