Skip to content

Commit b2d8cca

Browse files
authored
Don't panic if a whole read isn't consumed (#167)
1 parent 5551a47 commit b2d8cca

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

rust/src/hdfs/block_reader.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -222,25 +222,36 @@ impl ReplicatedBlockStream {
222222
))
223223
}
224224

225+
async fn get_next_packet(
226+
connection: &mut DatanodeConnection,
227+
checksum_info: Option<ReadOpChecksumInfoProto>,
228+
) -> Result<(PacketHeaderProto, Bytes)> {
229+
let packet = connection.read_packet().await?;
230+
let header = packet.header;
231+
Ok((header, packet.get_data(&checksum_info)?))
232+
}
233+
225234
fn start_packet_listener(
226235
mut connection: DatanodeConnection,
227236
checksum_info: Option<ReadOpChecksumInfoProto>,
228237
sender: Sender<Result<(PacketHeaderProto, Bytes)>>,
229238
) -> JoinHandle<Result<DatanodeConnection>> {
230239
tokio::spawn(async move {
231240
loop {
232-
let packet = connection.read_packet().await?;
233-
let header = packet.header;
234-
let data = packet.get_data(&checksum_info)?;
235-
236-
// If the packet is empty it means it's the last packet
237-
// so tell the DataNode the read was a success and finish this task
238-
if data.is_empty() {
241+
let next_packet = Self::get_next_packet(&mut connection, checksum_info).await;
242+
if next_packet.as_ref().is_ok_and(|(_, data)| data.is_empty()) {
243+
// If the packet is empty it means it's the last packet
244+
// so tell the DataNode the read was a success and finish this task
239245
connection.send_read_success().await?;
240246
break;
241247
}
242248

243-
sender.send(Ok((header, data))).await.unwrap();
249+
if sender.send(next_packet).await.is_err() {
250+
// The block reader was dropped, so just kill the listener
251+
return Err(HdfsError::DataTransferError(
252+
"Reader was dropped without consuming all data".to_string(),
253+
));
254+
}
244255
}
245256
Ok(connection)
246257
})

0 commit comments

Comments
 (0)