celix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pepijn Noltes <pepijnnol...@gmail.com>
Subject [DISCUSS] new Celix API
Date Tue, 29 May 2018 19:54:12 GMT
Hi All,

A while ago I created a proposal for a v3 Celix API. Since a few week I
have started working on some of the the changes, but adjusted them to keep
close to the OSGI api/nomenclature.
In this thread I would like to explain the changes I made and hope to start
a discussion to see if these change are in line with that we want as a
Celix community.


The API changes are added in new headers so that a) they can coexist with
the current API and b) the headers are not cluttered with two different
styles of API.

The basis premise is that most of the updated API is centred around the
bundle context. The bundle context is (from the OSGI spec) a object that
represents the execution context of a single bundle within the OSGi
framework, and acts as a proxy to the underlying Framework. And as such
should IMO be the primary entry to interact with everything the Celix
framework is offering.

This for example means that now both register and unregistering service is
done through the bundle context, also that setting up and stopping a
service tracker is done though the bundle context, etc.

Some of the more important changes are:

- All the updated APIs are location in the celix_ prefixed headers.

- All public functions in the update API are prefixed with celix_. This is
of course to prevent symbol collisions.

- Explicit locking is prevented by calling useService(s) functions, which
accepts user provided callbacks so that the framework can take care of
locking/race-conditions during the invocation of the callbacks.
Locking is really necessary in Celix to ensure that services cannot be
freed/unloaded if that service is still in use. On the other hand exposing
explicit lock functions or lock types are ugly, cumbersome and error prone.
The updated bundle context API now has useService(s) calls which lets the
users provide a callback. In the callback the framework ensure the locking
and the user can safely use the service - and other arguments - during the
callback.

- More focus on const correctness, specifically in the tracker/use
callbacks.

- Simpler error reporting. Although always returning a int stating if a
error occurred is very clear, it does make the code more verbose and (IMO)
unnatural to read. In most cases the returning type can easily be used to
indicate an error. This is now more often used.

- Less use of pointers. E.g. registering a service now returns a service id
(or <0 if error) instead of a service_registration_t pointer and setting up
a service tracker now return a tracker id (long). This prevents dangling
pointers and reduces the public api.

- Most of the bundle context calls now have a simple call (e.g.
celix_bundleContext_registerService) with a few arguments and a more
complex call which accepts a pointer to a options struct  (e.g.
celix_bundleContext_registerServiceWithOptions). This ensure that the basic
use can be left simple and also ensure that more complex setup are still
readable.

For example something like:
celix_bundleContext_registerServiceComplex(ctx, "service name", NULL, NULL,
props, NULL, "1.2.0");

Can be written as:
celix_service_registrations_options_t opts =
CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
opts.serviceName = "servicename";
opts.properties = props;
opts.serviceLanguage = lang;
celix_bundleContext_registerServiceWithOptions(ctx, &opts);

More verbose, but also more readable.
With the additional benefit that these options struct can be extended in a
(source level) backwards manner.

- Although not a change, but IMO a benefit: Documenting the bundle context
API should help a lot in making the Celix framework more easier to
understand and get started with Celix.



For the code and updated examples see:
- celix_bundle_context.h
https://github.com/apache/celix/blob/3e27acf533a195132934a3a5d6935c95f47c7ea9/libs/framework/include/celix_bundle_context.h
- C bundle example
https://github.com/apache/celix/tree/3e27acf533a195132934a3a5d6935c95f47c7ea9/examples/celix-examples/bundle_example_c
- C services example
https://github.com/apache/celix/tree/3e27acf533a195132934a3a5d6935c95f47c7ea9/examples/celix-examples/services_example_c

Some work is also already done for a C++ api. This is currently a fully
header based implementation, meaning that the installed celix libraries can
be kept pure C, but user
can choose to create bundles in C++. Note that there are still a lot of
TODO and the API is not stable.
For more info see:
- C++ BundleContext
https://github.com/apache/celix/blob/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/libs/framework/include/celix/BundleContext.h
- C++ bundle example
https://github.com/apache/celix/tree/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/examples/celix-examples/bundle_example_cxx
- C++ services example
https://github.com/apache/celix/tree/be6612f0f259cf080fe5ca1f6fbbfa9bb61a502c/examples/celix-examples/services_example_cxx

All in all my hope it that this simplifies to usage of Celix, but at the
same time ensure that we can still support the "old" API for
the foreseeable future.

Any though, comments or no-dont-do-this remarks are welcome.

Greetings,
Pepijn

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message