peterxcli commented on code in PR #11356:
URL: https://github.com/apache/ozone/pull/11356#discussion_r4192673719


##########
hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/transport/server/ratis/ContainerStateMachine.java:
##########
@@ -740,6 +742,33 @@ void streamPutBlock(ContainerCommandRequestProto request) 
throws IOException {
     dispatchCommand(request, context);
   }
 
+  /**
+   * Commit a PutBlock sent as a command in the middle of a data stream;
+   * see {@link StateMachine.DataStream#onCommand(ByteBuffer, long)}.
+   * The PutBlock is applied without a Raft log entry, so it has no log index 
to use as bcsId.
+   *
+   * @return the serialized {@link ContainerCommandResponseProto},
+   *         which is identical on all the peers of the pipeline.
+   */
+  ByteBuffer streamCommand(ByteBuffer command) throws IOException {

Review Comment:
   nit: wish we can refactor container SM and local stream, so we dont need to 
pass function as lambda. one reference-only refactor is -- `LocalStream` 
becomes the one place that handles a PutBlock arriving on the stream.
   
   ```java
   public class ContainerStateMachine extends BaseStateMachine {
       // ...
        CompletableFuture<DataStream> stream(RaftClientRequest request) {
          init = toProto(request);
          dispatchCommand(init, streamInitContext());          // StreamInit, 
checks the token for init's block
          channel = (KeyValueStreamDataChannel) 
dispatcher.getStreamDataChannel(init);   // no callback parameter
          return new LocalStream(channel, getChunkExecutor(init), init,
              dispatcher, getGroupId(), container2BCSIDMap);
        }
        
        CompletableFuture<?> link(DataStream stream, LogEntryProto entry) {
          return ((LocalStream) stream).link();               // V3: fails 
unless the close PutBlock was committed
        }
   ```
   
   ```java
   class LocalStream implements StateMachine.DataStream {
     KeyValueStreamDataChannel channel;
     DataChannel dataChannel;           // what Ratis writes to and closes
     BlockID blockID;                   // the block the stream was opened for
     ContainerDispatcher dispatcher; RaftGroupId groupId; Map<Long, Long> 
container2BCSIDMap; Executor executor;
   
     LocalStream(channel, executor, init, dispatcher, groupId, 
container2BCSIDMap) {
       blockID = init.getWriteChunk().getBlockID();
       dataChannel = init.getCmdType() == StreamInitWithPutBlock
           ? new PutBlockOnClose()      // V3: commit the trailing PutBlock at 
close
           : channel;                   // V2: the channel drops the trailing 
PutBlock (HDDS-12007)
     }
   
     DataChannel getDataChannel() { return dataChannel; }
   
     // PutBlock in the middle of the stream (flush / hsync)
     CompletableFuture<ByteBuffer> onCommand(ByteBuffer command, long offset) {
       return supplyAsync(() -> {
         channel.drainBuffers();
         return 
putBlock(toProto(command)).toByteString().asReadOnlyByteBuffer();
       }, executor);
     }
   
     // The single place that commits a PutBlock received on the stream
     private ContainerCommandResponseProto 
putBlock(ContainerCommandRequestProto request) {
       require request.getCmdType() == PutBlock;
       require blockIdOf(request) == blockID;
       context = DispatcherContext.newBuilder(Op.STREAM_PUT_BLOCK)
           
.setStage(COMBINED).setContainer2BCSIDMap(container2BCSIDMap).build();
       response = dispatcher.dispatch(request, context);
       if (response.getResult() != SUCCESS) {
         throw new StorageContainerException(response.getMessage(), 
response.getResult());
       }
       return response;
     }
   
     // Ratis closes the stream through getDataChannel().close()
     private class PutBlockOnClose implements DataChannel {
       write(b)  -> channel.write(b);
       force(m)  -> channel.force(m);
       isOpen()  -> channel.isOpen();
       close() {
         trailing = channel.closeAndReadPutBlock();   // writes the remaining 
data
         putBlock(trailing);                          // throws on failure, so 
the stream close fails
         channel.setLinked();
       }
     }
   
     CompletableFuture<?> link() { /* checks from ContainerStateMachine.link() 
*/ }
     cleanUp(), getExecutor()   // unchanged
   }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to