5

Futures ではなく CompletionHandler を使用して、vert.x ワーカー バーティクルの AsynchronousSocketChannel に単一の要求/応答を実装しようとしています。vert.x ドキュメントから:

「ワーカー バーティクルが複数のスレッドによって同時に実行されることはありません。」

これが私のコードです(ソケット処理が100%正しいかどうかはわかりません-コメントしてください):

    // ommitted: asynchronousSocketChannel.open, connect ...

    eventBus.registerHandler(address, new Handler<Message<JsonObject>>() {
        @Override
        public void handle(final Message<JsonObject> event) {
            final ByteBuffer receivingBuffer = ByteBuffer.allocateDirect(2048);
            final ByteBuffer sendingBuffer = ByteBuffer.wrap("Foo".getBytes());

            asynchronousSocketChannel.write(sendingBuffer, 0L, new CompletionHandler<Integer, Long>() {
                public void completed(final Integer result, final Long attachment) {
                    if (sendingBuffer.hasRemaining()) {
                        long newFilePosition = attachment + result;
                        asynchronousSocketChannel.write(sendingBuffer, newFilePosition, this);
                    }

                    asynchronousSocketChannel.read(receivingBuffer, 0L, new CompletionHandler<Integer, Long>() {
                        CharBuffer charBuffer = null;
                        final Charset charset = Charset.defaultCharset();
                        final CharsetDecoder decoder = charset.newDecoder();

                        public void completed(final Integer result, final Long attachment) {
                            if (result > 0) {
                                long p = attachment + result;
                                asynchronousSocketChannel.read(receivingBuffer, p, this);
                            }

                            receivingBuffer.flip();

                            try {
                                charBuffer = decoder.decode(receivingBuffer);
                                event.reply(charBuffer.toString()); // pseudo code
                            } catch (CharacterCodingException e) { }


                        }

                        public void failed(final Throwable exc, final Long attachment) { }
                    });
                }

                public void failed(final Throwable exc, final Long attachment) { }
            });
        }
    });

負荷テスト中に多くの ReadPendingException と WritePendingException にヒットしていますが、ハンドル メソッドに一度に 1 つのスレッドしかない場合は少し奇妙に思えます。一度に AsynchronousSocketChannel を処理するスレッドが 1 つしかない場合、読み取りまたは書き込みが完全に完了していない可能性はありますか?

4

1 に答える 1

1

AsynchronousSocketChannel のハンドラーは、ExecutorService の派生物である独自の AsynchronousChannelGroup で実行されます。特別な努力をしない限り、そのハンドラは I/O 操作を開始したコードと並行して実行されます。

バーティクル内で I/O 完了ハンドラーを実行するには、そのバーティクルからハンドラーを作成して登録する必要があります。このハンドラーは、現在 AsynchronousSocketChannel のハンドラーが行っていることを行います。

AsynchronousSocketChannel のハンドラーは、その引数 (結果と添付ファイル) のみをメッセージにパックし、そのメッセージをイベント バスに送信する必要があります。

于 2012-09-14T13:23:01.090 に答える