Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jetcd use only one event-loop thread #1297

Open
Wackerle opened this issue Jan 9, 2024 · 7 comments
Open

jetcd use only one event-loop thread #1297

Wackerle opened this issue Jan 9, 2024 · 7 comments

Comments

@Wackerle
Copy link

Wackerle commented Jan 9, 2024

Versions

  • etcd: 3.4.10
  • jetcd: 0.7.7
  • java: 1.8

Describe the bug
There is only one event-loop thread, which may cause performance and other problems.

To Reproduce
Code:

    public void test1() throws InterruptedException {
        System.out.println("test start in thread: " + Thread.currentThread().getName());
        for (int i = 0; i < 10; i++) {
            getResponse("key" + i);
        }
        Thread.sleep(5000);
        System.out.println("test end in thread: " + Thread.currentThread().getName());
    }

    private void getResponse(String key) {
        client.getKVClient()
            .get(ByteSequence.from(key, StandardCharsets.UTF_8))
            .whenComplete((getResponse, throwable) -> System.out
                .println("getResponse in thread: " + Thread.currentThread().getName()));
    }

Result:

test start in thread: main
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
getResponse in thread: vert.x-eventloop-thread-0
test end in thread: main

Similar problem here

Expected behavior
The number of event-loop threads should be the number of CPU cores * 2.

Additional context

@Wackerle Wackerle changed the title ![4985d2dc4047978c23612eb594cdf93](https://user-images.githubusercontent.com/20184263/195269630-f8206f9f-0452-40bd-80c5-a468a0b35e72.png) jetcd use only one event-loop thread Jan 9, 2024
@Wackerle
Copy link
Author

This is the code source of the problem I found.

When the jetcd creates a managedChannel for the first time, the vertx related methods are used.(io.etcd.jetcd.impl.ClientConnectionManager#getChannel)

    ManagedChannel getChannel() {
        if (managedChannel == null) {
            synchronized (lock) {
                if (managedChannel == null) {
                    managedChannel = defaultChannelBuilder().build();
                }
            }
        }

        return managedChannel;
    }

The implementation of the build method is as follows(io.vertx.grpc.VertxChannelBuilder#build):

  public ManagedChannel build() {
    // some code
    return builder
      .eventLoopGroup(context.nettyEventLoop())
      .channelFactory(transport.channelFactory(false))
      .executor(command -> {
      if (Context.isOnEventLoopThread()) {
        context.dispatch(event -> command.run());
      } else {
        command.run();
      }
    }).build();
  }

This code(.eventLoopGroup(context.nettyEventLoop())) causes grpc and netty to use only one eventloop thread.

I haven't figured out why vertx is doing this yet. But I wonder why jetcd switched from grpc to vertx? Or if there's something we're using incorrectly?

@lburgazzoli
Copy link
Collaborator

But I wonder why jetcd switched from grpc to vertx?

This had to do with maintenance, as I'm almost the only contributor left, I had to make some decision and switch to vert.x helped me to reduce some boilerplate and maintenance troubles.

Or if there's something we're using incorrectly?

Any help to figure it out would be really appreciated.

@barryzhang-cloud
Copy link

Is this issu solved? I have the same problem

@lburgazzoli
Copy link
Collaborator

@barryzhang-cloud no it is not, any help would be very appreciated

@Wackerle
Copy link
Author

Wackerle commented Apr 1, 2024

I suspect that there is a problem with the way jetcd integrates vert.x-grpc. So I asked for help in the vert.x user group, but no response. So I don't have any other ideas.

@lburgazzoli
Copy link
Collaborator

lburgazzoli commented Aug 16, 2024

@Wackerle any update ?
@vietj could maybe you help here ?

@cnz101
Copy link

cnz101 commented Nov 26, 2024

Jetcd-core-0.7. X changes grpc to vertx, which results in the change from multi-thread to single-thread operation such as add-delete read-write monitor which involves jetcd, it is easy to cause a single-thread exception jam, resulting in jetcd is not available.Will you fix shi problem?
version

  1. jetcd 0.7.7
  2. jdk 1.8

reproduce:

@Override
    public Map<String, String> gets(String key) throws EtcdOperationException {
        try {
            GetOption option = getGetOption(key);
            GetResponse response = kvClient().get(EtcdUtils.from(key), option).get();  // pending here
            List<KeyValue> keyValueList = response.getKvs();
            if (CollectionUtils.isEmpty(keyValueList)) {
                return Collections.emptyMap();
            }
            return keyValueList.stream()
                .collect(Collectors.toMap(kv -> EtcdUtils.to(kv.getKey()), kv -> EtcdUtils.to(kv.getValue())));
        } catch (InterruptedException | ExecutionException e) {
            throw new EtcdOperationException(e.getMessage());
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants