Uh oh!
There was an error while loading. Please reload this page.
GH-38309: [C++] build filesystems as separate modules - #39067
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
pitrou
commented
Dec 9, 2023
Ok, so I think we should provide the building blocks for lazy loading of filesystem libraries when a given URI scheme is requested. Something like: // filesystem.{h,cc}using FileSystemFactory = std::function<
Result<std::shared_ptr<FileSystem>>(
const Uri& uri, const io::IOContext& io_context, std::string* out_path)>;
using FileSystemLoader = std::function<Status(const std::string& scheme)>;
Status RegisterFileSystemFactory(std::vector<std::string> schemes,
FileSystemFactory factory);
Status RegisterFileSystemLoader(std::vector<std::string> schemes,
FileSystemLoader loader);
Result<FileSystemLoader> MakeSharedLibraryFileSystemLoader(
std::string library_path, std::string init_function) {
using InitFuncType = Status(*)();
auto loader = [=](const std::string& scheme) -> Status {
ARROW_ASSIGN_OR_RAISE(void* ptr, SharedLibrary::LookupSymbol(library_path, init_symbol));
returnreinterpret_cast<InitFuncType>(ptr)();
};
}
Status RegisterSharedLibraryFileSystemLoader(
std::vector<std::string> schemes,
std::string library_path, std::string init_function) {
ARROW_ASSIGN_OR_RAISE(auto loader,
MakeSharedLibraryFileSystemLoader(std::move(library_path), std::move(init_function)));
returnRegisterFileSystemLoader(std::move(schemes), std::move(loader));
}
// io_util.hclassSharedLibrary {
public:static Result<SharedLibrary> Open(const std::string& path);
Result<void*> LookupSymbol(const std::string& symbol);
static Result<void*> LookupSymbol(const std::string& path, const std::string& symbol) {
ARROW_ASSIGN_OR_RAISE(auto lib, Open(path));
return lib.LookupSymbol(symbol);
}
};And then you can use it such as: // libarrow_s3.so
Status RegisterS3FileSystem() {
returnRegisterFileSystemFactory({"s3"}, &MakeS3FileSystem);
}
// some init code somewhere
Status InitLoadableFileSystems() {
RETURN_NOT_OK(RegisterSharedLibraryFileSystemLoader(
{"s3"}, "libarrow_s3.so", "RegisterS3FileSystem");
// other filesystems here...returnStatus::OK();
}
|
2cca700 to
3e0ebd2Compare3e0ebd2 to
fb82438Compare
I don't think this presents much improvement over using direct factories. The main advantage I see with a FileSystemLoader approach is that initialization code can be run as part of loading the filesystem, including calls to However
|
fb82438 to
8bff100Comparepitrou
commented
Feb 1, 2024
This depends on how |
I agree, but again: customization will not be resident in libarrow.so, and will require instructions like "ensure X before calling FileSystemFromUri". That being the case, I don't think any instructions could be simpler than "ensure the library is loaded before calling FileSystemFromUri". In the specific case of a python package which renames or moves |
bkietz
commented
Feb 2, 2024
In light of the lack of an obvious approach, I think I'll defer support for autoloading for the moment. The main feature of interest is the registry anyway, and adding autoloading will not be more difficult after the registry is defined. |
kou
commented
Feb 4, 2024
It makes sense. |
8bff100 to
abaed2eCompareabaed2e to
f95dc66Compare7f9b201 to
13dfd98CompareUh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Do we need std::move() here?
| std::move(scheme), factory, std::move(finalizer), | |
| std::move(scheme), std::move(factory), std::move(finalizer), |
There was a problem hiding this comment.
We do not since the factory is currently a function pointer instead of a std::function. I guess that could be changed as well for consistency with finalizer
There was a problem hiding this comment.
Ah, OK. I missed the FileSystemFactory definition. (I thought that it's a normal class.)
Then should we remove std::move() for factory here https://github.com/apache/arrow/pull/39067/files#diff-e487db128ea7075182ace948c56f2992b370a10b40d0bceef696becab1c9dabfR808 ?
There was a problem hiding this comment.
I have changed factory to also be a std::function for consistency with finalizer, so the std::move is warranted
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
13dfd98 to
f515a7aComparebkietz
commented
Mar 6, 2024
@github-actions crossbow submit -g cpp -g r -g python -g wheel |
Revision: 4925905ea42d9571f65237603b0acc7547c9730f Submitted crossbow builds: ursacomputing/crossbow @ actions-348ec81e98 |
pitrou
commented
Mar 7, 2024
The |
bkietz
commented
Mar 7, 2024
The failure is in the orc external project. Since orc doesn't depend on arrow I think this must be spurious, and the retry has succeeded. |
pitrou
left a comment
There was a problem hiding this comment.
Starting to look very neat. The remaining comments are minor. Thank you!
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
bkietz
commented
Mar 7, 2024
jorisvandenbossche
commented
Mar 15, 2024
Seems this caused some nightly failures in the minimal C++ builds, see |
After merging your PR, Conbench analyzed the 7 benchmarking runs that have been run so far on merge-commit b235f83. There was 1 benchmark result with an error:
There were no benchmark performance regressions. 🎉 The full Conbench report has more details. It also includes information about 9 possible false positives for unstable benchmarks that are known to sometimes produce them. |
Rationale for this change
Each filesystem implementation carries unique and potentially heavy dependencies, so it'd be useful to build them separately. Furthermore, one typically doesn't need all of them at the same time and building separate modules would allow them to be dynamically loaded as necessary. Finally, defining this interface allows custom filesystem implementations to be supported seamlessly.
What changes are included in this PR?
An initial sketch of a registry, with documentation as if the registry were complete to illustrate intended usage.
Are these changes tested?
A toy module is added and a single unit test too.
Are there any user-facing changes?
Users would be able to add their own filesystem implementations to the registry