Hi Cedric, On 13 June 2016 at 03:02, Cedric BAIL <cedric.b...@free.fr> wrote:
> On Wed, Jun 8, 2016 at 4:16 AM, Carsten Haitzler <ras...@rasterman.com> > wrote: > > On Mon, 6 Jun 2016 06:01:13 +0200 Cedric BAIL <cedric.b...@free.fr> > said: > > <snip> > > >> >> You just can't do with eo event what promise do. Eo event are a > >> > > >> > it's not NECESSARY to do anything new. timeout can be an eo obj that > deletes > >> > itself after the one-shot callback. it doesn't need a promise. same > as job. > >> > i can't add promises as children to an obj and make sure they get > >> > autodeleted when parent is. i have to do this all by hand now. > >> > >> It is a terrible mistake to override eo object lifecycle. This is an > >> absolute no go as a solution. Anything that bypass the refcounting and > >> ownership of an eo object lead to massive issue and trouble. We can > >> not implement auto deletion of eo object outside of the reference > >> count system. > > > > this doesn't bypass it. it USES it. the object unrefs/del's itself. when > done. > > when an evas canvas is deleted it deletes all child objects. no code is > > explicitly in the app deleting the objects. it's done internally. > > That's exactly what I mean by bypass. Evas canvas delete object > because the parent die. Now, in the case of a promise eo object, there > is no parent that will disapear to do the unref/del, it is when all > the listener have received the value, that the promise disapear. If > you want to use normal eo lifecycle for that, it means that the object > has to delete itself. And this is bad. This is exactly what > ecore_timer where historically doing. They were not linked to any > parent and would just vanish under your feet. This is what tricked you > into thinking the bug was in the timeout promise while it was in the > handling of the lifecycle of the timer itself. > > Reading what you say, you are advocating for using the normal eo > lifecycle and not letting itself commit succide, which is the proper > way to handle eo object. Now how can that work with promise ? No idea. > > >> > efl model needs to drop promises. ask sanghyeon and sub - they are > hating to > >> > work with the promises in efl model - it's massive overkill and > unneeded. > >> > >> If you read the ongoing discussion regarding MVC and the view list > >> code, you will see that the problem is not the promise, but the fact > >> that the model is fully asynchronous and that they have to handle it. > >> Dropping promise out of the model, and they will not only hate, they > >> will want to jump by the window. > > > > it's both. async made it more complex than sync AND promises require a > unique > > promise per property on a model object when a simple "property loaded" > event on > > the model object would do just fine. the one cb can refresh the item > mapped to > > the model object in whole and a property get can just return null etc. > if the > > property is not loaded yet. property content has to in the end be cached > in the > > model object anyway so this ends up simpler and you don't need a promise > nor > > the value - the value is already living in the object under the property. > > Returning NULL change absolutely nothing to there problem. It just > means they have to keep fetching and fetching until they have all the > property resolved. Even worse, they have now no synchronisation > primitive to do that for them at all. You know with promise they have > promise_all to know when everything is finally settle down, because > there problem was how to find the final size of an item if you don't > have all it's data. So you need to keep fetching all the property you > need to display it until they are all there. Then you can stop, learn > the size and move on. Your solution doesn't simplify that at all and > you have no synchronisation helper anymore ! It add complexity as this > is what we had before. As I said, that's what we had before, and it > was way more complex. > > Now in the case where we do force all data to be available before we > notify them, so that they avoid there problem (which was to wait until > everything is there), it obviously create delay problem as the time > needed to finish fetching all property can be quite long. Expecting > only to have all data available in one request make absolutely no > sense. Let's take two examples : > > - An avahi model will be able to give you an ip right away, but it > won't be able to give you the name right away. That part is > asynchronous. So what do you do ? Wait for the network to be done > fully filling that entry before you can actually access any of it ? > This is likely going to be the case with a lot of network model, > multiple request to build the model delaying the availability of the > data to until all of it are fetched. > > - Io model. If you are listing the content of a directory, you get to > know right away if it is a file or a directory and you also get the > filename directly. You need another system call to get size and access > right which will take longer. Also at some point we should integrate > with efreet to allow easy linking of the type of the file to an icon > name that could be connected to efl.ui.icon. Obviously the time > between when you actually know the first group of information and when > you get the information of the last group will be huge. > > You can also proxy model into other model. Now, this increase the > complexity in the proxy model as it has to wait for the proxied model > to be done fetching everything before annoncing anything. All the > synchronisation problem are to be handled manually there. So you will > agree with me, that you need support for fetching individual property > individually. Be it with promise or by returning NULL, you need > indepedent fetching of each property and a notification when each of > them get done. Now, I think you are better of with synchronisation > primitive like promise_all than by doing everything manually. > > The only thing I think we may need at some point is a grouped promise > fetch so that you get a batch of data at once and the model does > handle the synchronisation needed to provide all of them into one > operation. This would reduce the amount of callback needed and quite > likely improve performance. That is an optimisation that is completely > doable in the current design of promise and can wait for later. > > <snip> > > >> >> repeated event which doesn't allow any easy synchronisation and lead > >> > > >> > wrong. you can in the callback just do the next action and delete > yourself. > >> > it is possible to do this easily enough. but this isn't the common > case. > >> > >> Yeah, this is going to make life easier by writing more code that is > >> likely to be the source of more problem. > > > > and eina_promise isn't more code? it's new/different to the rest of > events and > > objects? eina_promise objects have no safety and ate causing crashes now > where > > none were before and will continue to cause more and more and more. it > will > > cause much more time spent debugging and complaining that efl is > "horrible" and > > "hard". > > As said before, moving our internal code to use eina_promise has > reduced our size of code for mvc by 30%. As for the safety, I already > agreed about using the same kind of infra as Eo_Id and that's > absolutely no big deal. There is nothing to win with Eo and Event. > > <snip> > > >> to implement the asynchronous behavior. Writing a new data model for > >> MVC has also been a huge pain until we switched to promise. So yes, I > >> have been experiencing first hand what writing asynchronous code is. > >> Same goes for Felipe. I am not going to switch away of a solution that > >> make our life seriously easier. I will improve the solution, but not > >> walk away from its design. It is way way way easier to implement > >> safely asynchronous behavior with promise than with your proposition. > >> This has been tried and the outcome has been clear for anyone involved > >> with that previous experiment. > > > > eina_promise is not ready. it's unsafe. it's more complex. it's a new > kind of > > object that doesn't behave like any other object and lacks the safety and > > convenience. if you say objects' can't delete themselves then what on > earth are > > promises? are they not objects? are they not something you hold a handle > to so > > you can cancel them or otherwise interact with them? do they not have a > > lifecycle? are they not created and destroyed like eo objects? ye somehow > > promises can delete themselves (e.g. the eo timer object a timeout > created was > > deleted then the promise is deleted silently on its own in the > background...) > > Promise are a promise to deliver something in the future. In themself > they have no propery and no function. They aren't object, they are > delivering object. Their lifecycle is that they either deliver or > fail, they never "die" before that. It is a guaranty that they deliver > a callback whatever happen to everyone that registered to listen them. > This doesn't match at all eo object lifecycle. > > > you are totally inconsistent thinking promises are some kind of magically > > special thing that is not an object... yet in all ways it works *IS* an > object. > > If you stretch the definition of an object outside of what Eo is, yes, > but by that standard everything could be an object. If you limit your > definition to what Eo is and I mean by that Eo lifecycle and events, > it doesn't. Oh, and there is plenty of stuff in an Eo object that are > useless for promise. > > >> > promises are not eo objects. they cannot be managed in the lifecycle > of > >> > object. jobs and timeouts now need special handling. the promises for > >> > models are not eo objects so you have to specially handle them if you > want > >> > to cancel and there actually just is little point in doing so > actually. > >> > > >> > you can't make promises weak refs. you can't add them and children to > a > >> > parent for auto-deletion. they can't be easily extended (adding more > events > >> > to a promise) like eo objects can. > >> > >> You never want weak refs, you don't want either parent/child > > > > why do i not want them? tell me? why do they even exist then as an idea > and why > > are they in eo? if i want a weak ref then that's what i want. i want a > handle > > that the object system will set to NULL for me when the obj is deleted > so i > > don't have to do that by hand by adding a del callback and nulling the > ref > > myself. so... why don't i want them? i can tell you that e, efl etc. is > full of > > this kind of "track del event and NULL a ptr" code. it's all over the > place. > > so... why? > > Because you are only interested in the result of the promise, not in > the promise themself. You don't track the life of a promise, because > you do that the moment you register the then/cancel callback on it. If > you do not need the result of the promise, you cancel it and that is > the same as if an error did happen. As said before, we may need a way > to automatically cancel a promise once an object is deleted, but you > do not need to keep a promise around because an object is still alive. > That's because the object is not using the promise, it is expecting > its result. Something along eo_promise_link(obj, promise) is the only > thing we need. > > <snip> > > >> when handling asynchronous stuff). And implementing that behavior in > >> Eo is going to be a pain (disabling refcounting, disabling > >> parent/child, ...). > > > > eh? don't disable refcounting. in fact WTF is this?... > > > > EAPI void eina_promise_ref(Eina_Promise* promise); > > EAPI void eina_promise_unref(Eina_Promise* promise); > > > > you speak of not refcounting yet eina promise has RE-IMPLEMENTED > reference > > counting just like eo. i can't take what you say here seriously. if you > say > > promises are not objects and should have no reference counting because > they are > > oh so special yet... right there in eina_promise is EXACTLY THAT. eina > promises > > are re-inventing eo objects thinking they are oh-so-special > not-object-objects. > > This is the refcounting of how many callback then/cancel are to be > registered and a protection against deletion when running them. This > is not like eo_ref/unref as they do not refcount the same kind of > thing (number of user vs number of callback waiting for a result). > > >> >> Also last point, I think having the same signature, would actually be > >> >> more confusing to people. Like why does that event not accept to be > in > >> >> a promise_all or promise_race ? If it has the same signature, people > >> >> would expect to be able to use random event in promise_all/race and > >> >> that is just not doable. > >> > > >> > the number of times people actually NEED these is insanely rare. no > one is > >> > using them. these "features" cause more pain than it's worth. speak > to the > >> > people using promises now. > >> > >> Ofcourse they don't need it, they never write any asynchronous code. > >> Almost none of our API is asynchronous and when they can they run away > > > > no. i am speaking of the cases where promises have crept in. timeouts > are not > > needed when timers will do. jobs could just be objects like timers that > > self-del after calling their "done" callbacks. eina_model could work > without > > promises just fine (see above). any kind of event with "do something now > and > > later some event happens as a result" is async. we've had this in efl > for ages > > in several corners. edje objects are async by design. signals are queued > and > > will pop out later in their callbacks. i shouldn't have to tell you > this. edje > > - one of our biggest cornerstones of everything we do is async. preload - > > async. jobs - async. timers - async... ? > > Yes, they are async and yet there is no generic solution to > synchronize any of them. Result our API is harder to use as you need a > lot more code to synchronisation and make sure you didn't miss > anything. Promise do guaranty you that when you did register your > callback, you will get called, one way or another, whatever happen. It > is just two cases to handle, come with a few handy synchronisation > primitive and are simplifying a hard problem. Yes, asynchronous API > are hard for people. Having no primitive at all to handle it, doesn't > make our API simpler to use, it make our API harder to use. Eo is not > the answer to all problem. It has draw back in some case, like this > one to use it (Namely performance cost, memory cost, unmatching > lifecycle and unmatching event). > > <snip> > > >> > why should a timer be so DIFFERENT to a timeout? why should it be a > special > >> > thing with a whole different way of working with promises? why add the > >> > complexity? just set a timer to NOT REPEAT on creation... having all > the > >> > code for a timeout is needless complexity in our codebase AND in the > api as > >> > people have to figure out a completely different way soemthing works. > >> > >> So your point is to have the timer just stop emiting event and you > >> have to kill it manually afterward. Doesn't look any easier to me. You > > > > no. it just deletes itself. promises do just this already! > > > >> have more code to write and more chance to go wrong. The fact that > > > > no you don't have more code. well "more" would be to set he timer to not > repeat > > on creation. > > > > timeout = eo_add(parent, EFL_TIMER_CLASS, > > efl_timer_repeat_set(eo_self, EINA_FALSE), // this > extra line > > eo_callback_add(eo_self, EFL_ACTION_DONE, callback, > NULL); > > > > with timers being eo objects and timeouts being promises i have 2 vastly > > different pieces of code than i have to learn about 2 different kinds of > > objects that work differently and use different api's. > > Because they are different in nature. The first one is an object the > second is the guaranty to either deliver something at a specific point > in the future or fail. > > >> they don't do the same thing, means they are not the same. We could > >> sure merge everything together by this standard. Not going to make > >> anything easier. Having explicitly different object for different > >> behavior make things easier, not the opposite. Otherwise we should > >> merge back all this image object, because they all display pixels in > >> some way or another. > > > > it make's it harder to learn, more api's to learn, difference to figure > out, > > which do i use where etc. etc.- you add a learning curve that is simply > not > > needed. don't want ti to repeat? turn repeat off once above on creation. > > Having more focused and dedicated API make life easier as each object > are less complex. Otherwise we go back to the old Evas.Image which > should be easy to use as it could do everything. The problem is not on > the number of object and API, but on how clearly separated they are > and how much they deliver something different. > > <snip> > > >> the problem that I got described are: "It is to asynchronous, we want > >> result directly.". That is not going to happen and with your > >> proposition it will be just worst. Been there done that, not going > >> back there any time soon. > > > > how will it be worse? the model object stores its properties? a gegt is > an > > immediate get from the stored property data? you use events just to > indicate > > new property data arrived? (event info can indicate which property it is > that > > arrived if they care)? how is that worse? > > Well, how do you now know when you are done ? You have to do all > tracking by yourself, with promise, you have promise all. You also > have to do a manual check for each data fetch to see if it is NULL or > not. You increase the chance that someone will complain why is my data > NULL and people have to fetch all property every time there is an > update to just count things. I don't see at all why you think it is > simpler and less code. Experience as told us it wasn't. > > <snip> > > >> > see above for model. same for job and timeout. they don't need them. i > >> > haven't looked at eldbus or eio but i think its pretty much the same > deal. > >> > you don't need them. > >> > >> It's pretty easy, just git log -u on the any of the model and the > >> elementary view to see how much more work it was before the promise > >> (Keep in mind that it was also buggy and more difficult to > >> develop/fix). You proposition has been tried in the past and it has > >> been a complete failure. > > > > it has not. let's go to a long standing one - preload. that has been > around a > > long time and how has it been a failure? explain it to me. we won't talk > model > > as it barely has even existed or been used long enough to say. > > How many people use it instead of just doing a show ? How many user of > genlist complain about it being slow while they don't use preload on > the image ? I know that they are having anyway some filesystem access > with the header, but doing a full image decompression is worse. I am > pretty sure most people don't, because we have had a bug in preload > until 1.18. If you heavily use preload, you would end up with a crash > (like the one edje_cc was suffering from). So yes, you use it, but I > bet that most people don't and I am pretty sure that any use of > preload in genlist would have triggered the bug in previous efl > release. > > >> > this is the same as eina_promise. i have to do eina_promise_then() > AFTER i > >> > get the eina promise back - eg from job or timer. but what you do is > you > >> > dont need a promise at all above you just do: > >> > > >> > eo_callback_add(image, EFL_IMAGE_EVENT_LOAD_SUCCESS, cb, NULL); > >> > eo_callback_add(image, EFL_IMAGE_EVENT_LOAD_FAIL, cb, NULL); > >> > efl_file_set(image, "tot.jpg", NULL); > >> > > >> > i set up to listen before i do the action. simple. it works WITHOUT a > >> > promise. > >> > >> Thanks for an example that doesn't work. Either you add a call before > >> registering all the callback to force synchronise the previous > >> possibly running file set or you have to handle in both callback the > > > > err how does it fail? you dont dd cb's every time you file_set. are you > mad? > > the code that is controlling the file set sets up the cb's once and > listens for > > when things succeed or fail, then does something appropriate. how does > this > > fail? > > So what happen if there was already a file being set asynchronously on > the object ? > > >> case where the event you receive is not for the file you are just > >> opening after. So your example is misleading on the complexity on > > > > how is it misleading? you set up cbs once. you file_set. any new file_Sst > > cancels a previous one so no cb will be called for any previous ones. > any cb's > > called after that are for the last file_set. how does it fail? > > That is a synchronisation bug to happen. How other pieces of software > will be notified that the previous file set request has been cancelled > if they are not getting the callback at all. You either add a new > callback that they have to listen to or you trigger the cancel > callback. In which case you have trouble. > > >> purpose. Oh and with promise their would be no misleading behavior as > >> the previous promise will have automatically been cancelled and the > > > > it isn't automatic. the file_set explicitly tracks the previous promise > and has > > to cancel it. it's the exact same thing. > > Yes, except that the previous promise will deliver a cancel to > everyone and it will be explicitely related to the request they > registered for. No need to filter things out ala Ecore_Con events or > to have addoc synchronisation in the application. > > >> new one will have been completely independant. Thanks for giving me a > >> good bad example with your proposal and why people have not implement > >> much asynchronous behavior with our current API. > > > > wtf? it's no more code at all. it's 2cb's added as event cb's and a > file_set. i > > don't have an ADDED promise object to deal with at all. it's simpler. > not more > > complex. > > We both know that dealing with event filtering is a very bad pattern, > and very explicit reason why people don't like Ecore_Con API. So what > is your work around ? You keep focusing on the code that just set > callbacks as if it was the end of what you are writting, but forget > about the added complexity in the callback themself. > > <snip> > > >> >> is no way to get any event. Ofcourse, we can override the behavior of > >> >> events on this eo_promise completely. Now let's imagine, that we > >> >> actually do always store the events, so that everytime someone > >> >> register a callback we can send the event. Still you can't auto del > >> >> the object at any point in time, you have to force the user to > >> >> implement the eo_del and to always provide both a then and cancel > >> >> callback. > >> > > >> > you have the same issue with eina_promise if you return it. EXACTLY > THE > >> > SAME. it has no cb's for then/fail yet. > >> > >> No, promise keep in memory the result until you register all the > >> callback you have planned to register. There is no race condition at > >> all. That is why you pass a free method when you set the value. It is > >> to clean it later on and to keep it around until you are done. So no, > >> it is NOT THE SAME. > > > > and if you pass in an eo promise object it can be done similarly - just > set up > > cb's on the promise obj before passing to the action. the model stuff > works > > this way - promises are passed in not returned. > > Rellying on the order of callback being registered is a recipe for > complain. I can see people complaining why they don't get their > callback already. Also you would need to do the full setup of your > promise including all the promise_race and promise_all before you set > up your request. This is a huge requirement and restriction. > > > and you can do the same with eo - you can store the result until cb's > added or > > until a go/done/whatever api is called. but that on;y matters if you > want a > > specific cb for that specific action. in general if you want that hen > you want > > a real object to be returned so you can manage it like other objects. > > As said before, basically what you want is an Eo object which doesn't > behave like a normal eo object. Having its own meaning for ref/unref, > for events and life cycle. At this point, I don't see how it will be > easier for people and not more confusing ? > Efl.Part are EO objects that die after a single function call. So, we already have objects with a different lifecycle. Events are the same: they call a callback function with a user data and an event info (promise value). For how long is a promise handle valid? Is it valid up until eina_promise_then? What if you just stuff the promise in a _race or _all? Can you ignore a promise handle altogether? (I guess it would leak) 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). > >> If history tell us, our existing solution is not usable, but prove me > >> wrong and show me how amazing our current limited set of asynchronous > >> API is used by so many people. Now just think that we are expanding > > > > as above. ecore_con. ecore_con_url, preload, timer, job, animator, .... > all > > used. > > We both know that people complain about our ecore_con api a lot and > that preload was not used much until now. > > > what we learned is these are objects that need tracking and that is a > pain and > > that is why we have eo. you are now choosing to abandon that lesson with > > eina_promise. > > I am not. We have also learned that they are a pain to deal with > because of a lot of other reason than just it not being eo, on of them > being also synchronise things together is a pain. You know tracking > things and making sure that you stop caring about your timer timeout > when you have connected and stuff like that, but sure it is just > registering a few callbacks and using refcounting. > > >> the amount of async API and image the result. I see it already, as > >> many data model as we have user of elm_store, as many view as we have > >> user of image async preload, ... I can see that success already. > > > > we have very little async api. almost all of them are used. > > > > we're repeating here. > > > > eina_promises are objects. they just refuse to be eo objects and so be > totally > > different in usage. this is bad. it means no safety. it means different > > callback signatures etc. - as above. this is worse than what we had with > eo > > until promises turned up. far worse. and it's worse than legacy api > because you > > lose the benefits of eo AND make the code longer. > > As said before, what you are advocating for was what model was before > promise. It was exactly that and it was 30% more code all over the > place. So please check our history of code and see that your assesment > of it being more code is wrong. As for the benefit of Eo, it is now > in, we are using the same kind of infra as Eo_Id for promise. > > >> No, you didn't, I did. You completely missed the problem. The issue as > >> to do with timer that have a problematic lifecycle. Historically timer > >> where automatically destroyed by the main loop when the main loop was > >> destroyed. This behavior is still there and by pass the ownership > >> behavior of eo reference (like your proposal for having an > >> automatically deleted eo object). So I needed to watch for the timer > >> to vanish under the feet of the timeout. This was badly done on my > >> side as I was just watching the DEL event on the timer. Obviously any > >> eo_del o the timer does lead to that event, which created the double > >> free. Promise could be more resistant and prevent double cancel and > >> double value set (which they will soon), but the main fix is to fix > >> the timer lifecycle properly and watch the main loop deletion, not the > >> timer destruction. So your analysis of why promise is bad is based on > >> a lifecycle issue on an eo object which is doing exactly what you > >> recommand to do. Seems like you should revise your proposal as it did > >> obviously misslead you into not fixing a bug properly. > > > > umm i sat here and looked at the backtraces. i sat in valgrind. you > cancel > > promise. it dels' timer obj. del cb on timer then wants to cancel promise > > again. then it falls over in a big stinking heap. i shortcut it so on > cacnel > > this loop wouldn't happen. it worked. it didn't leak. but it points out > how > > fragile promises are. > > It did leak, just not in the case you were testing, but whatever it > was a bug in promise as it was obviously in the backtrace and eo can > not be the source of the problem even when it pops up in the > backtrace. > -- > Cedric BAIL > > > ------------------------------------------------------------------------------ > 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. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e > _______________________________________________ > enlightenment-devel mailing list > enlightenment-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > > -- 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. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel