pnoltes commented on PR #627: URL: https://github.com/apache/celix/pull/627#issuecomment-2111057796
> **Services** The next topic I wanted to approach is services. When using a service a bundle calls the function of another bundle. Both bundles need to agree upon the the API of the service and also on the ABI of the service. In my eyes the Celix Rust API should be safe to use for the user. This means it should not be possible to cause undefined behaviour without using unsafe code in Rust. But we can not enforce during compilation that the API and ABI of the service we want to use is the same as we think it is. > > So I think we have two options here: > > 1. Using a service is inherently unsafe and invariants must be upheld by the user. For C and C++ services this will probably be the only solution, so using these services from Rust will allways be unsafe. However for Rust services I think there is another way! First of, my complements about taking API **and** ABI compatibility into account. For C and C++ we currently only support source compatibility, so everything should be build with the same compiler using the same sources (include service interface headers). But the idea to do some API compatibility checking is not new. Apache Celix also has a [`libffi` library](https://github.com/apache/celix/tree/master/libs/dfi) (recently updated for stability and documentation). An idea back when libffi was first created, was to use the `libclang` to parse C service interface headers to create descriptors (small and easy parseable files describing C structures and interfaces). Note: using libclang as lib and not necessary also using the clang compiler. And then adding these generated dfi descriptors in bundle zips to that they can be referred to during service registration and service usage. The Celix framework could then use these descriptors and libffi to check compatibility. I still think this would be a very welcome addition to Apache Celix, but I would still require significant effort to develop, test and make user friendly. > > 2. Checking ABI and API compatibility at runtime. If we can achieve this, using a service is safe, incompatible ABI/API would not cause undefined behaviour, returning an Error would be enough. > > > **How can we achieve ABI and API checks at runtime?** There is one Rust crate that already tries to deal with this issue. Only a very small part of the Rust API is already stable. Most part of the API is allowed to change between compiler versions but also between different compiler runs. [abi_stable](https://docs.rs/abi_stable/latest/abi_stable/) provides ABI stability by transforming Rust types with unstable ABI into types with a stable ABI (#[repr(C)]) types. It utilizes the Rust procedural macro system for this which can transform abstract syntax trees into other abstract syntax trees. To get API stability the crate provides type information of these types, which can be checked at runtime. To make sure that the API and ABI of the abi_stable crate is compatible a static variable is provided which can also be checked against at runtime. > > I think we can utilize this crate to provide safe services. I have a short look at abi_stable and mainly looked for the license. Maybe I missing something, but I could not find under which license the code is provided. But this does indeed sound like a good addition for runtime compatibility checking. > > **How could this look like?** A service would be an object that implements a trait (the service interface). This is similar to C++ services. The trait is defined in an Service API crate. The bundle that provides the service statically links against this API crate. When registering this service a pointer to the bundle-static type information and abi_stable library information is stored in the framework (for that it is necessary to implement one or two functions that are only usable internally by the Celix Rust API). > > When another bundle now wants to use the service it must statically link against the API crate as well. When using the service it is checked that the type information and abi_stable library information are compatible. > > **Additional opportunities** It would be great if we could use Rust services from C and C++. For this the Service API crate must export some C/C++ header files. Luckily there is a crate that already does this: [cglue](https://docs.rs/cglue/latest/cglue/). On top of that it is compatible and works together with abi_stable. This makes it possible to easily create services that are usable from C, C++ and Rust and provide additional guaranties. > Nice, I will have a deeper look into this. Currently when combining C and C++, it possible to use C service in C++ but not the other way around. If rust service can be more flexible that would be great. -- 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: dev-unsubscr...@celix.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org