On 03/06/16 07:42, Carsten Haitzler wrote:
> ok. interacting with promises...
>
> these are just a mess.
>
> 1. the value thing is just odd.
> 2. they are complex to set up inside our api (setting them up setting cancel
> cb's and more)
> 3. they totally screw with what eo and interfaces was all about - making the
> api EASIER to use. promises make it harder.
>
> why harder? longer lines of code with more parameters and more special
> casing... but the WORST...
>
>   void _cb_promise(void *data, void *vaue, Eina_Promise *promise)
>
> that's a promise cb
>
>   Eina_Bool _cb_event(void *data, const Eo_Event *event)
>
> and that's an event cb. they are different. eo events were meant to simplify
> and unify our callback handling. to have a single cb signature. now promises
> break that. this is just bad.
>
> i wasn't sold on promises. i was skeptical, but whatever... but now i am 
> seeing
> they are visibly making things worse. code is harder to write, harder to read,
> harder to maintain, harder to get right. now we have timeouts that cannot
> repeat. no - creating a new timer in the cb is not repeating. it has to repeat
> with the "zero time" being the time when the timer was ticked off, not "now".
>
> please - everyone. take a look at promises and how they are used. forget all 
> of
> the "but node.js has them" and all the "i can chain promises" and so on. the
> BASIC usage of them is harder now in efl.
>
> what to do? well... minimize their use for one. do not use them unless you
> ABSOLUTELY HAVE TO. also promises should become eo objects with event cb's so
> they work just like everything else. i can ref, unref, delete and whatever 
> them
> like everything else.
>
> right now i think promises are just not in a shape to use or ship. they need a
> lot more work. i think we need to drop them for efl 1.18 and defer for efl 2.0
>

Guys, you bored me to death with this thread. I replied to what looked 
like it needed attention, but please let me know if there's anything 
specific I missed that warrants my reply.

I would like to add my take on promises too. As you may remember, I've 
objected to promises from the start. I just didn't see a sensible way of 
implementing them back then, and unfortunately, even after they've been 
implemented, I still don't think they are done nicely.
Here are a few of my comments on what I think needs to change. It is all 
based on things people talked to me about in the past and asked me, I 
haven't actually played with promises, sorry, no time. I don't know what 
is done with "value" that raster and jp mentioned, and I don't know 
about the type safety there (though it looked abysmal).

Lets start with life-cycle: Eo is great, and I think using Eo is the 
right way to go, but unfortunately that doesn't solve our life-cycle 
issue. When do promises die?

p = efl_file_set()...
// Delete here if file has been set?
promise_then_add(p, cb)
// Delete here if file has been set?
promise_then_add(p, cb2);
// Delete here if file has been set?
... // a million years into the future
// Delete here if file has been set?

There is just no sensible way to do it automatically. You will *always* 
have to unref, so following the above example:

p = efl_file_set()
... // All of the code before
eo_del(p); // It'll only die here

Which won't work because then ignoring efl_file_set's output won't be 
allowed.

The only sensible way of doing it, I guess, is to force a wrapper of 
some sort, so the code above becomes:
p = eo_ref(efl_file_set());
... // Code from before
eo_del(p);

Or probably for extra safety (like marking the promise was actually 
used, and not just implicitly with a ref, this will allow us to block 
then/cancel registration and be more safe).

p = efl_promise_use(efl_file_set());
... // Code from before
eo_del(p);

efl_promise_use will set a flag in the promise so that
p = efl_file_set();
promise_then_add(p); // This will fail because the flag wasn't set.

So that's safe and probably the way to go. This will let us manage 
life-cycle correctly.



Usage of event callbacks: I mentioned it somewhere else in the thread, 
but not as bluntly. I think Marcel is wrong, and I think you guys are 
focusing too much on non-existent semantics. Saying promises are 
callbacks that are only called once so they are inherently different 
from event callbacks is absolutely wrong. Think of EO_EVENT_DEL, called 
when object is deleted, only called once. You are too fixated with how 
events happen to be implemented in eo.base, don't.
As I also said, overriding callback_add and adding there code to call 
the callback immediately if the promise has already finished is 
*exactly* the way to go. Also, you don't need to remove callbacks once 
they have been executed, they just happen to never be called again 
because the callback is never triggered again.



Splitting of promise to two objects, owner and future: unnecessary. 
There are a few mechanisms in Eo to let you have different "access" to 
an object.
1. Make all of the owner methods "protected", so assume whoever is 
implementing "owner" is more responsible and let him have access to both 
the "future" functions and his "own".
2. Same assumption as #1, but just make Owner inherit from Future, and 
create Owner internally, but return Future in the API. Won't have a 
different in C, but for bindings it'll only expose the correct type.
3. If you don't want to restrict yourself to the assumption made in #1, 
that the implementer of Owner can be trusted to know what he's doing, 
you can create two classes and two interfaces.
abstract Efl.Promise
interface Efl.Promise.Owner, implements Efl.Promise, adds Owner API
interface Efl.Promise.Future, implements Efl.Promise, adds Future APi
class Efl.Promise.Internal, inherits from Promise, implements both 
interfaces
You then create the internal one when implementing a promise and return 
Owner or Future as the type (so it's an interface, which is very common 
in OOP) depending on who is using them. It's a bit more complex and 
doesn't add any assurance in C, but make it work as you want in bindings.

With that being said, I think you are just being difficult with this 
requirement. People should know not to be dumb. The same way people know 
not to call eo_event_callback_call(obj, EO_EVENT_DEL, ...) on an object 
randomly. They *can*, but they shouldn't. You can't protect from 
everything. I think the first or second approach are just fine.




I also want to limit the usage. I want them to be used and proved useful 
before we start using them everywhere. By useful and used, I mean useful 
and used by people other than the creator. We've detected issues with 
eina value, and ecore getops long after they were created although their 
creators were already using them and said they were good. Same goes for 
Eo, that's why we had so many iterations. I would like to have way more 
proof and time before I fully commit our new API to a new unproven 
concept. Eo proved useful because people were using it even when it was 
hard and we told them not to. This is how much value it added to people. 
Let's see if promises prove the same. Until then, I say: please, let's 
not expose them in our APIs.

I hope I haven't forgotten anything.

--
Tom.

------------------------------------------------------------------------------
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://sdm.link/zohomanageengine
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to