mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Use TCP_CORK to improve throughput for large file transfers
This commit is contained in:
parent
4ffda3300c
commit
c8f1d11e80
@ -553,8 +553,8 @@ class HTTPPair(object):
|
|||||||
self.simple_response(httplib.PRECONDITION_FAILED)
|
self.simple_response(httplib.PRECONDITION_FAILED)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
with self.conn.corked:
|
||||||
self.send_headers()
|
self.send_headers()
|
||||||
|
|
||||||
if self.method != 'HEAD':
|
if self.method != 'HEAD':
|
||||||
output.commit(self.conn.socket_file)
|
output.commit(self.conn.socket_file)
|
||||||
self.conn.socket_file.flush()
|
self.conn.socket_file.flush()
|
||||||
|
@ -15,7 +15,7 @@ from io import DEFAULT_BUFFER_SIZE, BytesIO
|
|||||||
from calibre.srv.errors import NonHTTPConnRequest, MaxSizeExceeded
|
from calibre.srv.errors import NonHTTPConnRequest, MaxSizeExceeded
|
||||||
from calibre.srv.http import http_communicate
|
from calibre.srv.http import http_communicate
|
||||||
from calibre.srv.opts import Options
|
from calibre.srv.opts import Options
|
||||||
from calibre.srv.utils import socket_errors_to_ignore, socket_error_eintr, socket_errors_nonblocking
|
from calibre.srv.utils import socket_errors_to_ignore, socket_error_eintr, socket_errors_nonblocking, Corked
|
||||||
from calibre.utils.socket_inheritance import set_socket_inherit
|
from calibre.utils.socket_inheritance import set_socket_inherit
|
||||||
from calibre.utils.logging import ThreadSafeLog
|
from calibre.utils.logging import ThreadSafeLog
|
||||||
|
|
||||||
@ -330,6 +330,7 @@ class Connection(object): # {{{
|
|||||||
def __init__(self, server_loop, socket):
|
def __init__(self, server_loop, socket):
|
||||||
self.server_loop = server_loop
|
self.server_loop = server_loop
|
||||||
self.socket = socket
|
self.socket = socket
|
||||||
|
self.corked = Corked(socket)
|
||||||
self.socket_file = SocketFile(socket)
|
self.socket_file = SocketFile(socket)
|
||||||
|
|
||||||
def nonhttp_communicate(self, data):
|
def nonhttp_communicate(self, data):
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import errno
|
import errno, socket
|
||||||
from urlparse import parse_qs
|
from urlparse import parse_qs
|
||||||
import repr as reprlib
|
import repr as reprlib
|
||||||
from email.utils import formatdate
|
from email.utils import formatdate
|
||||||
@ -107,4 +107,17 @@ socket_errors_to_ignore = error_codes( # errors indicating a closed connection
|
|||||||
socket_errors_nonblocking = error_codes(
|
socket_errors_nonblocking = error_codes(
|
||||||
'EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK')
|
'EAGAIN', 'EWOULDBLOCK', 'WSAEWOULDBLOCK')
|
||||||
|
|
||||||
|
class Corked(object):
|
||||||
|
|
||||||
|
' Context manager to turn on TCP corking. Ensures maximum throughput for large logical packets. '
|
||||||
|
|
||||||
|
def __init__(self, sock):
|
||||||
|
self.sock = sock if hasattr(socket, 'TCP_CORK') else None
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
if self.sock is not None:
|
||||||
|
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_CORK, 1)
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
if self.sock is not None:
|
||||||
|
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_CORK, 0)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user