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

Reply via email to