-
Notifications
You must be signed in to change notification settings - Fork 444
RATIS-2546. Add input stream to DataStreamApi for read operations in Client #1481
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
Open
peterxcli
wants to merge
17
commits into
apache:master
Choose a base branch
from
peterxcli:RATIS-2546-stream-read-client
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
bd30f51
RATIS-2560
peterxcli 357cb71
stream client handling
peterxcli b8298ee
Merge branch 'master' into RATIS-2546-stream-read-client
peterxcli 65e6b83
open another thread for blocking sm write
peterxcli 1d3b322
Merge branch 'master' into RATIS-2546-stream-read-client
peterxcli 28f4055
Merge branch 'master' into RATIS-2546-stream-read-client
peterxcli 7a37daf
upd
peterxcli 962623d
Merge branch 'master' into RATIS-2546-stream-read-client
peterxcli 3a06f77
handle the bytebuf release for bytebuf reply
peterxcli bbbd445
minor
peterxcli e8527fc
Observer API
peterxcli 3cb6794
refactor
peterxcli 7b15a13
DataStreamClientImpl idempotent close
peterxcli 23dacc3
refactor
peterxcli 6ec28a9
refactor
peterxcli d693fbd
refactor test
peterxcli 4906624
Add RC for readAsync reply and extract inner class
peterxcli File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
ratis-client/src/main/java/org/apache/ratis/client/api/DataStreamInput.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.ratis.client.api; | ||
|
|
||
| import org.apache.ratis.protocol.DataStreamReply; | ||
| import org.apache.ratis.util.ReferenceCountedObject; | ||
|
|
||
| import java.io.Closeable; | ||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| /** | ||
| * An asynchronous input stream supporting zero buffer copying. | ||
| */ | ||
| public interface DataStreamInput extends Closeable { | ||
| /** | ||
| * Read the next chunk in the stream asynchronously. | ||
| * The caller owns the returned {@link DataStreamReply} which is a {@link ReferenceCountedObject}. | ||
| * It must call {@link ReferenceCountedObject#release()} after consuming it. | ||
| * | ||
| * @return a future of the reference-counted reply. | ||
| */ | ||
| CompletableFuture<ReferenceCountedObject<DataStreamReply>> readAsync(); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
ratis-client/src/main/java/org/apache/ratis/client/impl/DataStreamInputImpl.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.ratis.client.impl; | ||
|
|
||
| import org.apache.ratis.client.DataStreamClientRpc; | ||
| import org.apache.ratis.client.api.DataStreamInput; | ||
| import org.apache.ratis.datastream.DataStreamObserver; | ||
| import org.apache.ratis.datastream.impl.DataStreamRequestByteBuffer; | ||
| import org.apache.ratis.io.StandardWriteOption; | ||
| import org.apache.ratis.proto.RaftProtos.DataStreamPacketHeaderProto.Type; | ||
| import org.apache.ratis.protocol.ClientId; | ||
| import org.apache.ratis.protocol.DataStreamReply; | ||
| import org.apache.ratis.protocol.DataStreamRequestHeader; | ||
| import org.apache.ratis.protocol.RaftClientRequest; | ||
| import org.apache.ratis.protocol.exceptions.AlreadyClosedException; | ||
| import org.apache.ratis.util.JavaUtils; | ||
| import org.apache.ratis.util.ReferenceCountedObject; | ||
|
|
||
| import java.io.EOFException; | ||
| import java.nio.ByteBuffer; | ||
| import java.util.LinkedList; | ||
| import java.util.Objects; | ||
| import java.util.Queue; | ||
| import java.util.concurrent.CompletableFuture; | ||
|
|
||
| final class DataStreamInputImpl implements DataStreamInput, | ||
| DataStreamObserver<ReferenceCountedObject<DataStreamReply>> { | ||
| private final RaftClientRequest header; | ||
| private final ClientId clientId; | ||
| private final Queue<ReferenceCountedObject<DataStreamReply>> replies = new LinkedList<>(); | ||
| private final Queue<CompletableFuture<ReferenceCountedObject<DataStreamReply>>> pendingReads = new LinkedList<>(); | ||
|
|
||
| /* | ||
| * null : the stream is open. | ||
| * AlreadyClosedException: the stream is closed. | ||
| * Other exception : the stream is failed. | ||
| */ | ||
| private Throwable readException; | ||
|
|
||
| DataStreamInputImpl(DataStreamClientRpc dataStreamClientRpc, RaftClientRequest request) { | ||
| this.header = request; | ||
| this.clientId = request.getClientId(); | ||
| final ByteBuffer buffer = ClientProtoUtils.toRaftClientRequestProtoByteBuffer(header); | ||
| final DataStreamRequestHeader h = new DataStreamRequestHeader(clientId, Type.STREAM_HEADER, | ||
| header.getCallId(), 0, buffer.remaining(), StandardWriteOption.FLUSH, StandardWriteOption.CLOSE); | ||
| dataStreamClientRpc.streamAsync(new DataStreamRequestByteBuffer(h, buffer), this) | ||
| .whenComplete(asWhenCompleteBiConsumer()); | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized void onNext(ReferenceCountedObject<DataStreamReply> reply) { | ||
| if (readException != null) { | ||
| return; | ||
| } | ||
|
|
||
| reply.retain(); | ||
| for (CompletableFuture<ReferenceCountedObject<DataStreamReply>> pending; | ||
| (pending = pendingReads.poll()) != null; ) { | ||
| if (pending.complete(reply)) { | ||
| return; | ||
| } | ||
| } | ||
| replies.add(reply); | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized void onError(Throwable throwable) { | ||
| // An error case, release the replies | ||
| releaseReplies(); | ||
| if (readException == null) { | ||
| readException = throwable; | ||
| failPendingReads(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized void onCompleted() { | ||
| // Not an error case, do not release the replies | ||
| if (readException == null) { | ||
| // No more onNext(), the pending reads cannot be completed. | ||
| readException = new EOFException(clientId + ": end of stream, request=" + header); | ||
| failPendingReads(); | ||
| } | ||
| } | ||
|
|
||
| private void releaseReplies() { | ||
| for (ReferenceCountedObject<DataStreamReply> reply; (reply = replies.poll()) != null; ) { | ||
| reply.release(); | ||
| } | ||
| } | ||
|
|
||
| private void failPendingReads() { | ||
| Objects.requireNonNull(readException, "readException == null"); | ||
| for (CompletableFuture<ReferenceCountedObject<DataStreamReply>> p; (p = pendingReads.poll()) != null; ) { | ||
| p.completeExceptionally(readException); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized CompletableFuture<ReferenceCountedObject<DataStreamReply>> readAsync() { | ||
| final ReferenceCountedObject<DataStreamReply> reply = replies.poll(); | ||
| if (reply != null) { | ||
| return CompletableFuture.completedFuture(reply); | ||
| } | ||
| if (readException != null) { | ||
| return JavaUtils.completeExceptionally(readException); | ||
| } | ||
| final CompletableFuture<ReferenceCountedObject<DataStreamReply>> f = | ||
| new CompletableFuture<>(); | ||
| pendingReads.add(f); | ||
| return f; | ||
| } | ||
|
|
||
| @Override | ||
| public synchronized void close() { | ||
| // When close() is called the first time, we set | ||
| // (1) release all replies | ||
| // (2) set readException to AlreadyClosedException | ||
| // (3) complete all pendingReads, and | ||
| releaseReplies(); | ||
| if (readException == null) { | ||
| readException = new AlreadyClosedException(clientId + ": stream already closed, request=" + header); | ||
| failPendingReads(); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
ratis-common/src/main/java/org/apache/ratis/datastream/DataStreamObserver.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.ratis.datastream; | ||
|
|
||
| import java.util.function.BiConsumer; | ||
|
|
||
| /** An interface similar to gRPC {@link org.apache.ratis.thirdparty.io.grpc.stub.StreamObserver}. */ | ||
| public interface DataStreamObserver<V> { | ||
| void onNext(V value); | ||
|
|
||
| void onCompleted(); | ||
|
|
||
| void onError(Throwable throwable); | ||
|
|
||
| default <T> BiConsumer<T, Throwable> asWhenCompleteBiConsumer() { | ||
| return (v, throwable) -> { | ||
| if (throwable != null) { | ||
| onError(throwable); | ||
| } else { | ||
| onCompleted(); | ||
| } | ||
| }; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about else? Is that possible other instances are passed here? If no maybe add an assertion, otherwise handle other instances?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two classes implement the
DataStreamReply, which isDataStreamReplyByteBufandDataStreamReplyByteBuffer.And only
DataStreamReplyByteBufneed to release the Netty byteBuffer reference countratis/ratis-common/src/main/java/org/apache/ratis/datastream/impl/DataStreamPacketByteBuf.java
Lines 58 to 63 in 3cb6794