On Mon, Aug 1, 2016 at 3:25 PM, Cedric BAIL <cedric.b...@free.fr> wrote:
> On Sun, Jul 31, 2016 at 8:50 PM, Gustavo Sverzut Barbieri
> <barbi...@gmail.com> wrote:
[...]
>> struct Eina.Blob {
>>     mem: void_ptr;
>>     parent: Eina.Blob;
>>     size: size;
>>     refcount: int;
>>     free: Eina_Blob_Free_Cb;
>> }
>
> I really don't like the introduction of that type. Eina_Binbuf already
> support static/read only content. See below for why.

See my other email on why binbuf is not enough. In Soletta we also had
a sol_buffer (~eina_binbuf), which also had fixed capacity (ie: no
realloc) and memory-not-owned (ie: no free) flags. It's not enough to
get efficient access:

 - cannot be used for mmap()'ed memory, you'd need to munmap() on free;

 - parent + refcount is needed if you want to allow slicing and
viewports, things like take a line from an mmap'ed file, unref the
mmaped file yet it will be alive until the slice is alive.

See 
https://github.com/solettaproject/soletta/blob/master/src/samples/crypto/message-digest.c
for an example on how this can be used. In this example the file can
be used as a single blob or "sliced" into chunks.

See 
https://github.com/solettaproject/soletta/blob/master/src/lib/common/sol-file-reader.c#L136
on how a blob can be extended, in this case it keeps the reference to
the mmap()'ed file handle, so on blob "free" you can munmap(mem) +
close(fd).

This is my efficiency advice after my experience optimizing these
streaming use cases. It's not strictly required, but I'd say it's a
nice addition to use this type and pattern across all "memory passing"
functions that deal with read-only memories that have uncertain
lifetime.



>> /*
>>  * Using 'Net' instead of 'Network' since all others use a shorter
[...]
> I am personnally against the shortening of our namespace and naming in
> general. Good proper text editor will do the autocomplete efficiently
> enough and it bring a general rules that is less confusing to user.
> Are we going to go with Can insstead of Canvas ? And so on and so
> forth.

Nobody ever used "Can" for canvas... "Net" is very frequently used for
networking, as one can see in all these toolkits, the kernel, etc.

But I'm okay to keep Efl.Network. Should I change for v2 or wait
others to chime in?



>> abstract Efl.Net.BaseSocket (Eo.Base) {
>
> Pretty sure this one should be actually an Efl.Loop_User. The idea of
> an Efl.Loop_User is that when you set a parent, that parent should be
> able to return an EFL_LOOP_CLASS object when requested with
> eo_provider_find.
[...]

thanks for the insight!


>>     [[Abstract class representing a network connection socket]]
>>
>>     events {
>>         read @hot: Eina.Binbuf; [[data is available to read,
>>                             if consumed use eina_binbuf_remove().]]
>>         sent: Eina.Blob, error; [[data specified by blob was sent,
>>                                  if error != 0, contains errno]]
>>         error: int; [[errno]]
>>     }
>
> I am not to sure about this events, see below.
>
>>     methods {
>>         send @virtual_pure {
>>             [[Queue data to be sent to remote]]
>>             params {
>>                 @in data: Eina.Blob; [[data to queue for sending]]
>>                 @out error: int; [[0 on success, ENOSPC if no space left]]
>>             }
>>
>>             /* can provide a helper that sends memory, creating the
>>                blob internally, such as static-const (no free) or
>>                allocated memory (call free)
>>             */
>>         }
>
> I would clearly prefer a send that take an Eina.Binbuf and return a
> future/promise when the transaction is done. This would enable the
> possibility to be notified of progress also. I am just wondering what
> would be the useful value to return. Time when the operation was done
> ? The failed case would just expose an Eina_Error that properly
> describe the problem. It will make the code look a lot more
> synchronous as we can just chain them. Not as nice as go, but closer I
> think.

As talked to you at IRC, I'd like to keep away from Promise at this
stage at least it's final and I can implement using the Eina or Eo
variant of that.

For now we can go with:

send {
    params {
        @in data: Eina.Blob; // or void+size or binbuf
    }
    return: promise<bool>; [[success or failure of completion]]
}


> Also if we go with a future, should we also propose a read function
> that return a future/promise to an Eina_Binbuf ? This would be nice if
> we want to implement timeout on a read or chain it with something
> else.

not sure I follow you here, example?


> Also possible additional operation would be sending a file. Eina_File
> should be a native type to any binding and we do have a few place
> where you get one, would be nice to do be able to transparently send
> one.

