[Python-ideas] PEP 3156: Transport.sendfile

Giampaolo Rodolà g.rodola at gmail.com
Fri Jan 25 21:44:14 CET 2013


In principle os.sendfile() is not too different than socket.send():
they share the same return value (no. of bytes sent) and errors, hence
it's pretty straightforward to implement (the user could even just
override Transport.write() him/herself).
Nonetheless there are other subtle differences (e.g. it works with
regular (mmap-like) files only) so that deciding whether to use send()
or sendfile() behind the curtains is not a good idea.
Transport class should probably provide a separate method (other than write()).
Also, I think that *at this point* thinking about adding sendfile()
into Tulip is probably premature.

--- Giampaolo

http://code.google.com/p/pyftpdlib/
http://code.google.com/p/psutil/
http://code.google.com/p/pysendfile/


2013/1/25 Nikolay Kim <fafhrd91 at gmail.com>:
>
> On Jan 25, 2013, at 12:04 PM, Guido van Rossum <guido at python.org> wrote:
>
> On Fri, Jan 25, 2013 at 10:11 AM, Nikolay Kim <fafhrd91 at gmail.com> wrote:
>>
>>
>> On Jan 25, 2013, at 10:08 AM, Guido van Rossum <guido at python.org> wrote:
>>
>> On Fri, Jan 25, 2013 at 10:03 AM, Nikolay Kim <fafhrd91 at gmail.com> wrote:
>>>
>>>
>>> I think Transport needs 'sendfile' api, something like:
>>>
>>>    @tasks.coroutine
>>>    def sendfile(self, fd, offset, nbytes):
>>>       ….
>>>
>>> otherwise it is impossible to implement sendfile without breaking
>>> transport encapsulation
>>
>>
>> Really? Can't the user write this themselves? What's wrong with this:
>>
>> while True:
>>   data = os.read(fd, 16*1024)
>>   if not data: break
>>   transport.write(data)
>>
>> (Perhaps augmented with a way to respond to pause() requests.)
>>
>>
>> i mean 'os.sendfile()', zero-copy sendfile.
>
>
> I see (http://docs.python.org/dev/library/os.html#os.sendfile).
>
> Hm, that function is so platform-specific that we might as well force users
> to do it this way:
>
> sock = transport.get_extra_info("socket")
> if sock is not None:
>   os.sendfile(sock.fileno(), ......)
> else:
>   <use write() like I suggested above>
>
>
> there should some kind of way to flush write buffer or write callbacks.
>
> sock = transport.get_extra_info("socket")
> if sock is not None:
>    os.sendfile(sock.fileno(), ......)
> else:
>    yield from transport.write_buffer_flush()
>    <use of write() method>
>
>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas
>



More information about the Python-ideas mailing list