BryanCutler commented on a change in pull request #23760: [SPARK-26762][SQL][R]
Arrow optimization for conversion from Spark DataFrame to R DataFrame
URL: https://github.com/apache/spark/pull/23760#discussion_r256223500
##########
File path: sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala
##########
@@ -3198,9 +3199,66 @@ class Dataset[T] private[sql](
}
/**
- * Collect a Dataset as Arrow batches and serve stream to PySpark.
+ * Collect a Dataset as Arrow batches and serve stream to SparkR. It sends
+ * arrow batches in an ordered manner with buffering. This is inevitable
+ * due to missing R API that reads batches from socket directly. See
ARROW-4512.
+ * Eventually, this code should be deduplicated by `collectAsArrowToPython`.
*/
- private[sql] def collectAsArrowToPython(): Array[Any] = {
+ private[sql] def collectAsArrowToR(): Array[Any] = {
+ val timeZoneId = sparkSession.sessionState.conf.sessionLocalTimeZone
+
+ withAction("collectAsArrowToR", queryExecution) { plan =>
+ RRDD.serveToStream("serve-Arrow") { outputStream =>
Review comment:
> For instance, we cannot `read_arrow(socketConn)`
If the Arrow R api follows C++ then there could be a layer of abstraction to
create the reader, e.g. wrap the socket as an
[InputStream](https://github.com/apache/arrow/blob/apache-arrow-0.12.0/r/R/io.R#L148)
This is what I've done in C++, sorry if I knew R a bit better I could tell
you for sure :(
```c++
// Class to wrap a socket as a readable Arrow InputStream
class ArrowStreamClient : public arrow::io::InputStream {
public:
ArrowStreamClient(const std::string& host);
~ArrowStreamClient() override;
arrow::Status Connect();
arrow::Status Close() override;
arrow::Status Tell(int64_t* position) const override;
arrow::Status Read(int64_t nbytes, int64_t* bytes_read, void* out)
override;
arrow::Status Read(int64_t nbytes,
std::shared_ptr<arrow::Buffer>* out) override;
private:
const std::string host_;
int sock_;
int64_t pos_;
};
// Then to use it
auto in_stream_ = std::make_shared<ArrowStreamClient>(dataset()->host_);
socket_stream->Connect());
arrow::ipc::RecordBatchStreamReader::Open(in_stream_.get(), &reader_));
reader_->ReadNext(¤t_batch_));
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]