See my comment about Eina.Blob.

It should cover that unless you want to do progressive loading of
chunks, such as instead of providing a full mmap()'ed file, you just
open(2) it and on "read(size)", you do the syscall. This could be
useful to fd that does not describe a file, but a socket, pipe, etc..


>>         flush @virtual_pure {
>>             [[Try to send as much as data without blocking]]
>>             /* NOTE: changes behavior from current flush() that
>>              * really blocks!
>>              */
[...]
> Hum, what is the purpose of flush in that case ?

call underlying write(2), send(2)... without the busy wait. If the
busy wait is desired, then the user can:

    while (!flush()) { /* some stuff here, like sched_yield(); pulse
the GUI, etc */ }



>>         @property internal_fd {
>>             [[the internal file descriptor (use with caution!)]]
>>             /* it seems the usage is to steal the fd to do something
>>              * else or set some flags. If so we could expose some
>>              * primitives such as fcntl_add(type, flags) and
>>              * fcntl_del(type, flags) as well as a destructor that
>>              * will return the stolen fd (destroys the object and
>>              * keeps fd alive).
[...]
> This should not be exposed for the moment. I see a lot of wrong doing
> possible. It will be better to had property that enable possible
> fcntl.

Agreed, I'll omit this from v2 and leave fcntl controls out, add when
we find the users, currently empc.


>>         @property timeout { /* this usually doesn't change,
[...]
> What does this timeout cover ? connection ? transmission ? both ?

it will restart an ecore_timer after every operation. If the timer
expires (no read or write), it will call ecore_con_server_del().



>> class Efl.Net.Socket (Efl.Net.BaseSocket) {
>>     [[This is a client socket that is created and connected to a
>>       specific server given to the constructor]]
>>
>>     methods {
>>         connect {
>>             [[The constructor that connects the socket to a given server]]
>>             params {
>>                 @in type: Efl.Net.Socket.Type;
>>                 @in address: Efl.Net.SocketAddress;
>>                 @in timeout: double;
>>             }
>>         }
>
> Maybe it should be a property on a connection manager that return
> future<Efl.Network.Socket> ? Something like future<Efl.Network.Socket>
> Efl.Network.Manager.connect(Efl.Network.Socket.Type,
> Efl.Network,SocketAddress). But that would work only if we have no
> other parameter to set. If this is just a property that will trigger a
> connection on finalize, then we have a lot of possible flags to handle
> maybe.

Here you must tell me what you guys prefer. To me it's mostly the
same, the important part is to keep the API consistent and users
easily understand how to use them.


>>     }
>>
>>     constructors {
>>         .connect;
>
> Hum, didn't we abandon custom constructor ? I kind of forgot where we
> are on this, but I remember that the idea was to rely just on
> finalize.

pointers to the discussion and outcoming code/examples would help :-)


>> class Efl.Net.Server (Eo.Base) {
>>     events {
>>         connection @hot: Efl.Net.BaseSocket; [[new connection was accepted]]
>>         error: int; [[errno]]
>>         /* no disconnect, listen on each individual connection */
>
> Should we plan to automatically call eo_del on disconnection and
> people are just supposed to listen on the del event actually ?

I'd say yes, that's my understanding when I wrote that. But again,
tell me what's the current pattern.


>>         @property connections {
>>             [[active connections]]
>>             /* Needed?
>>              *
>>              * actual members or just a counter? It seems all others
>>              * do not keep a list and we should be careful if
>>              * iterating over the list happens to modify it.
>>              *
>>              * count would be useful to gracefully quit if no
>>              * connections, but is easily done elswhere.
>>              *
>>              * the only user in our repo is eeze_scanner.c that uses
>>              * to send a single eet to all connections. Also easily
>>              * done at its own side (actually it already stores the
>>              * clients in a hash, could foreach() that one).
>>              */
>
> Maybe proposing an iterator instead, but then how about when you need
> to split the processing in smaller step ? I do agree with you, this is
> a tricky one. For now, let's just expose a counter.

IMO I'd skip even the counter, it's easy to do outside with simple
listeners to events.


> Nice review of all of the other toolkit. I do like the go one a lot,
> but that isn't possible in C. Also one of the thing I would like to
> see in the long term is that with the support for multiple main loop
> we get the ability to send a socket to another thread and manage to
> scale better.

node.js seems to be the closer to what EFL is following.

Go is a different approach since they simplify they stuff by
leveraging the goroutines to spawn "threads" and channels to
synchronize them.



-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to