Hi,

On 16 June 2016 at 05:41, Cedric BAIL <cedric.b...@free.fr> wrote:

> Hello,
>
> Ok, I am giving up on this. We will make it an eo object, but not an
> eolian one as it should be a native type for any binding (It is sure
> that C++, Lua and JS will have to do a manual binding for it) as there
> is very little case were inheritance make sense on promise and
> wouldn't at the same time break binding. eina_promise_owner will
> become eo_promise and eina_promise will become eo_future (to follow
> C++ naming convention). Not to sure how to limit the interface exposed
> by a return type as we don't want the user of the API to access the
> promise API, just the future one. Double object would be annoying, but
> is likely the only solution. So if we want to be safe, we will need to
> use 2 objects per promise. One facing the user of the API and one used
> by the producer of the API. If we don't want to be safe, we can merge
> both API and just use inheritance. So returning an eo_future interface
> in the API, while in fact eo_promise function would work on it.
>
> On Mon, Jun 13, 2016 at 7:23 PM, Jean-Philippe André <j...@videolan.org>
> wrote:
> > On 14 June 2016 at 02:28, Felipe Magno de Almeida <
> > felipe.m.alme...@gmail.com> wrote:
> >> Sorry for top-posting. But let me summarize the Promise lifetime:
>
<snip>

> >>
> >> Eina_Promise* p = ...;
> >> eina_promise_all(p, ...);
> >> // promise will be deleted
> >> // when callback for the then is called
> >
> > So my understanding here is that this can work because a promise can not
> > ever be synchronous.
> > In other words, eina_promise_then can never trigger the success/error
> > callback to be called synchronously, otherwise the above reference count
> > system falls apart.
> >
> > While this approach is convenient, it means that we can use an object
> > (promise) we don't hold any reference on (after first _then).
> > This is weird :)
>
> Agreed.
>

Ok

<snip>


>
> > The ON_HOLD flag, now called efl_event_processed_get/set() is a better
> > approach to stop processing events.
>
> That is off topic, but seriously something we should consider asap if
> we want to drop the return type of event. I have not any case in mind
> where returning EINA_FALSE make sense. Should we drop it ?
>

I am also thinking we should drop it.
Pretty sure the few places that return EINA_FALSE right now are actually
mistakes and sources of bugs.


<snip>
>
> >> >> Anyway it seems the only difference here is that a promise starts the
> >> >> action as soon as possible, while an eo object would have to
> >> explicitely be
> >> >> marked as ready (which is very similar to starting the action during
> >> >> eina_promise_then).
> >> >
> >> > No, the main difference is that the life cycle is linked to the
> >> > callbacks and that their should not be any way to bypass it. eo_del
> >> > should also be forbidden for example on a promise as only a cancel
> >> > make sense. Of course we could alias it, and make sure that cancel
> >> > don't destroy the parent. We can also override all eo event API and
> >> > make sure they do what we want, but we can't at the moment override
> >> > eo_ref and eo_unref. The alternative would be to create an Eo_Promise
> >> > which doesn't inherit from Eo_Base (Or make an Eo_Light that both
> >> > would inherit from) and would kind of make clear that it is not an Eo
> >> > object, but a promise object (Given that eo_ref and eo_unref become
> >> > virtual function).
> >> >
> >> > Also at which point do you think user are going to be confused by an
> >> > Eo object where every single function call on it has its own
> >> > documentation and doesn't behave like a normal eo object ?
> >
> > That's where we still disagree :)
> >
> > I still have trouble understanding how fundamentally different those two
> > objects are.
> > In fact I see a lot of similarities between a (conceptual) promise and
> > Efl.Part.
> >
> > From my understanding, the main difference is that a promise callback
> WILL
> > be called, be it the error or success, one of them will be, for each
> _then,
> > _race and _all that was setup. Which can be enforced with a commit
> approach:
> >
> > // same syntax as eina_promise:
> > p = promise_function(obj)
> > eo_promise_then(p, _success, _error, data) // this is a HELPER based on
> eo
> > events, implemented in Eo.Promise, steals the ref
> >
> >
> > // it would be equivalent to:
> > p = promise_function(obj)
> > eo_event_callback_add(p, PROMISE_EVENT_FAILURE, _error, data)
> > eo_event_callback_add(p, PROMISE_EVENT_SUCCESS, _success, data)
> > eo_promise_commit(p) // steals the ref
> >
> >
> > // or:
> > p = promise_function(obj)
> > eo_event_callback_add(p, PROGRESS_EVENT, _progress, data)
> > eo_event_callback_add(p, PROMISE_EVENT_SUCCESS, _success, data)
> > eo_event_callback_add(p, PROMISE_EVENT_SUCCESS, _success_watcher, data)
> > eo_event_callback_add(p, PROMISE_CANCEL_SUCCESS, _canceled, data)
> > eo_wref_add(p, &p2)
> > eo_data_key_set(p, "my data", stuff_that_i_need)
> > eo_promise_commit(p)
> >
> > etc...
>
> commit doesn't work well with bindings and library that will not know
> when to commit a promise that is given to them. Basically only case
> where commit is to be called is in the application itself and never in
> any API that expose one. I don't think this is a solution.
>
> Only viable solution if to be done with eo is if eo_ref and eo_unref
> either send a message or can be overriden. If so, we can implement the
> following :
>
> p = promise_function(obj);
> eo_promise_then(p, &_then, &_cancel, &_progress, NULL);
>
> and
>
> p = promise_function(obj);
> eo_ref(p);
> eo_promise_then(p, &_then, &_cancel, &progress, NULL);
> all = eo_promise_all(p, p1, p2, p3);
> race = eo_promise_race(p, p2, p2, p3);
> eo_unref(p);
>
> We would silently eo_ref in eo_promise_then and eo_unref would start
> acting if the number of ref == number of function. Once it start
> calling each function, it would eo_unref and the last call would drop
> all reference to eo, destroying the object.
>

