pnoltes commented on issue #775:
URL: https://github.com/apache/celix/issues/775#issuecomment-2429951856

   Interesting question. 
   
   Yes in many cases I think this can be solved as you mention, but this does 
mean that the service are heavily intertwined. 
   From an abstraction point of view this is not very nice (not a "cohesive" 
interface). 
   
   IMO the C language is missing some async concepts to do this nicely. For C++ 
std::future could be used and the OSGi spec has also something for this [OSGi 
Promise](https://docs.osgi.org/specification/osgi.cmpn/8.1.0/util.promise.html).
 ASF Celix also has a implementation for 
[Promises](https://github.com/apache/celix/tree/rel/celix-2.4.0/libs/promises), 
but only for C++.
   
   Let assume there was also C implementation for this. The instead of a 
callback the provide api could look something like:
   ```
   //provider api
   #include <celix_promise.h>
   
   #define MY_SERVICE_NAME "my_service"
   #define MY_SERVICE_VERSION "1.0.0"
   
   typedef struct my_service {
       void* handle;
       celix_promise_t (*doSomething)(void *handle, const char *input, const 
char *callbackServiceUUID);
   ```
   
   Maybe with promise api like:
   ```
   //celix_promise_factory.h
   
   celix_deferred_t celix_promiseFactory_deferred(celix_promise_factory_t* fac);
   
   //celix_promise.h
   
   celix_promise_onSuccess(celix_promise_t promise, void* data, void 
(*done)(void* data, void* result));
   
   //celix_deferred.h
   celix_promise_t celix_deferred_getPromise(celix_deferred_t deferred);
   void celix_deferred_resolvePromise(celix_deferred_t deferred, void* result);
   void celix_deferred_fail(celix_deferred_t deferred, int error, const char* 
errorMsg);
   ```
   And a separate promise api for a `long`, `double`, `boolean,` void`, and 
`array_list`  promise.
   
   The provider could do something like:
   ```
   celix_promise_t my_service_doSomething(void *handle, const char *input, 
const char *callbackServiceUUID) {
       provider_t *provider = handle;
   
       celix_deferred_t def = celix_promiseFactory_deferred(provider->factory);
       provider->queueAsyncProcessing(def);
       return celix_deferred_getPromise(def);
   }
   ```
   
   And the consumer snippet:
   ```
   void useServiceCallback(void* data, void* result) {
      consumer_t *consumer = handle;
      //handle real result.
   }
   
   void useService(void *handle, void *svc) {
      consumer_t *consumer = handle;
      celix_promise_t promise =  service->doSomething(service->handle, "input", 
"<frameworkUUID>+<service id>");
      celix_arrayList_add(consumer->activePromises, promise);
      celix_promise_onSuccess(promise, consumer, useServiceCallback);
   }
   ```
   
   This also means that the provider is not aware how the consumer will handle 
the (async) result. 
   
   Important concept would be that both the provided and consumer can drop the 
promise/deferred and it should clean itself up. 
   
   But maybe something already exists for this. Because although I like the 
Promise concept, I am not sure if we need a C implementation for this. 
   
   Also this concept then needs to be directly supported in remote services 
(first class citizen) so that the remote service admins can generated 
endpoint/proxies that can handle promise and deferred objects. For Java this is 
also mentioned in the remote service admin spec: 
https://docs.osgi.org/specification/osgi.cmpn/8.1.0/service.remoteservices.html#d0e1444
   
   


-- 
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