|
19 | 19 |
|
20 | 20 | import java.io.Closeable;
|
21 | 21 | import java.io.IOException;
|
| 22 | +import java.net.BindException; |
22 | 23 | import java.net.InetSocketAddress;
|
| 24 | +import java.net.ServerSocket; |
23 | 25 | import java.security.SecureRandom;
|
24 | 26 | import java.util.concurrent.ConcurrentHashMap;
|
25 | 27 | import java.util.concurrent.ConcurrentMap;
|
@@ -61,54 +63,91 @@ public class RpcServer implements Closeable {
|
61 | 63 | private static final SecureRandom RND = new SecureRandom();
|
62 | 64 |
|
63 | 65 | private final String address;
|
64 |
| - private final Channel channel; |
| 66 | + private Channel channel; |
65 | 67 | private final EventLoopGroup group;
|
66 | 68 | private final int port;
|
67 | 69 | private final ConcurrentMap<String, ClientInfo> pendingClients;
|
68 | 70 | private final RSCConf config;
|
69 |
| - |
| 71 | + private final int DEFAULT_RETRY=10; |
| 72 | + |
| 73 | + |
70 | 74 | public RpcServer(RSCConf lconf) throws IOException, InterruptedException {
|
71 | 75 | this.config = lconf;
|
72 | 76 | this.group = new NioEventLoopGroup(
|
73 |
| - this.config.getInt(RPC_MAX_THREADS), |
74 |
| - Utils.newDaemonThreadFactory("RPC-Handler-%d")); |
75 |
| - this.channel = new ServerBootstrap() |
76 |
| - .group(group) |
77 |
| - .channel(NioServerSocketChannel.class) |
78 |
| - .childHandler(new ChannelInitializer<SocketChannel>() { |
79 |
| - @Override |
80 |
| - public void initChannel(SocketChannel ch) throws Exception { |
81 |
| - SaslServerHandler saslHandler = new SaslServerHandler(config); |
82 |
| - final Rpc newRpc = Rpc.createServer(saslHandler, config, ch, group); |
83 |
| - saslHandler.rpc = newRpc; |
84 |
| - |
85 |
| - Runnable cancelTask = new Runnable() { |
86 |
| - @Override |
87 |
| - public void run() { |
88 |
| - LOG.warn("Timed out waiting for hello from client."); |
89 |
| - newRpc.close(); |
90 |
| - } |
91 |
| - }; |
92 |
| - saslHandler.cancelTask = group.schedule(cancelTask, |
93 |
| - config.getTimeAsMs(RPC_CLIENT_HANDSHAKE_TIMEOUT), |
94 |
| - TimeUnit.MILLISECONDS); |
95 |
| - } |
96 |
| - }) |
97 |
| - .option(ChannelOption.SO_BACKLOG, 1) |
98 |
| - .option(ChannelOption.SO_REUSEADDR, true) |
99 |
| - .childOption(ChannelOption.SO_KEEPALIVE, true) |
100 |
| - .bind(0) |
101 |
| - .sync() |
102 |
| - .channel(); |
| 77 | + this.config.getInt(RPC_MAX_THREADS), |
| 78 | + Utils.newDaemonThreadFactory("RPC-Handler-%d")); |
| 79 | + int portNumber=config.getInt(LAUNCHER_PORT); |
| 80 | + for(int tries = 0 ; tries<DEFAULT_RETRY ; tries++){ |
| 81 | + try { |
| 82 | + this.channel=createChannel(portNumber, tries); |
| 83 | + break; |
| 84 | + }catch(BindException e){ |
| 85 | + LOG.warn("RPC not able to connect port "+ portNumber); |
| 86 | + portNumber = portNumber +1; |
| 87 | + } |
| 88 | + } |
| 89 | + |
103 | 90 | this.port = ((InetSocketAddress) channel.localAddress()).getPort();
|
104 | 91 | this.pendingClients = new ConcurrentHashMap<>();
|
105 |
| - |
| 92 | + LOG.warn("Connected to the port " + this.port); |
106 | 93 | String address = config.get(RPC_SERVER_ADDRESS);
|
107 | 94 | if (address == null) {
|
108 | 95 | address = config.findLocalAddress();
|
109 | 96 | }
|
110 | 97 | this.address = address;
|
111 | 98 | }
|
| 99 | + |
| 100 | + /** |
| 101 | + * If user set the port number by livy.rsc.launcher.port then use that |
| 102 | + * @param portNumber : Provided by the user |
| 103 | + * @return |
| 104 | + * @throws IOException |
| 105 | + * @throws InterruptedException |
| 106 | + */ |
| 107 | + public Channel createChannel(int portNumber,int tries) throws IOException, InterruptedException{ |
| 108 | + if(portNumber==-1) { |
| 109 | + return getChannel(0); |
| 110 | + } |
| 111 | + else { |
| 112 | + return getChannel(config.getInt(LAUNCHER_PORT) + tries ); |
| 113 | + } |
| 114 | + } |
| 115 | + |
| 116 | + /** |
| 117 | + * @throws InterruptedException |
| 118 | + * |
| 119 | + */ |
| 120 | + public Channel getChannel(int portNumber) throws BindException, InterruptedException{ |
| 121 | + Channel channel = new ServerBootstrap() |
| 122 | + .group(group) |
| 123 | + .channel(NioServerSocketChannel.class) |
| 124 | + .childHandler(new ChannelInitializer<SocketChannel>() { |
| 125 | + @Override |
| 126 | + public void initChannel(SocketChannel ch) throws Exception { |
| 127 | + SaslServerHandler saslHandler = new SaslServerHandler(config); |
| 128 | + final Rpc newRpc = Rpc.createServer(saslHandler, config, ch, group); |
| 129 | + saslHandler.rpc = newRpc; |
| 130 | + |
| 131 | + Runnable cancelTask = new Runnable() { |
| 132 | + @Override |
| 133 | + public void run() { |
| 134 | + LOG.warn("Timed out waiting for hello from client."); |
| 135 | + newRpc.close(); |
| 136 | + } |
| 137 | + }; |
| 138 | + saslHandler.cancelTask = group.schedule(cancelTask, |
| 139 | + config.getTimeAsMs(RPC_CLIENT_HANDSHAKE_TIMEOUT), |
| 140 | + TimeUnit.MILLISECONDS); |
| 141 | + } |
| 142 | + }) |
| 143 | + .option(ChannelOption.SO_BACKLOG, 1) |
| 144 | + .option(ChannelOption.SO_REUSEADDR, true) |
| 145 | + .childOption(ChannelOption.SO_KEEPALIVE, true) |
| 146 | + .bind(portNumber) |
| 147 | + .sync() |
| 148 | + .channel(); |
| 149 | + return channel; |
| 150 | + } |
112 | 151 |
|
113 | 152 | /**
|
114 | 153 | * Tells the RPC server to expect connections from clients.
|
@@ -310,3 +349,4 @@ private ClientInfo(String id, String secret, ClientCallback callback) {
|
310 | 349 | }
|
311 | 350 |
|
312 | 351 | }
|
| 352 | + |
0 commit comments