On Thu, 16 Jun 2016 20:11:09 +0100 Tom Hacohen <t...@osg.samsung.com> said:

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

the way i see it is you need to set both then and else at the same time so

  p = efl_file_set()
  eo_promise_then(p, sucess_cb, fail_cb, NULL);
  // p may be deleted at this point since on success or failure it is deleted
  // do not depend on p after you have set then/else cb's. ensure if you need to
  // access the cb that you add a DEL event cb to the promise to track it OR if
  // you HAVE to have it then add an eo_ref(p) before eo_promise_then()

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

well that's kind of the problem. with no then/else the promise has to stay
around forever holding the return value. you can't ignore it if its a return.
if it's

  p = eo_add(NULL, PROMISE);
  // do aother promise setup here like
  eo_promise_then(p, done_cb, NULL, NULL);
  elf_file_set(obj, file, key, &promise);

then it can set up the promise in efl_file_set. if you do

  efl_file_set(obj, file, key, NULL);

then we say "we don't care about the async result". perhaps it can now be sync
by default if you do this?

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

i think that's more complex than the above i suggest. the problem is if you
pass in a promise... this now affects all of our file_set or any api that can
or should be async.

as i said... i don't think we need a promise on these objects. we already have
an object to store the value/state of the load. it can already call event cb's
when these actions succeed or fail. we have done this with preload for years
already. if you do another file_set it does cancel the previous one by
definition (the only q is if that means you have to call a load fail callback
of some sort).

this is what i mean by "let's not use promises here because at this stage they
do not help, just cause more work, complexity etc.".

> 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 

i totally agree with you on this.

> when object is deleted, only called once. You are too fixated with how 
> events happen to be implemented in eo.base, don't.

i agree.

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

agree - but i think the then/else would do well to be special for eo promises
(for the reasons already given). progress should be an eo event etc.

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

i agree. single object, but 2 interfaces. a future and an owner interface on a
promise obj.

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

this sounds good.

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

well futures and promises for at least several languages need to be manually
bound. but a quick look shows lua does not have promises IN LUA. there are
libraries that implement them (promises/futures) but it's not a language
construct. c++ doesnt have it either. it's in sdtc++. i am unsure for js/node
where they stand but given node.js has them they can be assuemed to be a core of
the langauge in a node.js environment.

but for lua we will want to have actual promise objects with out methods
exposed in lua like everything else... so we DO want at least some auto
generation for eo promise and perhaps just a special case for eo_promise_then()
like eo_callback_add/del are special.

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

i actually prefer this by far.

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

i like this one much better.

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

the last one but you can return the core object. you don't hide the owner
api's. they are there. but they are clearly FOR the OWNER to use, not the USER
of the promise. it's clear. if people do stupid stuff and their code starts to
not work well... well that's life. don't do that then! it's one thing what we
do with an api. people can abuse it and do bad things. don't do that! all it
does it make your app do bad things. it's not a good idea. we are not creating
a security layer where a user must be FORCED to never be able to do anything
bad and it's impossible.

we just need it to be clear enough that "this api is for you to use, this
other api is for some other piece of code". if it's split into 2 interfaces on
the same object, then it's very clear what belongs where. :)

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

we need time and space to experiment with them indeed. we shouldn't go gung-ho
until we have worked out the kinks. i do see the usefulness of promises, but
their usefulness has to beat what can be done with basic objects+events on them.

-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
The Rasterman (Carsten Haitzler)    ras...@rasterman.com


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