Environment / core / correct way of switching to Epoll

Hello!
Java SDK 2.3.1 / 1.3.1

[285…293]@https://github.com/couchbase/couchbase-jvm-core/blob/master/src/main/java/com/couchbase/client/core/env/DefaultCoreEnvironment.java

    if (builder.ioPool == null) {
        this.ioPool = new NioEventLoopGroup(ioPoolSize(), new DefaultThreadFactory("cb-io", true));
        this.ioPoolShutdownHook = new IoPoolShutdownHook(this.ioPool);
    } else {
        this.ioPool = builder.ioPool;
        this.ioPoolShutdownHook = builder.ioPoolShutdownHook == null
                ? new NoOpShutdownHook()
                : builder.ioPoolShutdownHook;
    }

I would like to switch to Epoll leaving other env-params with their default values, so:

            final EpollEventLoopGroup elg = 
                    new EpollEventLoopGroup(
                        DefaultCouchbaseEnvironment.IO_POOL_SIZE, 
                        new DefaultThreadFactory("cb-io", true)
                    );
            final ShutdownHook hook = 
                    new IoPoolShutdownHook(elg);
            ce = DefaultCouchbaseEnvironment
                    .builder()
                        .ioPool(elg, hook)
                    .build();

Is it a “correct switching to epoll” or i need to do something more ?

Yup, your Epoll code looks about right. You can also take a look how we conditionally enable it in the YCSB client for example: https://github.com/brianfrankcooper/YCSB/blob/master/couchbase2/src/main/java/com/yahoo/ycsb/db/couchbase2/Couchbase2Client.java#L193

Oh and don’t forget to shut it down manually during teardown since you are passing it from the outside we don’t own it and as a result don’t automatically shut it down.

@daschl,
are you sure about need in shutdown ? From https://github.com/couchbase/couchbase-jvm-core/blob/master/src/main/java/com/couchbase/client/core/env/resources/IoPoolShutdownHook.java i suppose that hook shuts ELG being called from “somewhere” (?):

public IoPoolShutdownHook(EventLoopGroup ioPool) {
    this.ioPool = ioPool;
    this.shutdown = false;
}
public Observable<Boolean> shutdown() {
    return Observable.create(new Observable.OnSubscribe<Boolean>() {
        @Override
        public void call(final Subscriber<? super Boolean> subscriber) {
            ioPool.shutdownGracefully(0, 10, TimeUnit.MILLISECONDS)
                .addListener(new GenericFutureListener() {
                @Override
                public void operationComplete(final Future future) throws Exception {
                    if (!subscriber.isUnsubscribed()) {
                        try {
                            if (future.isSuccess()) {
                                subscriber.onNext(true);
                                shutdown = true;
                                subscriber.onCompleted();
                            } else {
                                subscriber.onError(future.cause());
                            }
                        } catch (Exception ex) {
                            subscriber.onError(ex);
                        }
                    }
                }
            });
        }
    });
}

Oh sorry I didn’t say it clearly: if you provide the shutdown hook we’ll shut it down for you, but if you use it in other places as well don’t set a shutdown hook and shut it down on your own… for example if you share the group with some other code then it might make sense to defer shutdown until that other component is clean as well.

Ok, thanks, i got it!

1 Like