use of org.apache.twill.common.Cancellable in project cdap by caskdata.
the class NettyRouter method startServer.
private Cancellable startServer(final ServerBootstrap serverBootstrap, final ChannelGroup channelGroup) throws Exception {
// Start listening on ports.
Map<Integer, String> serviceMap = new HashMap<>();
for (Map.Entry<String, Integer> forward : serviceToPortMap.entrySet()) {
int port = forward.getValue();
String service = forward.getKey();
String boundService = serviceLookup.getService(port);
if (boundService != null) {
LOG.warn("Port {} is already configured to service {}, ignoring forward for service {}", port, boundService, service);
continue;
}
InetSocketAddress bindAddress = new InetSocketAddress(hostname, port);
LOG.info("Starting Netty Router for service {} on address {}...", service, bindAddress);
try {
Channel channel = serverBootstrap.bind(bindAddress).sync().channel();
channelGroup.add(channel);
InetSocketAddress boundAddress = (InetSocketAddress) channel.localAddress();
serviceMap.put(boundAddress.getPort(), service);
// Update service map
serviceLookup.updateServiceMap(serviceMap);
LOG.info("Started Netty Router for service {} on address {}.", service, boundAddress);
} catch (Exception e) {
if ((Throwables.getRootCause(e) instanceof BindException)) {
throw new ServiceBindException("Router", hostname.getCanonicalHostName(), port, e);
}
throw e;
}
}
return new Cancellable() {
@Override
public void cancel() {
List<Future<?>> futures = new ArrayList<>();
futures.add(channelGroup.close());
futures.add(serverBootstrap.config().group().shutdownGracefully(0, 5, TimeUnit.SECONDS));
futures.add(serverBootstrap.config().childGroup().shutdownGracefully(0, 5, TimeUnit.SECONDS));
for (Future<?> future : futures) {
future.awaitUninterruptibly();
}
}
};
}
use of org.apache.twill.common.Cancellable in project cdap by caskdata.
the class LocalStreamService method createSizeAggregator.
/**
* Create a new aggregator for the {@code streamId}, and add it to the existing map of {@link Cancellable}
* {@code aggregators}. This method does not cancel previously existing aggregator associated to the
* {@code streamId}.
*
* @param streamId stream name to create a new aggregator for
* @param baseCount stream size from which to start aggregating
* @param threshold notification threshold after which to publish a notification - in MB
* @return the created {@link StreamSizeAggregator}
*/
private StreamSizeAggregator createSizeAggregator(StreamId streamId, long baseCount, int threshold) {
// Handle threshold changes
final Cancellable thresholdSubscription = getStreamCoordinatorClient().addListener(streamId, new StreamPropertyListener() {
@Override
public void thresholdChanged(StreamId streamId, int threshold) {
StreamSizeAggregator aggregator = aggregators.get(streamId);
while (aggregator == null) {
Thread.yield();
aggregator = aggregators.get(streamId);
}
aggregator.setStreamThresholdMB(threshold);
}
});
StreamSizeAggregator newAggregator = new StreamSizeAggregator(streamId, baseCount, threshold, thresholdSubscription);
aggregators.put(streamId, newAggregator);
return newAggregator;
}
use of org.apache.twill.common.Cancellable in project cdap by caskdata.
the class DistributedStreamService method createSizeAggregator.
/**
* Create a new aggregator for the {@code streamId}, and add it to the existing map of {@link Cancellable}
* {@code aggregators}. This method does not cancel previously existing aggregator associated to the
* {@code streamId}.
*
* @param streamId stream Id to create a new aggregator for
* @param baseCount stream size from which to start aggregating
* @param threshold notification threshold after which to publish a notification - in MB
* @return the created {@link StreamSizeAggregator}
*/
private StreamSizeAggregator createSizeAggregator(StreamId streamId, long baseCount, int threshold) {
LOG.debug("Creating size aggregator for stream {} with baseCount {} and threshold {}", streamId, baseCount, threshold);
// Handle threshold changes
final Cancellable thresholdSubscription = getStreamCoordinatorClient().addListener(streamId, new StreamPropertyListener() {
@Override
public void thresholdChanged(StreamId streamId, int threshold) {
StreamSizeAggregator aggregator = aggregators.get(streamId);
while (aggregator == null) {
Thread.yield();
aggregator = aggregators.get(streamId);
}
aggregator.setStreamThresholdMB(threshold);
}
});
StreamSizeAggregator newAggregator = new StreamSizeAggregator(streamId, baseCount, threshold, thresholdSubscription);
newAggregator.init();
aggregators.put(streamId, newAggregator);
return newAggregator;
}
use of org.apache.twill.common.Cancellable in project cdap by caskdata.
the class InMemoryElectionTest method testElection.
@Test(timeout = 5000)
public void testElection() throws ExecutionException, InterruptedException, BrokenBarrierException {
final InMemoryElectionRegistry electionRegistry = new InMemoryElectionRegistry();
ExecutorService executor = Executors.newCachedThreadPool();
// Create 5 participants to join leader election process simultaneously
int participantCount = 5;
final CyclicBarrier barrier = new CyclicBarrier(participantCount + 1);
final Semaphore leaderSem = new Semaphore(0);
final Semaphore followerSem = new Semaphore(0);
final CountDownLatch[] stopLatch = new CountDownLatch[participantCount];
try {
final AtomicInteger currentLeader = new AtomicInteger(-1);
for (int i = 0; i < participantCount; i++) {
stopLatch[i] = new CountDownLatch(1);
final int idx = i;
executor.submit(new Runnable() {
@Override
public void run() {
try {
barrier.await();
Cancellable cancel = electionRegistry.join("test", new ElectionHandler() {
@Override
public void leader() {
currentLeader.set(idx);
leaderSem.release();
}
@Override
public void follower() {
followerSem.release();
}
});
stopLatch[idx].await(10, TimeUnit.SECONDS);
cancel.cancel();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
});
}
// Sync the joining
barrier.await();
// There should be 1 leader and 4 followers
leaderSem.tryAcquire(10, TimeUnit.SECONDS);
followerSem.tryAcquire(participantCount - 1, 10, TimeUnit.SECONDS);
// Continuously stopping leader until there is one left.
for (int i = 0; i < participantCount - 1; i++) {
stopLatch[currentLeader.get()].countDown();
// Each time when the leader is unregistered from the leader election, a new leader would rise and
// the old leader would become a follower.
leaderSem.tryAcquire(10, TimeUnit.SECONDS);
followerSem.tryAcquire(10, TimeUnit.SECONDS);
}
// Withdraw the last leader, it'd become follower as well.
stopLatch[currentLeader.get()].countDown();
followerSem.tryAcquire(10, TimeUnit.SECONDS);
} finally {
executor.shutdown();
executor.awaitTermination(5L, TimeUnit.SECONDS);
}
}
use of org.apache.twill.common.Cancellable in project cdap by caskdata.
the class KafkaTester method getPublishedMessages.
public <T> Map<Integer, T> getPublishedMessages(String topic, Set<Integer> partitions, int expectedNumMsgs, final Function<FetchedMessage, T> converter) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(expectedNumMsgs);
final CountDownLatch stopLatch = new CountDownLatch(1);
final Map<Integer, T> actual = new HashMap<>();
KafkaConsumer.Preparer preparer = kafkaClient.getConsumer().prepare();
for (int partition : partitions) {
preparer.addFromBeginning(topic, partition);
}
Cancellable cancellable = preparer.consume(new KafkaConsumer.MessageCallback() {
@Override
public long onReceived(Iterator<FetchedMessage> messages) {
long offset = 0L;
while (messages.hasNext()) {
FetchedMessage message = messages.next();
actual.put(message.getTopicPartition().getPartition(), converter.apply(message));
latch.countDown();
offset = message.getNextOffset();
}
return offset;
}
@Override
public void finished() {
stopLatch.countDown();
}
});
Assert.assertTrue(String.format("Expected %d messages but found %d messages", expectedNumMsgs, actual.size()), latch.await(15, TimeUnit.SECONDS));
cancellable.cancel();
Assert.assertTrue(stopLatch.await(15, TimeUnit.SECONDS));
return actual;
}
Aggregations