emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PATCH: add support for TCP_NODELAY on network streams


From: Robert Pluim
Subject: Re: PATCH: add support for TCP_NODELAY on network streams
Date: Wed, 11 Dec 2024 13:45:34 +0100

>>>>> On Wed, 11 Dec 2024 11:51:27 +0100, Eric Marsden 
>>>>> <eric.marsden@risk-engineering.org> said:

    Eric> Hi,
    Eric> The attached patch adds support for the socket option TCP_NODELAY,
    Eric> to disable Nagle's algorithm. This means that network segments are
    Eric> sent as soon as possible, even when they contain little data. This
    Eric> reduces network latency on the network connection, but can lead to
    Eric> many small packets being sent.

    Eric> I have only tested on Linux/AMD64, but support for this socket option
    Eric> is very widespread.

If setting it fails you can get an error, so thatʼs not a big deal. I
should be able to verify it on macOS later this week.

    Eric> My motivation for adding this support is that Emacs is very slow
    Eric> when connecting to the PostgreSQL database over the network, using
    Eric> my pg-el library, and is unable to saturate CPU when sending a
    Eric> stream of messages. It is much faster when using a local Unix
    Eric> connection and saturates CPU.

    Eric> With this patch, a test case that takes 911 seconds goes down to
    Eric> 76 seconds (x 12 speedup).

    Eric> Eric

ENOCOMMITMESSAGE

    Eric> diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
    Eric> index 79ef959ae65..93ac5a6aa7d 100644
    Eric> --- a/doc/lispref/processes.texi
    Eric> +++ b/doc/lispref/processes.texi
    Eric> @@ -3090,6 +3090,13 @@ Network Options
    Eric>  may be a period of time after the last use of that port (by any
    Eric>  process on the host) where it is not possible to make a new server on
    Eric>  that port.
    Eric> +
    Eric> +@item :nodelay @var{nodelay-flag}
    Eric> +If @var{nodelay-flag} is non-@code{nil}, the @code{TCP_NODELAY} 
option
    Eric> +is enabled on the socket. This disables the Nagle algorithm, meaning
    Eric> +that network segments are sent as soon as possible, even when they
    Eric> +contain little data. This reduces network latency on the network
    Eric> +connection, but can lead to many small packets being sent.
    Eric>  @end table
 
    Eric>  @defun set-network-process-option process option value &optional 
no-error
    Eric> diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
    Eric> index f058fc48cc7..07eb4690fce 100644
    Eric> --- a/lisp/emacs-lisp/bytecomp.el
    Eric> +++ b/lisp/emacs-lisp/bytecomp.el
    Eric> @@ -6049,8 +6049,8 @@ bytecomp--check-keyword-args
    Eric>              :buffer :host :service :type :family :local :remote 
:coding
    Eric>              :nowait :noquery :stop :filter :filter-multibyte 
:sentinel
    Eric>              :log :plist :tls-parameters :server :broadcast :dontroute
    Eric> -            :keepalive :linger :oobinline :priority :reuseaddr 
:bindtodevice
    Eric> -            :use-external-socket)
    Eric> +            :keepalive :linger :oobinline :priority :reuseaddr 
:nodelay
    Eric> +            :bindtodevice :use-external-socket)
    Eric>            '(:name :service))))

I think you need to update the docstring of `make-network-process' as
well, as itʼs possible to set options on process creation.

    Eric>  (provide 'byte-compile)
    Eric> diff --git a/src/process.c b/src/process.c
    Eric> index b71ba3daf2d..0b994d6c5b7 100644
    Eric> --- a/src/process.c
    Eric> +++ b/src/process.c
    Eric> @@ -38,6 +38,7 @@ Copyright (C) 1985-1988, 1993-1996, 1998-1999, 
2001-2024 Free Software
    Eric>  #include <sys/socket.h>
    Eric>  #include <netdb.h>
    Eric>  #include <netinet/in.h>
    Eric> +#include <netinet/tcp.h>
    Eric>  #include <arpa/inet.h>
 
    Eric>  #else
    Eric> @@ -2860,6 +2861,9 @@ DEFUN ("set-process-datagram-address", 
Fset_process_datagram_address, Sset_proce
    Eric>  #endif
    Eric>  #ifdef SO_REUSEADDR
    Eric>      { ":reuseaddr", SOL_SOCKET, SO_REUSEADDR, SOPT_BOOL, 
OPIX_REUSEADDR },
    Eric> +#endif
    Eric> +#ifdef TCP_NODELAY
    Eric> +    { ":nodelay", IPPROTO_TCP, TCP_NODELAY, SOPT_BOOL, OPIX_MISC },
    Eric>  #endif
    Eric>      { 0, 0, 0, SOPT_UNKNOWN, OPIX_NONE }
    Eric>    };

Iʼm not sure why we have a separate field for the option type, when the
only socket option that gets special treatment is :reuseaddr. Oh well,
hysterical raisins :-)

Robert
-- 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]