Yes. I'm not even sure you need more than 1 ref, but that's an
implementation detail.
It seems to me that you'll have, on success, a single call to
eo_event_callback_call(), followed by a single unref and removal of all
callbacks. If the object is still alive (i.e. the user had another ref on
it), then any subsequent callback add should do the same (call the
success_cb, remove the cb, unref).

But this is an implementation detail and I'll trust your judgement there.



> > _race and _all could be implemented in Eo.Promise, and would make the
> _all
> > promise get an extra ref on the sub promise.
>
> As _race and _all are most likely already existing as a native object
> in all bindings, it will be only useful for C. Implementing them on
> top of an Eo.Promise wouldn't be a real problem and we can make them
> more convenient as we do not need to follow eolian constraint there.
>

I was talking about the methods themselves. But indeed the returned object
should inherit from Eo.Promise as well.



> > And then the eo event callback data is "data", the event->info is the
> value
> > (void* anyway).
>
> Yes.
>
> > Internally, all we need to make sure is that all the callbacks will be
> > called (error or success), and the promise object can't be deleted until
> > then.
>
> We need to also override eo_del to actually act like a promise_cancel.
>
> > Also need to ensure that we unref() the promise object after it called
> its
> > callback (this can be done in each promise implementation - no infra).
> >
> > What happens if cancel() is called during a success callback? Will the
> > cancel or error cbs be called? Anyway this is a tricky situation, similar
> > to eo_del() during a callback.
>
> This is forbidden. The state of a promise is defined once and for all
> by the first value set or cancel. eo_del will have a warning and do
> nothing on a promise which as already succeeded, but hasn't finished
> yet for whatever reason. If it doesn't follow that rule, it breaks
> assumption on promise making them pretty much useless.
>

Good.


> Now, if you forget about Eo, Eina, ... and go back to C++, you will agree
> > that anything is an object. A promise would also be an object, an
> instance
> > of a class. Why would it be any different with our object model?
>
> Promise would be a template provided as a native type in C++ and be
> named future. C++ object model let you implement a lot of different
> life cycle management, funny GC for example, without enforcing
> anything. There is no such thing as eo_ref/eo_unref on a C++ object.
> This is something you implement yourself on top of C++ object model.
> Same goes with weak ref or smart pointer. They are something you
> implement on top of the language. This is not the case of what eo
> does. Eo come with its own life cycle management, and we currently
> can't implement promise without change to eo and overridding a few
> base function (ref/unref and del for sure, not sure for weak ref and
> friends).
>
> Every language now provide this as a native type.
>
> > So, yeah, still not convinced we need a different event signature, a
> > different ref/unref system (where, as seen above, we can manipulate
> objects
> > of which we don't own any ref), and lose on the way all the fancy
> features
> > that eo provides.
>
> With change to eo, it is doable. Still think we are forcing a cube
> into a smaller cilinder, but well, I have some good hammer, so
> whatever !
>

Really sorry to push this so much, especially so late. But looking at the C
API, the inconsistency, while trying to show that promise handles are a bit
different from standard EO objects, was just more confusing than anything
else IMHO.

-- 
Jean-Philippe André
------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://pubads.g.doubleclick.net/gampad/clk?id=1444514421&iu=/41014381
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to