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

Reply via email to