Hi, On Tue, Jan 8, 2019 at 7:13 PM Gerrit Binnenmars <[email protected]> wrote: > > Hello Pepijn, > > I am a bit concerned by this move. Introducing C++ in the framework makes > Celix no longer a dynamic service framework for C. > I understood the support for C++ in the API, so C++ bundles were supported, > but this is something different.
Note that even if the framework is done is C++, we can still deliver a C API - for the framework and for the services provided by the bundles. It does add a mandatory requirement to a C++(11) compiler and dependency to libstdc++. My concern here is that moving to C++ could (eventually) lead to some bundles only provided/consuming a C++ API and shut out C support. > A lot of effort is put in the code quality and stability of the framework, > does this work need to be done once more? I understand your concern, and yes of course recreating the framework will lead to some stability issues. I started experimenting with a C++ framework for two reasons; 1) I wanted to tryout what features/concepts of C++ we should include in a C++ API to make it more accessible for C++ users and 2) IMO the current implement/design of the Celix framework is flawed and as result we still run into stability issues. Those two issues combined are there reason there is now an experimental C++ branch. Wether we decide to move to C++ or not, I still think we need recreate the celix framework. What if forgot the mention in the previous mail is that in the C++ registry all registration/unregistration and the starting/stopping of trackers are handled in registry and with use of ref counting & async calls (future) to prevent deadlocks in the framework; this is somewhat complex, but manageable. For the current celix implementation this partly done in the framework object, the service registry object and the service tracker object and this combined with (no ref count) handling of services references & service registrations and a lot of entanglement between those objects currently still leads to race condition / dead lock issues. This approach can also be done in C, but requires simple more lines of code ... With the updated C API I also started cutting out some concepts/complexity we IMO do not need (service references, bundle archive, bundle revision, module, service listeners, service listener hooks, framework listener), with the idea to eventually drop those concepts. These concepts are already dropped in the current C++ framework implementation. So moving forward with C or C++ we should IMO (eventually) go for a 3.0 release with a more lean API, implementation and support for bundles as linkable shared objects. And this will lead to some stability issues, but for sure become a more stable and maintainable framework in the end. > > My conclusion: I would prefer to keep the framework as is and concentrate > on adding functionality. > A C++ framework implementation does not bring enough to Celix. Functionally I agree, but it does arguable result in less lines of code framework .. i.e. a better maintainability & productivity. > If you really want to continue this should not go into Celix but in a new > Apache project. I do not agree. Yes it would introduce back incompatibility changes, but that does not make it a different project. > > I am quite curious what the rest of the community thinks. Indeed... > > Gerrit > > > > On Mon, Jan 7, 2019 at 11:19 PM Miroslav Beranič < > [email protected]> wrote: > > > Hi Pepijn, > > > > is there any metric data regarding performance, code size etc - compared C > > and "new" C++? Code size I do not know, but is something we can measure. For performance I assume you mean the overhead of calling services? I have no metric for that .. although that would be nice. In my reasoning as long as you can still provide/consume pointers to C service structs (as with the current Celix framework) for C usage, there is no performance difference. And the goal of the C++ framework should be to still a) support a C API and b) support C service struct. So there should be no change. For C++ usage there will be the overhead of dereferencing the std::shared_ptr and overhead of accessing a std::function / pure abstract C++ interface (i.e. virtual method). > > > > Is there any plan to support other languages ( using language bindings ) ? A C API, conform the current updated (celix_* headers) C API, should IMO be added 'out of the box'. Any other languages you where thinking about? > > > > From my side, I would really like to see C version, but I guess C++ is > > "must have". > > > > Kind Regards, > > Miroslav > > > > > > V V pon., 7. jan. 2019 ob 22:25 je oseba Pepijn Noltes < > > [email protected]> napisala: > > > > > Hi All, > > > > > > The last weeks I put some effort in exploring the benefits and > > > downsides of changing the primary language of Celix from C to C++ in > > > an experimental branch. > > > > > > As you probably already know Celix start around 2010 with the focus on > > > a OSGi implementation in C; following the Java OSGi spec very > > > strictly. And IMO that was correct choice at that time and with our > > > given experience. > > > My current vision is that we should follow the concepts of OSGi and > > > where possible the nomenclature, but focus on delivering a (as much as > > > possible) easy to use dynamic services framework for C/C++. > > > > > > IMO this also means that we should think about moving to C++. Because: > > > a) With the concepts of C++11 we can create a much easier to use and > > > hopefully also easier to develop/maintain framework. > > > b) More type safe > > > c) RAII; which really helps a lot in dealing with volatile services > > > and trying to keep track of which services are still in use. > > > b) C++ is simply more relevant and popular, which should help in > > > getting more traction for Celix. > > > > > > To get the discussion rolling and for me to get a feeling what the > > > effect of moving to C++ would mean, I created C++ experimental (but > > > functionally quite complete) Celix C++ framework [1]. > > > And I would like some feedback/discussion if this is an improvement > > > for Celix or any remarks on the Celix C++ framework implementation. > > > > > > There are a few interesting changes in the approach/design of the C++ > > > framework: > > > 1) There is a separate (static) Registry library [2], which delivers > > > the functionality to register/use/track (and TODO listener hooks) > > > services. This library, by design, can be used without the rest of the > > > framework. I designed the Registry library separate to keep it clean > > > of bundles lifecycle stuff. > > > - ServiceRegistration/ServiceRegistry uses RAII to make it easier > > > in use, specifically for cleanup. > > > - The registry also support registering std::function as services, > > > this seems logical for C++. > > > - The service template argument is used to deduce the service name. > > > - The concept of services versions is dropped. I do think versions > > > on API is important, but more in a distributed environment. In my > > > experience for Celix everything should be build against the same > > > service API's. Playing around with backwards compatibility on binary > > > level with C++ is just reasonable. > > > 2) The framework library [3]. Here the focus in on the BundleContext > > > api so that almost everything can be done through the bundle context > > > api. > > > - It is now also possible to register "static" bundles. These > > > bundles are installed on every created Framework object. This make it > > > possible to register bundles with use a __attribute__((constructor)) > > > decorated function. With support for "static" bundles, bundles can be > > > created as shared objects, which "just work" if you link against them. > > > See the C++ Shell example [4]. IMO this is a much .. much more natural > > > way to handle bundles in a C/C++ environment. > > > - Support for zip bundles and dynamically loaded shared object - with > > > use a the bundle create, start,stop ..etc symbols is still TODO > > > - BundleActivator now work on the constructor/destructor, i.e. also > > > following a RAII approach. > > > - There is no concept of a ServiceReference (same as in the updated C > > > api). > > > 3) Resources can be linked against a shared object and in that way > > > OSGi extender pattern concept can be used without using zip files as > > > bundles. See the C++ Shell implementation as an example (this bundles > > > has a version.properties resource) [5]. > > > 4) For now glog is used as logging framework. > > > 5) libzip is used to handle the zip files. Note that resources linked > > > against the shared object bundles are packed as a zip file. > > > 6) googletest is used for testing. > > > - It is also easier to test bundles, because the test executable > > > "just" has to link against the bundle shared objects to make them > > > available. See the tests of the C++ Shell bundle [5] > > > 7) For now there is no way to export/import (versioned) shared objects > > > from other bundles. I personally do no think this is really needed (I > > > never use it myself). I also think that this should be solved by the > > > language itself (i.e. C++ Modules). > > > 8) As far as I can see it is possible to create a (mostly) backwards > > > compatibility C API from the C++ framework. As long as we only support > > > the updated C API, i.e. the the celix_* headers. > > > > > > The C++ framework API has no documentation yet, please be aware. I do > > > think that it should be clear enough for experience users and the > > > developers, but this is still a TODO. > > > Currently for C++ there is a Registry [2] library, a Framework library > > > [3], a C++ Shell bundle [5], a C++ Shell TUI bundle [6] and a single > > > example executable to run everything [4]. > > > I also took some effort to ensure that the code coverage result are > > > generated and somewhat respectable. > > > > > > My experience thus far is mostly positive. Fewer lines of code are > > > needed (duh), but also (mainly because of RAII) less if else branches > > > are needed / error handling is needed. > > > I do have some trouble arrange the code, because some part need to be > > > in the header (template) or in Impl classes to ensure a more clean > > > user API and the rest is in the sources files. > > > > > > Please feel free to let me know what you think. Note that this is > > > still experimental and we will discuss how to move forward later. > > > > > > [1] feature/cxx branch (for the 807b88 .. commit): > > > > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f > > > [2] registry dir: > > > > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f/libs/registry > > > [3] > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f/libs/framework_cxx > > > [4] > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f/examples/celix-examples/cxx_shell_example > > > [5] > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f/bundles/shell/cxx_shell > > > [6] > > > > > https://github.com/apache/celix/tree/807b88b5bb166e253dc1c517326d2865bc60584f/bundles/shell/cxx_shell_tui > > > > > > > > > Greetings, > > > Pepijn > > > > > > > > > -- > > Miroslav Beranič > > MIBESIS > > +386(0)40/814-843 > > [email protected] > > https://www.mibesis.si > >
