• Re: Apache + mod_php performance

    From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Sep 25 12:25:20 2024
    On 2024-09-24, Arne Vajh°j <arne@vajhoej.dk> wrote:
    I am not impressed by Apache + mod_php performance on VMS.


    Is the PHP FPM option available to you on VMS ?

    https://www.php.net/manual/en/install.fpm.php

    If it is, be aware that .htaccess no longer works to control PHP when
    it is in FPM mode and you need to use .user.ini files instead:

    https://www.php.net/manual/en/configuration.file.per-user.php

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Sep 25 12:48:46 2024
    In article <vcvmu1$3cnv1$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/24/2024 5:09 PM, Dan Cross wrote:
    In article <vcv0bl$39mnj$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    I am not impressed by Apache + mod_php performance on VMS.

    The basic numbers I see (simple PHP code for getting some data
    out of a MySQL database and displaying) are:

    Apache + CGI : 4 req/sec = 240 req/min
    Apache + mod_php : 11 req/sec = 660 req/min
    Tomcat + Quercus : 127 req/sec = 7620 req/min

    (VMS x86-64 9.2-2, Apache 2.4-58, Berryman PHP 8.1,
    Java 8u372, Tomcat 8.5-89, Quercus 4.0)

    That CGI is slow is no surprise. Using CGI for performance
    is like doing 100 meter crawl dressed in medieval armor.

    But I had expected much better numbers for mod_php. Instead
    of the actual x2.5 and x10 I had expected like x10 and x2.5
    between the three.

    Anyone having any ideas for why it is like this and what
    can be done about it?

    Did you try running your test script under the PHP interpreter
    directly, without the web stack? What kind of QPS numbers do
    you see if it's just PHP talking to MySQL?

    Just executing the same PHP code in a loop give much higher
    performance.

    Single process : 158 executions per second = 9480 executions per minute

    And multi process could probably get significantly higher.

    So this suggests that your PHP code, by itself, is not the
    bottleneck, though it remains unclear to me what you mean when
    you say, "just executing the same PHP code in a loop...": does
    this mean that you're running the PHP interpreter itself in a
    loop? As in, starting it fresh on every iteration? Or does
    this mean that you've got a loop inside the PHP program that
    runs your test and you're measuring the throughput of that? And
    is this standalone, or executed under the web framework? That
    is, are you running this under Apache and hitting some query
    that then causes the PHP interpreter to repeatedly query the
    database?

    With no further details, I'd wonder if you're not caching
    connections to the database between queries.

    Does not matter.

    Surely it does. If, for whatever reason, you're not holding
    onto the connection to the database between queries, but rather, re-establishing it each time, that will obviously have overhead
    that will impact performance.

    Or perhaps you're saying this because of some unstated
    assumption alluded to in the questions above?

    I just found out that Tomcat+Quercus numbers get even higher
    after some warmup.

    no db con pool db con pool
    Apache + CGI 4 N/A
    Apache + mod_php 11 11
    Tomcat + Quercus 208 214

    That's nice, but that seems irrelevant to the question of why
    PHP under Apache is so slow.

    Perhaps a simpler question: what sort of throughput does Apache
    on VMS give you if you just hit a simple static resource
    repeatedly?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Sep 25 09:24:06 2024
    On 9/25/2024 8:25 AM, Simon Clubley wrote:
    On 2024-09-24, Arne Vajhøj <arne@vajhoej.dk> wrote:
    I am not impressed by Apache + mod_php performance on VMS.

    Is the PHP FPM option available to you on VMS ?

    I don't see anything in neither Apache or PHP to
    indicate so.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Sep 25 11:49:13 2024
    On 9/25/2024 8:48 AM, Dan Cross wrote:
    In article <vcvmu1$3cnv1$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/24/2024 5:09 PM, Dan Cross wrote:
    In article <vcv0bl$39mnj$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    I am not impressed by Apache + mod_php performance on VMS.

    The basic numbers I see (simple PHP code for getting some data
    out of a MySQL database and displaying) are:

    Apache + CGI : 4 req/sec = 240 req/min
    Apache + mod_php : 11 req/sec = 660 req/min
    Tomcat + Quercus : 127 req/sec = 7620 req/min

    (VMS x86-64 9.2-2, Apache 2.4-58, Berryman PHP 8.1,
    Java 8u372, Tomcat 8.5-89, Quercus 4.0)

    That CGI is slow is no surprise. Using CGI for performance
    is like doing 100 meter crawl dressed in medieval armor.

    But I had expected much better numbers for mod_php. Instead
    of the actual x2.5 and x10 I had expected like x10 and x2.5
    between the three.

    Anyone having any ideas for why it is like this and what
    can be done about it?

    Did you try running your test script under the PHP interpreter
    directly, without the web stack? What kind of QPS numbers do
    you see if it's just PHP talking to MySQL?

    Just executing the same PHP code in a loop give much higher
    performance.

    Single process : 158 executions per second = 9480 executions per minute

    And multi process could probably get significantly higher.

    So this suggests that your PHP code, by itself, is not the
    bottleneck,

    The PHP code is very simple: read 3 rows from a database table
    and output 35 lines of HTML.

    though it remains unclear to me what you mean when
    you say, "just executing the same PHP code in a loop...": does
    this mean that you're running the PHP interpreter itself in a
    loop? As in, starting it fresh on every iteration? Or does
    this mean that you've got a loop inside the PHP program that
    runs your test and you're measuring the throughput of that? And
    is this standalone, or executed under the web framework? That
    is, are you running this under Apache and hitting some query
    that then causes the PHP interpreter to repeatedly query the
    database?

    PHP script with a loop executing the same code as the web
    request inside the loop. PHP script run command line.
    No Apache or mod_php involved.

    With no further details, I'd wonder if you're not caching
    connections to the database between queries.

    Does not matter.

    Surely it does. If, for whatever reason, you're not holding
    onto the connection to the database between queries, but rather, re-establishing it each time, that will obviously have overhead
    that will impact performance.

    Or perhaps you're saying this because of some unstated
    assumption alluded to in the questions above?

    I am saying this because the numbers were the same. 11 req/sec
    in both cases.

    I just found out that Tomcat+Quercus numbers get even higher
    after some warmup.

    no db con pool db con pool
    Apache + CGI 4 N/A
    Apache + mod_php 11 11
    Tomcat + Quercus 208 214

    That's nice, but that seems irrelevant to the question of why
    PHP under Apache is so slow.

    You brought up the topic, so I tested.

    Perhaps a simpler question: what sort of throughput does Apache
    on VMS give you if you just hit a simple static resource
    repeatedly?

    Now it becomes interesting.

    nop.php also gives 11 req/sec.

    And nop.txt also gives 11 req/sec.

    So the arrow is definitely pointing towards Apache.

    So either something to speed up Apache or switching to WASD or OSU.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Sep 25 18:41:17 2024
    In article <vd1bdp$3npm3$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 8:48 AM, Dan Cross wrote:
    [snip]
    Just executing the same PHP code in a loop give much higher
    performance.

    Single process : 158 executions per second = 9480 executions per minute

    And multi process could probably get significantly higher.

    So this suggests that your PHP code, by itself, is not the
    bottleneck,

    The PHP code is very simple: read 3 rows from a database table
    and output 35 lines of HTML.

    though it remains unclear to me what you mean when
    you say, "just executing the same PHP code in a loop...": does
    this mean that you're running the PHP interpreter itself in a
    loop? As in, starting it fresh on every iteration? Or does
    this mean that you've got a loop inside the PHP program that
    runs your test and you're measuring the throughput of that? And
    is this standalone, or executed under the web framework? That
    is, are you running this under Apache and hitting some query
    that then causes the PHP interpreter to repeatedly query the
    database?

    PHP script with a loop executing the same code as the web
    request inside the loop. PHP script run command line.
    No Apache or mod_php involved.

    So PHP talking to your database seems fine, then.

    With no further details, I'd wonder if you're not caching
    connections to the database between queries.

    Does not matter.

    Surely it does. If, for whatever reason, you're not holding
    onto the connection to the database between queries, but rather,
    re-establishing it each time, that will obviously have overhead
    that will impact performance.

    Or perhaps you're saying this because of some unstated
    assumption alluded to in the questions above?

    I am saying this because the numbers were the same. 11 req/sec
    in both cases.

    Oh, I see what you mean now. That was a statement of fact based
    on your findings, not an assertion. Sorry, I missed your "db
    con pool" numbers in your previous post.

    I just found out that Tomcat+Quercus numbers get even higher
    after some warmup.

    no db con pool db con pool
    Apache + CGI 4 N/A
    Apache + mod_php 11 11
    Tomcat + Quercus 208 214

    That's nice, but that seems irrelevant to the question of why
    PHP under Apache is so slow.

    You brought up the topic, so I tested.

    Hmm, I just went back and looked at the thread, and I don't see
    where I asked about Tomcat/Quercus.

    Perhaps a simpler question: what sort of throughput does Apache
    on VMS give you if you just hit a simple static resource
    repeatedly?

    Now it becomes interesting.

    nop.php also gives 11 req/sec.

    And nop.txt also gives 11 req/sec.

    So the arrow is definitely pointing towards Apache.

    I should think so. Lesson #1: always verify your base
    assumptions when investigating something like this.

    So either something to speed up Apache or switching to WASD or OSU.

    Well, the question now becomes, "what makes Apache so slow?"

    I would concentrate on your nop.txt test; I assume that's a
    small (possibly empty) text file and as an example has the
    fewest number of variables.

    Do your logs give any indications of what might be going on?
    For example, do the logs have host names in them, possibly
    implying your stalling on reverse DNS lookups or something
    similar?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Sep 25 17:10:43 2024
    On 9/25/2024 2:41 PM, Dan Cross wrote:
    In article <vd1bdp$3npm3$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 8:48 AM, Dan Cross wrote:
    Perhaps a simpler question: what sort of throughput does Apache
    on VMS give you if you just hit a simple static resource
    repeatedly?

    Now it becomes interesting.

    nop.php also gives 11 req/sec.

    And nop.txt also gives 11 req/sec.

    So the arrow is definitely pointing towards Apache.

    I should think so. Lesson #1: always verify your base
    assumptions when investigating something like this.

    So either something to speed up Apache or switching to WASD or OSU.

    Well, the question now becomes, "what makes Apache so slow?"

    I would concentrate on your nop.txt test; I assume that's a
    small (possibly empty) text file and as an example has the
    fewest number of variables.

    Do your logs give any indications of what might be going on?
    For example, do the logs have host names in them, possibly
    implying your stalling on reverse DNS lookups or something
    similar?

    Just logging IP address.

    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Sep 25 17:22:18 2024
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    But the system did not like further increases.

    And in case someone wonders what "did not like" means:

    $ anal/crash

    OpenVMS system dump analyzer
    ...analyzing an x86-64 interleaved memory dump...

    %SDA-W-DUMPINCOMPL, the dump file write was not completed
    %SDA-I-LMBEMPTY, empty "Non-Key Global Pages" LMB in file #1 at VBN 000006DE %SDA-W-NOTSAVED, some processes not found in dump file
    Dump taken on 25-SEP-2024 15:27:12.64 using version V9.2-2
    RESEXH, Resources exhausted, system shutting down

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Sep 25 17:17:32 2024
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    Apache on VMS is prefork MPM. Yuck.

    Which puzzles me.

    VMS is a threading OS not a forking OS.

    And prefork MPM is really an early 90's traditional Unix design.

    Using worker MPM on VMS would make more sense IMHO.

    The best would probably have been to create a VMS MPM
    based on the WinNT MPM.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Sep 25 21:49:22 2024
    On Wed, 25 Sep 2024 17:17:32 -0400, Arne Vajhøj wrote:

    Using worker MPM on VMS would make more sense IMHO.

    Server-side proxy is the way to go.

    The suggestion to use PHP-FPM is basically along these lines, except that
    the whole FastCGI protocol is IMHO best considered “legacy” at this point. Proxying (or “reverse proxying”, if you prefer) makes use of standard
    HTTP, and easily supports extras like WebSocket connections.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Sep 25 19:14:58 2024
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    Does anyone know internals of Apache on VMS?

    Based on some messages in error_log it looks like
    it uses mailboxes APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between
    master process and a child process, then that could
    slow down things.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Sep 25 19:10:34 2024
    On 9/25/2024 6:24 PM, Lawrence D'Oliveiro wrote:
    On Wed, 25 Sep 2024 17:17:32 -0400, Arne Vajhøj wrote:
    Using worker MPM on VMS would make more sense IMHO.

    According to the docs
    <https://httpd.apache.org/docs/2.4/mod/worker.html>, this is a hybrid multithread/multiprocess model.

    Yes. And I think that would fit better with VMS.

    But threading won’t work with PHP, because mod_php isn’t threadsafe.

    The worker MPM works fine with PHP.

    Two different ways:
    A) Build mod_php and PHP extensions thread safe
    B) Use fcgi or fpm

    Option #A is common on Windows.

    Option #B is common on Linux.

    I think #A would fit better with VMS.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Sep 25 22:24:43 2024
    On Wed, 25 Sep 2024 17:17:32 -0400, Arne Vajhøj wrote:

    Using worker MPM on VMS would make more sense IMHO.

    According to the docs
    <https://httpd.apache.org/docs/2.4/mod/worker.html>, this is a hybrid multithread/multiprocess model. But threading won’t work with PHP, because mod_php isn’t threadsafe.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Sep 26 00:21:26 2024
    On Wed, 25 Sep 2024 19:10:34 -0400, Arne Vajhøj wrote:

    The worker MPM works fine with PHP.

    Two different ways:
    A) Build mod_php and PHP extensions thread safe
    B) Use fcgi or fpm

    Option #A is common on Windows.

    Option #B is common on Linux.

    I think #A would fit better with VMS.

    I don’t think the Windows option is known for good performance. Just
    saying ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Sep 25 20:57:44 2024
    On 9/25/2024 8:20 PM, Lawrence D'Oliveiro wrote:
    On Wed, 25 Sep 2024 19:14:58 -0400, Arne Vajhøj wrote:

    Based on some messages in error_log it looks like it uses mailboxes
    APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between master process and a
    child process, then that could slow down things.

    I also wonder about the difference in handling nondeterministic communication.

    On *nix systems, you have poll/select (also other options like epoll or kqueue, depending on the *nix variant) for monitoring multiple
    communication channels at once, and all your files/pipes/sockets are
    treated as byte streams.

    On VMS, you have to have async QIO calls pending on every channel that you want to monitor, and all the communication channels are treated as record- oriented.

    I don't recognize that.

    On VMS you can use select if using the socket API and
    IO$_SETMODE|IO$M_READATTN if using $QIO(W) API.

    And both socket API and $QIO(W) API are stream oriented.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Sep 26 00:20:23 2024
    On Wed, 25 Sep 2024 19:14:58 -0400, Arne Vajhøj wrote:

    Based on some messages in error_log it looks like it uses mailboxes APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between master process and a
    child process, then that could slow down things.

    I also wonder about the difference in handling nondeterministic
    communication.

    On *nix systems, you have poll/select (also other options like epoll or
    kqueue, depending on the *nix variant) for monitoring multiple
    communication channels at once, and all your files/pipes/sockets are
    treated as byte streams.

    On VMS, you have to have async QIO calls pending on every channel that you
    want to monitor, and all the communication channels are treated as record- oriented.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Sep 26 01:52:57 2024
    On Wed, 25 Sep 2024 20:57:44 -0400, Arne Vajhøj wrote:

    On VMS you can use select if using the socket API and IO$_SETMODE|IO$M_READATTN if using $QIO(W) API.

    That sends an AST to tell you there is something to read. Extra mechanism overhead.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 10:54:20 2024
    In article <66fc8d31$0$716$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 7:55 PM, Dan Cross wrote:
    In article <66fc58ce$0$708$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It makes even less sense to implement the protocol improperly
    and then blame the other side when it doesn't work the way you
    expect, wouldn't you agree?

    Not sending "Connection: close" header is perfectly valid.
    And it is the normal scenario.

    Indeed. Because persistent connections are the default in
    HTTP/1.1. If you want the server to close the connection after
    every request, which you said that you did, you would send
    `Connection: close`.

    Sending "Connection: close" with every request is the client
    way to disable keep alive. And the unusual scenario.

    Yes. Colloquially, we call persistent connections "keep alive".
    You were asked if your client was using keep-alive was disabled,
    and you said that it was. Clearly it was not.

    Disabling keep alive client side not surprisingly has
    the same effect as disabling keep alive server side.

    Indeed. I'm glad that you were able to recognize that, after
    suggesting that there was a "problem" when the server didn't
    close the connection when you didn't send `Connection: close`.
    Why would you expect it to?

    But while disabling keep alive server side makes sense
    then it doesn't make sense to disable it client side.

    Huh? The RFC is quite clear on the behavior of persistent
    connections and the use of the `Connection: close` header. You
    appear to have been sending HTTP/1.1 requests, sans header, and
    then asserting that there was a bug in the server software when
    it didn't behave as you expected. Were you unable to understand
    section 9.3 of RFC 9112, which I referred you to earlier? https://www.rfc-editor.org/rfc/rfc9112#name-persistence

    Again, it seems that the "bug" was yours.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dave Froble on Wed Oct 2 10:02:39 2024
    On 10/2/2024 9:31 AM, Dave Froble wrote:
    On 10/1/2024 4:17 PM, Arne Vajhøj wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble  <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It does if the server is holding the connection open, waiting for more.

    Not really.

    The real goal is to make it work well for users not to make the
    test program work well.

    Having the test program send "Connection: close" will improve
    performance for the test program.

    But it does not improve anything for the web browsers that
    does not send "Connection: close".

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Wed Oct 2 09:31:48 2024
    On 10/1/2024 4:17 PM, Arne Vajhøj wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    Arne


    It does if the server is holding the connection open, waiting for more.

    Not claiming this happens in the real world. Things aren't that clean.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dave Froble on Wed Oct 2 10:00:02 2024
    On 10/2/2024 9:45 AM, Dave Froble wrote:
    On 9/30/2024 9:25 PM, Arne Vajhøj wrote:
    On 9/30/2024 9:10 PM, Dave Froble wrote:
    Granted, starting up a new process involves some overhead.

    But it really depends upon the requirements.  The more use out of a
    process
    once it is started, the better overall performance.  If a group of
    worker
    processes is started once, then used for many tasks, then that overhead
    happens only once.  Perhaps once a day, week, month, and even year.
    There are
    various communication methods available on VMS.

    In the end, it comes down to the requirements.  An engineer must
    evaluate the
    task(s) and determine what methods will give adequate results.

    There are obviously a scale.

    But the Apache case is to start with 5 processes, start 145 new
    processes in a few seconds and then kill 140 again after maybe
    30-45 seconds. And repeat.

    Perhaps the real problem is using a poorly designed application,
    regardless of how popular it might be?

    Or taking code designed for a different OS and expecting
    it to work on another OS.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Wed Oct 2 09:45:33 2024
    On 9/30/2024 9:25 PM, Arne Vajhøj wrote:
    On 9/30/2024 9:10 PM, Dave Froble wrote:
    On 9/30/2024 8:33 PM, Arne Vajhøj wrote:
    On 9/30/2024 8:24 PM, Lawrence D'Oliveiro wrote:
    On Mon, 30 Sep 2024 19:50:38 -0400, Arne Vajhøj wrote:
    On 9/29/2024 11:15 PM, Lawrence D'Oliveiro wrote:
    On Sun, 29 Sep 2024 22:34:04 -0400, Arne Vajhøj wrote:
    But I am pretty sure that it will not work on VMS.

    That’s what I figured. VMS, like Windows, really wants you to use >>>>>> threads.

    For massive parallel processing on VMS then threads not
    processes is the way to go.

    Threads require shared memory, though. Processes allow you to have a mix >>>> of shared and private data, plus the use of IPC mechanisms like message >>>> passing. This makes for a looser coupling, which better suits the way
    massively parallel systems are built.

    It is undeniable that multiple processes are more loosely coupled
    than multiple threads.

    But efficiency is a problem. VMS does not do fork. Process creation
    is expensive on VMS. None of that fancy moving descriptors over
    Unix socket stuff.

    VMS got plenty of methods for IPC. A solution with a fixed number
    of processes doing IPC between each other may work fine.

    But the concept of constantly starting new processes and killing
    old processes is not going to perform great.

    Well, now, that is a rather bold statement.

    Sometimes I make such.

    :-)

    Granted, starting up a new process involves some overhead.

    But it really depends upon the requirements. The more use out of a process >> once it is started, the better overall performance. If a group of worker
    processes is started once, then used for many tasks, then that overhead
    happens only once. Perhaps once a day, week, month, and even year. There are
    various communication methods available on VMS.

    In the end, it comes down to the requirements. An engineer must evaluate the
    task(s) and determine what methods will give adequate results.

    There are obviously a scale.

    But the Apache case is to start with 5 processes, start 145 new
    processes in a few seconds and then kill 140 again after maybe
    30-45 seconds. And repeat.

    Arne




    Perhaps the real problem is using a poorly designed application, regardless of how popular it might be?

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Oct 2 10:08:46 2024
    On 10/2/2024 6:54 AM, Dan Cross wrote:
    In article <66fc8d31$0$716$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 7:55 PM, Dan Cross wrote:
    In article <66fc58ce$0$708$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It makes even less sense to implement the protocol improperly
    and then blame the other side when it doesn't work the way you
    expect, wouldn't you agree?

    Not sending "Connection: close" header is perfectly valid.
    And it is the normal scenario.

    Indeed. Because persistent connections are the default in
    HTTP/1.1. If you want the server to close the connection after
    every request, which you said that you did, you would send
    `Connection: close`.

    Sending "Connection: close" with every request is the client
    way to disable keep alive. And the unusual scenario.

    Yes. Colloquially, we call persistent connections "keep alive".
    You were asked if your client was using keep-alive was disabled,
    and you said that it was. Clearly it was not.

    I said that it was not using it. And it is not. It is just
    not informing the server that it has no intention of using it.

    Disabling keep alive client side not surprisingly has
    the same effect as disabling keep alive server side.

    Indeed. I'm glad that you were able to recognize that, after
    suggesting that there was a "problem" when the server didn't
    close the connection when you didn't send `Connection: close`.
    Why would you expect it to?

    I have never expected that.

    But while disabling keep alive server side makes sense
    then it doesn't make sense to disable it client side.

    Huh? The RFC is quite clear on the behavior of persistent
    connections and the use of the `Connection: close` header. You
    appear to have been sending HTTP/1.1 requests, sans header, and
    then asserting that there was a bug in the server software when
    it didn't behave as you expected. Were you unable to understand
    section 9.3 of RFC 9112, which I referred you to earlier? https://www.rfc-editor.org/rfc/rfc9112#name-persistence

    Again, it seems that the "bug" was yours.

    You are not making any sense.

    It is perfectly valid per RFS to make HTTP 1.1 connections
    without "Connection: close".

    It is the normal case.

    It is what browsers do.

    Changing the test client to always send "Connection: close"
    does improve performance for the test client.

    But it does not improve performance for the browsers that
    do not send "Connection: close".

    There is no point on improving test results for a test
    program by having the test program do something that the browsers
    it is simulating does not.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 10:09:23 2024
    On 10/1/2024 5:34 PM, Lawrence D'Oliveiro wrote:
    On Tue, 1 Oct 2024 16:17:18 -0400, Arne Vajhøj wrote:
    It does not really make any sense for the test client to send
    "Connection: close".

    I think you’re right, but it still should be closing the connection cleanly, so the server side can get notification of that.

    Browsers doesn't, so ...

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 14:32:11 2024
    In article <vdjjl2$37f8q$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 9:45 AM, Dave Froble wrote:
    On 9/30/2024 9:25 PM, Arne Vajhøj wrote:
    On 9/30/2024 9:10 PM, Dave Froble wrote:
    Granted, starting up a new process involves some overhead.

    But it really depends upon the requirements.  The more use out of a
    process
    once it is started, the better overall performance.  If a group of
    worker
    processes is started once, then used for many tasks, then that overhead >>>> happens only once.  Perhaps once a day, week, month, and even year.
    There are
    various communication methods available on VMS.

    In the end, it comes down to the requirements.  An engineer must
    evaluate the
    task(s) and determine what methods will give adequate results.

    There are obviously a scale.

    But the Apache case is to start with 5 processes, start 145 new
    processes in a few seconds and then kill 140 again after maybe
    30-45 seconds. And repeat.

    Perhaps the real problem is using a poorly designed application,
    regardless of how popular it might be?

    Or taking code designed for a different OS and expecting
    it to work on another OS.

    I don't see any evidence that leads me to believe that was
    actually a problem. I do see evidence that you assumed there
    was a problem where, in fact, one did not exist, and that you
    failed to investigate sufficiently before jumping to
    conclusions.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Wed Oct 2 14:29:27 2024
    In article <vdji17$38hdb$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/1/2024 4:17 PM, Arne Vajhøj wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It does if the server is holding the connection open, waiting for more.

    Which is precisely the behavior Arne observed, and is also what
    the RFC says the server should do.

    Not claiming this happens in the real world. Things aren't that clean.

    I decided to do what Arne was either unwilling or unable to do:
    connect to the server directly and observe its behavior. This
    is an example of the sort of problem report that Arne _should_
    have sent; had he given some useful details on the experimental
    setup he used, and his observed results, we probably could have
    been able to see his error much earlier, but he was rather
    cagey with details and this conversation dragged on. Anyway.

    I did not set Apache up under VMS, but instead, did so on
    FreeBSD. Everything is stock; installation was just via the
    normal `pkg install apache24`.

    I then created a simple text file under apache's DocumentRoot:

    ```
    : fbsd; cat /usr/local/www/apache24/data/nop.txt
    hi
    : fbsd;
    ```

    I verified that I could get that via `curl`:

    ```
    : fbsd; curl http://localhost/nop.txt
    hi
    : fbsd;
    ```

    (Note, that returns almost immediately.)

    To get a baseline on performance, I used the `ab` tool ("Apache
    Bench"). I hit it with 100,000 requests using 20 concurrent
    requestors.

    ```
    : fbsd; ab -c 20 -n 100000 http://localhost/nop.txt
    This is ApacheBench, Version 2.3 <$Revision: 1913912 $>
    Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/

    Benchmarking localhost (be patient)
    Completed 10000 requests
    Completed 20000 requests
    Completed 30000 requests
    Completed 40000 requests
    Completed 50000 requests
    Completed 60000 requests
    Completed 70000 requests
    Completed 80000 requests
    Completed 90000 requests
    Completed 100000 requests
    Finished 100000 requests


    Server Software: Apache/2.4.62
    Server Hostname: localhost
    Server Port: 80

    Document Path: /nop.txt
    Document Length: 3 bytes

    Concurrency Level: 20
    Time taken for tests: 1.247 seconds
    Complete requests: 100000
    Failed requests: 0
    Total transferred: 24900000 bytes
    HTML transferred: 300000 bytes
    Requests per second: 80200.05 [#/sec] (mean)
    Time per request: 0.249 [ms] (mean)
    Time per request: 0.012 [ms] (mean, across all concurrent requests) Transfer rate: 19501.77 [Kbytes/sec] received

    Connection Times (ms)
    min mean[+/-sd] median max
    Connect: 0 0 0.0 0 0
    Processing: 0 0 0.0 0 0
    Waiting: 0 0 0.0 0 0
    Total: 0 0 0.0 0 0

    Percentage of the requests served within a certain time (ms)
    50% 0
    66% 0
    75% 0
    80% 0
    90% 0
    95% 0
    98% 0
    99% 0
    100% 0 (longest request)
    : fbsd;
    ```

    I then observed what happened if I connected directly to the
    HTTP server and sent commands. I used the "netcat" (`nc`)
    command to connect to the HTTP server port, and issued a
    `GET` request via a pipe; I timed the `nc` command to see how
    long it took until the server disconnected.

    ```
    : fbsd; (printf "GET /nop.txt HTTP/1.1\r\nHost: localhost\r\n\r\n") | time nc localhost 80
    HTTP/1.1 200 OK
    Date: Wed, 02 Oct 2024 14:00:42 GMT
    Server: Apache/2.4.62 (FreeBSD)
    Last-Modified: Wed, 02 Oct 2024 13:44:20 GMT
    ETag: "3-6237ea2939a43"
    Accept-Ranges: bytes
    Content-Length: 3
    Content-Type: text/plain

    hi
    nc localhost 80 0.00s user 0.00s system 0% cpu 5.106 total
    : fbsd;
    ```

    My observation was that the resposne to the query returned
    almost immediately (within milliseconds), and the server
    disconnected around the 5 second mark, as indicated by the
    `time` command.

    This, and having some familiarity with reading RFCs, makes clear
    what is going on: without sending the `Connection: close` header
    the server is waiting for the another request; eventually it
    times out closes the connection. Where does the 5 seconds come
    from, though? It's probably a configuration parameter, but let
    us see if we can verify. Using the "ripgrep" tool (`rg`), I
    search for the number "5" in the Apache configuration:

    ```
    : fbsd; rg '\b5\b' /usr/local/etc/apache24
    [snip]

    /usr/local/etc/apache24/extra/httpd-default.conf
    29:KeepAliveTimeout 5

    [snip]

    /usr/local/etc/apache24/extra/httpd-mpm.conf.sample
    29: StartServers 5
    30: MinSpareServers 5
    97: MinSpareThreads 5
    : fbsd;
    ```

    I cut out a number of irrelvant matches (magic numbers and MIME
    types and the like), but the output isn't that big, and
    certainly `KeepAliveTimeout` shines like a bright light in the
    middle of it. That matches our observed results, but what
    happens if I change it to, say, 20 seconds? I edit the config
    file and restart the server and re-run my test:

    ```
    : fbsd; (printf "GET /nop.txt HTTP/1.1\r\nHost: localhost\r\n\r\n") | time nc localhost 80
    HTTP/1.1 200 OK
    Date: Wed, 02 Oct 2024 14:19:50 GMT
    Server: Apache/2.4.62 (FreeBSD)
    Last-Modified: Wed, 02 Oct 2024 13:44:20 GMT
    ETag: "3-6237ea2939a43"
    Accept-Ranges: bytes
    Content-Length: 3
    Content-Type: text/plain

    hi
    nc localhost 80 0.00s user 0.00s system 0% cpu 20.317 total
    : fbsd;
    ```

    And there we have it. This behavior clearly matches what Arne
    saw, and we can speculate that the "problem" that Arne observed
    was almost certainly due to the default setting of
    `KeepAliveTimeout` on VMS being 20 seconds. I'd bet cookies to
    cake that, if Arne changed that value, he'd see different
    timeouts with his test client.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 14:41:20 2024
    In article <vdjk5e$37f8p$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 6:54 AM, Dan Cross wrote:
    In article <66fc8d31$0$716$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 7:55 PM, Dan Cross wrote:
    In article <66fc58ce$0$708$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It makes even less sense to implement the protocol improperly
    and then blame the other side when it doesn't work the way you
    expect, wouldn't you agree?

    Not sending "Connection: close" header is perfectly valid.
    And it is the normal scenario.

    Indeed. Because persistent connections are the default in
    HTTP/1.1. If you want the server to close the connection after
    every request, which you said that you did, you would send
    `Connection: close`.

    Sending "Connection: close" with every request is the client
    way to disable keep alive. And the unusual scenario.

    Yes. Colloquially, we call persistent connections "keep alive".
    You were asked if your client was using keep-alive was disabled,
    and you said that it was. Clearly it was not.

    I said that it was not using it. And it is not. It is just
    not informing the server that it has no intention of using it.

    So then it was, because it's the default to use it unless the
    client tells it otherwise, or you explicitly disable it in the
    server configuration.

    Disabling keep alive client side not surprisingly has
    the same effect as disabling keep alive server side.

    Indeed. I'm glad that you were able to recognize that, after
    suggesting that there was a "problem" when the server didn't
    close the connection when you didn't send `Connection: close`.
    Why would you expect it to?

    I have never expected that.

    Apparently you did. You said there was a "problem" when you
    made an HTTP/1.1 request without the `Connection: close` header.

    But while disabling keep alive server side makes sense
    then it doesn't make sense to disable it client side.

    Huh? The RFC is quite clear on the behavior of persistent
    connections and the use of the `Connection: close` header. You
    appear to have been sending HTTP/1.1 requests, sans header, and
    then asserting that there was a bug in the server software when
    it didn't behave as you expected. Were you unable to understand
    section 9.3 of RFC 9112, which I referred you to earlier?
    https://www.rfc-editor.org/rfc/rfc9112#name-persistence

    Again, it seems that the "bug" was yours.

    You are not making any sense.

    No, I'm afraid you are just confused.

    It is perfectly valid per RFS to make HTTP 1.1 connections
    without "Connection: close".

    It is the normal case.

    It is what browsers do.

    Changing the test client to always send "Connection: close"
    does improve performance for the test client.

    But it does not improve performance for the browsers that
    do not send "Connection: close".

    There is no point on improving test results for a test
    program by having the test program do something that the browsers
    it is simulating does not.

    I don't think you understand how the protocol works, or how a
    browser might use it. A browser will opportunistically reuse a
    persistent connection; evidently, your test program does not.

    In your test program, you had some number of threads sending
    requests to the server; those requests did not include a
    `Connection: close` header. But those threads received the
    expected response from the server, but then paused waiting for
    the server to close the connection, which it did after the
    `KeepAliveTimeout` number of seconds. What did you expect the
    server to do differently? Why you were surprised by the results
    you observed?

    For some strange and unexplained reason, you then concluded that
    the server had a bug. That makes no sense.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 14:47:30 2024
    In article <vdjjpv$37f8q$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 9:31 AM, Dave Froble wrote:
    On 10/1/2024 4:17 PM, Arne Vajhøj wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble  <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It does if the server is holding the connection open, waiting for more.

    Not really.

    The real goal is to make it work well for users not to make the
    test program work well.

    Having the test program send "Connection: close" will improve
    performance for the test program.

    But it does not improve anything for the web browsers that
    does not send "Connection: close".

    If a web browser sends an HTTP/1.1 request without the
    `Connection: close` header, it's likely that it wants that
    connection to be persistent, presumably so that it can use it
    for another request.

    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    Do you understand that the protocol definition specifies that
    the connection should be persistent unless the client says
    differently via the `Connection: close` header?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 15:07:44 2024
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do? And what is the "problem" that
    you are imagining here? Please be specific. Better yet, why
    don't you post your test program somewhere so folks who
    understand how the protocol works can look at it and point out
    the bug?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Oct 2 10:53:56 2024
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    In article <vdjjpv$37f8q$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 9:31 AM, Dave Froble wrote:
    On 10/1/2024 4:17 PM, Arne Vajhøj wrote:
    On 10/1/2024 3:45 PM, Dan Cross wrote:
    In article <vd9mqn$1cm1v$1@dont-email.me>,
    Dave Froble  <davef@tsoft-inc.com> wrote:
    On 9/27/2024 9:11 PM, Arne Vajhøj wrote:
    [snip]
    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Feature ...

    Yes, it is a feature, despite this report of a non-problem.

    In this case, later posts revealed the real culprit: Arne's test
    program did not follow the protocol, and was not sending
    `Connection: close` with an HTTP/1.1 request; in response, the
    server (correctly) kept the connection open waiting for the
    client to send another request.

    It does not really make any sense for the test client
    to send "Connection: close".

    It does if the server is holding the connection open, waiting for more.

    Not really.

    The real goal is to make it work well for users not to make the
    test program work well.

    Having the test program send "Connection: close" will improve
    performance for the test program.

    But it does not improve anything for the web browsers that
    does not send "Connection: close".

    If a web browser sends an HTTP/1.1 request without the
    `Connection: close` header, it's likely that it wants that
    connection to be persistent, presumably so that it can use it
    for another request.

    That is the purpose.

    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Oct 2 11:20:53 2024
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

    And what is the "problem" that
    you are imagining here? Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Oct 2 11:30:26 2024
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj  <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

                                And what is the "problem" that
    you are imagining here?  Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    And the numbers are low due to keep alive.

    Basically Apache on VMS keep an entire process around for
    a kept alive connection.

    When Apache configuration does not allow more
    processes to start then new requests get queued
    until keep alive starts to timeout and processes
    free up.

    And one can not just increase number of processes
    allowed because they use 25 MB each. The system
    runs out of memory/pagefile fast.

    An it does not help that if Apache kills some
    processes then it is expensive to start a new one again,
    which means that either the large number of memory
    consuming processes are kept around or Apache
    will be slow to adjust to increasing load.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Oct 2 11:32:58 2024
    Summary numbers and analysis.

    no db con pool db con pool
    Apache + CGI 4 req/sec N/A
    Apache + mod_php (cfg A) 11 req/sec 11 req/sec
    Apache + mod_php (cfg B) 22 req/sec 22 req/sec
    Apache + mod_php (cfg C) 94 req/sec 103 req/sec
    Apache + mod_php (cfg D) 85 req/sec 83 req/sec
    Tomcat + Quercus 208 req/sec 214 req/sec
    Apache + mod_php (win) ~1200 req/sec ~6000 req/sec

    Note that Windows got more CPU and RAM than VMS, so not really
    comparable. With resources similar to VMS then I would expect
    maybe 1/10'th of througput.

    I have not tested Apache on Linux, but I would expect the numbers
    to be even higher than Windows - it is what is used by most of the web.

    config KeepAlive KeepALiveTimeout MaxSpareServers MaxClients
    A On 15 10 150
    B On 15 50 300
    C Off N/A 50 300
    D On 1 300 300

    A is default config
    B is as many resources that my VMS system could support
    C is keep alive disabled
    D is keep alive limited

    Allocating as many resources as one can spare make sense. But it can
    be a lot of resources. Expect memory usage to be MaxClients * 25 MB.

    But for the rest then as usual there are tradeoffs.

    config browser benefit browser benefit througput
    keep alive keep alive
    within page across pages
    B yes yes low
    C no no acceptable
    D yes no almost acceptable

    I consider 100 req/sec as acceptable. Good would be 200-300 which
    is what Quercus can do and the exterpolation from:
    (througput PHP Apache / throughput static Apache) * throughput
    static OSU

    I suspect that most will find D attractive.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 15:42:54 2024
    In article <vdjocl$37f8p$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    Does the client close the connection? Why do you think that it
    moves on to the next request?

    Despite repeated requests for more information, you haven't told
    us much of anything at all about the client or your setup. I
    gather that the client is something you wrote yourself; why not
    put that code somewhere for someone else to inspect and
    understand?

    That request will block if the server can't serve it
    because all processes are busy.

    You haven't shown sufficient evidence to support that
    conclusion; perhaps you have it, but you haven't shared
    it. Have you even attempted any of the debugging steps
    I suggested to you, for instance?

    And what is the "problem" that
    you are imagining here? Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    Yes. I don't see any evidence to support your claims.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 15:45:00 2024
    In article <vdjoui$37f8q$4@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj  <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

                                And what is the "problem" that
    you are imagining here?  Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    And the numbers are low due to keep alive.

    Basically Apache on VMS keep an entire process around for
    a kept alive connection.

    When Apache configuration does not allow more
    processes to start then new requests get queued
    until keep alive starts to timeout and processes
    free up.

    And one can not just increase number of processes
    allowed because they use 25 MB each. The system
    runs out of memory/pagefile fast.

    An it does not help that if Apache kills some
    processes then it is expensive to start a new one again,
    which means that either the large number of memory
    consuming processes are kept around or Apache
    will be slow to adjust to increasing load.

    These are all claims not supported by the _actual_ evidence that
    you've posted here. While your argument is plausible on the
    face of it, how did you arrive at this conclusion?

    Post more details about your setup and experiments.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Oct 2 12:58:46 2024
    On 10/2/2024 12:25 PM, Dan Cross wrote:
    In article <vdjpps$fk2$2@reader1.panix.com>,
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <vdjoui$37f8q$4@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj  <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close` >>>>>>> with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

    >                            And what is the "problem" that
    > you are imagining here?  Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    And the numbers are low due to keep alive.

    Basically Apache on VMS keep an entire process around for
    a kept alive connection.

    When Apache configuration does not allow more
    processes to start then new requests get queued
    until keep alive starts to timeout and processes
    free up.

    And one can not just increase number of processes
    allowed because they use 25 MB each. The system
    runs out of memory/pagefile fast.

    An it does not help that if Apache kills some
    processes then it is expensive to start a new one again,
    which means that either the large number of memory
    consuming processes are kept around or Apache
    will be slow to adjust to increasing load.

    These are all claims not supported by the _actual_ evidence that
    you've posted here. While your argument is plausible on the
    face of it, how did you arrive at this conclusion?

    Post more details about your setup and experiments.

    Let's dig a little deeper here and show that Arne's pro blem
    is not specific to VMS. Indeed, I can replicate something more
    or less like the results he showed on FreeBSD.

    I'm using "seige", which is another testing tool; here, I can
    force HTTP/1.1 and also enable keep-alive via options in its
    configuration file. With 25 worker threads 1000 queries each,
    I easily saturate the number of workers and hang waiting for
    timeouts, tanking throughput.

    So...Not a VMS problem at all.

    The basic mechanism is not VMS specific at all.

    I assume that it is inherent in prefork MPM on all
    platforms and other servers that use a similar
    worker process model.

    As I have noted a couple of times then back when
    prefork MPM was common (20 years ago) then the question
    about whether to have keep alive on or off was
    often discussed.

    The problem does not seem to impact newer designs
    using threads. They obviously still need to keep
    the connection open, but I guess they do some
    select/poll/epoll/whatever to detect when there is a
    new request to keep resource usage minimal.

    But the mechanism hits VMS harder than other platforms.
    The *nix fork is way more efficient than SYS$CREPRC for
    creating those hundreds or thousands of worker processes.

    We can have fewer worker processes on VMS and it creates
    longer delay to start them up.

    As described above.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to Dan Cross on Wed Oct 2 16:25:08 2024
    In article <vdjpps$fk2$2@reader1.panix.com>,
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In article <vdjoui$37f8q$4@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj  <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

                                And what is the "problem" that
    you are imagining here?  Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    And the numbers are low due to keep alive.

    Basically Apache on VMS keep an entire process around for
    a kept alive connection.

    When Apache configuration does not allow more
    processes to start then new requests get queued
    until keep alive starts to timeout and processes
    free up.

    And one can not just increase number of processes
    allowed because they use 25 MB each. The system
    runs out of memory/pagefile fast.

    An it does not help that if Apache kills some
    processes then it is expensive to start a new one again,
    which means that either the large number of memory
    consuming processes are kept around or Apache
    will be slow to adjust to increasing load.

    These are all claims not supported by the _actual_ evidence that
    you've posted here. While your argument is plausible on the
    face of it, how did you arrive at this conclusion?

    Post more details about your setup and experiments.

    Let's dig a little deeper here and show that Arne's pro blem
    is not specific to VMS. Indeed, I can replicate something more
    or less like the results he showed on FreeBSD.

    I'm using "seige", which is another testing tool; here, I can
    force HTTP/1.1 and also enable keep-alive via options in its
    configuration file. With 25 worker threads 1000 queries each,
    I easily saturate the number of workers and hang waiting for
    timeouts, tanking throughput.

    So...Not a VMS problem at all.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 17:44:48 2024
    On 2024-10-01, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/1/2024 8:46 PM, Lawrence D'Oliveiro wrote:
    On Tue, 1 Oct 2024 19:46:53 -0400, Arne Vajh°j wrote:
    But any time one need to do anything time consuming in the GUI then it
    needs to be done in its own thread ...

    Note that ?cpu-intensive? and ?time-consuming? are not synonymous.
    Something can take a long time to complete, but not require much CPU time
    during that time, so running it in the main thread would be fine and have
    minimal impact.

    But how do you keep the GUI responsive if the event/main loop
    is doing something that is time consuming??


    You can add events to the main GTK loop (such as an I/O channel becoming
    ready) for GTK to listen on. Not sure if that is what Lawrence is thinking
    of.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 17:32:23 2024
    On 2024-10-01, Arne Vajh°j <arne@vajhoej.dk> wrote:

    If I look at Windows GUI applications that also runs on Linux then I see:

    FireFox (just 1 tab open) - 96 threads
    ThunderBird - 72 threads
    LibreOffice - 22 threads

    Is it different on Linux?


    What makes you think those extra threads are doing anything directly
    with the GUI ?

    Also, I thought Windows was a single-thread GUI model (at least it was
    back in the traditional Win32 days IIRC). Has that changed recently ?

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Oct 2 13:50:42 2024
    On 10/2/2024 1:44 PM, Simon Clubley wrote:
    On 2024-10-01, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/1/2024 8:46 PM, Lawrence D'Oliveiro wrote:
    On Tue, 1 Oct 2024 19:46:53 -0400, Arne Vajhøj wrote:
    But any time one need to do anything time consuming in the GUI then it >>>> needs to be done in its own thread ...

    Note that ?cpu-intensive? and ?time-consuming? are not synonymous.
    Something can take a long time to complete, but not require much CPU time >>> during that time, so running it in the main thread would be fine and have >>> minimal impact.

    But how do you keep the GUI responsive if the event/main loop
    is doing something that is time consuming??

    You can add events to the main GTK loop (such as an I/O channel becoming ready) for GTK to listen on. Not sure if that is what Lawrence is thinking of.

    So the event loop is not executing the long running task, but
    it is asking the OS to do something and moves on, and then the
    OS stuff an event into the vent loop when whatever is done?

    Lawrence actually posted a link to some code. I will have
    to take a look at that. Sometime.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Oct 2 13:46:54 2024
    On 10/2/2024 1:32 PM, Simon Clubley wrote:
    On 2024-10-01, Arne Vajhøj <arne@vajhoej.dk> wrote:
    If I look at Windows GUI applications that also runs on Linux then I see:

    FireFox (just 1 tab open) - 96 threads
    ThunderBird - 72 threads
    LibreOffice - 22 threads

    Is it different on Linux?

    What makes you think those extra threads are doing anything directly
    with the GUI ?

    Also, I thought Windows was a single-thread GUI model (at least it was
    back in the traditional Win32 days IIRC). Has that changed recently ?

    Maybe we are not talking about the same.

    Are we talking about how many threads can update the GUI
    widgets/controls or are we talking about how many threads
    in the GUI application?

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 17:52:35 2024
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.


    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive settings) or does it always create a brand-new connection for the next
    request ?

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Oct 2 13:57:51 2024
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive settings) or does it always create a brand-new connection for the next request ?

    New connection.

    It is simulating multiple browser instances.

    Browser #1 open connection to request the page - keep
    the connection alive, because it may want to use it later.

    Browser #2 open connection to request the page - keep
    the connection alive, because it may want to use it later.

    etc.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Oct 2 14:06:51 2024
    On 10/2/2024 11:32 AM, Arne Vajhøj wrote:
    Summary numbers and analysis.

                            no db con pool     db con pool
    Apache + CGI               4 req/sec           N/A Apache + mod_php (cfg A)  11 req/sec         11 req/sec
    Apache + mod_php (cfg B)  22 req/sec         22 req/sec
    Apache + mod_php (cfg C)  94 req/sec        103 req/sec
    Apache + mod_php (cfg D)  85 req/sec         83 req/sec
    Tomcat + Quercus         208 req/sec        214 req/sec
    Apache + mod_php (win) ~1200 req/sec      ~6000 req/sec

    Note that Windows got more CPU and RAM than VMS, so not really
    comparable. With resources similar to VMS then I would expect
    maybe 1/10'th of througput.

    I have not tested Apache on Linux, but I would expect the numbers
    to be even higher than Windows - it is what is used by most of the web.

    config       KeepAlive   KeepALiveTimeout     MaxSpareServers    MaxClients
      A             On             15                   10               150
      B             On             15                   50               300
      C             Off            N/A                  50               300
      D             On             1                   300               300

    A is default config
    B is as many resources that my VMS system could support
    C is keep alive disabled
    D is keep alive limited

    Allocating as many resources as one can spare make sense. But it can
    be a lot of resources. Expect memory usage to be MaxClients * 25 MB.

    But for the rest then as usual there are tradeoffs.

    config    browser benefit    browser benefit    througput
              keep alive         keep alive
              within page        across pages
       B          yes                yes               low
       C          no                 no                acceptable
       D          yes                no                almost acceptable

    I consider 100 req/sec as acceptable. Good would be 200-300 which
    is what Quercus can do and the exterpolation from:
        (througput PHP Apache / throughput static Apache) * throughput
    static OSU

    I suspect that most will find D attractive.

    What would be nice to have had was a MaxKeepAliveConnections
    config parameter.

    KeepAlive=On,MaxClients=300,KeepAliveTimeout=15,
    MaxKeepAliveConnections=150 would work like:
    * the first 150 clients get full 15 seconds keep alive
    * the last 150 clients would not get keep alive

    That would utilize keep alive for everyone at low volume,
    but turn off keep alive for some clients at high load
    to keep throughput up.

    That config parameter does not exist though.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 18:04:10 2024
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:32 PM, Simon Clubley wrote:
    On 2024-10-01, Arne Vajh°j <arne@vajhoej.dk> wrote:
    If I look at Windows GUI applications that also runs on Linux then I see: >>>
    FireFox (just 1 tab open) - 96 threads
    ThunderBird - 72 threads
    LibreOffice - 22 threads

    Is it different on Linux?

    What makes you think those extra threads are doing anything directly
    with the GUI ?

    Also, I thought Windows was a single-thread GUI model (at least it was
    back in the traditional Win32 days IIRC). Has that changed recently ?

    Maybe we are not talking about the same.

    Are we talking about how many threads can update the GUI
    widgets/controls or are we talking about how many threads
    in the GUI application?


    How many threads can _directly_ update the GUI widgets/controls.

    In Android that answer is exactly one, regardless of the number of
    additional threads the application is running.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 17:59:43 2024
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:44 PM, Simon Clubley wrote:
    On 2024-10-01, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/1/2024 8:46 PM, Lawrence D'Oliveiro wrote:
    On Tue, 1 Oct 2024 19:46:53 -0400, Arne Vajh°j wrote:
    But any time one need to do anything time consuming in the GUI then it >>>>> needs to be done in its own thread ...

    Note that ?cpu-intensive? and ?time-consuming? are not synonymous.
    Something can take a long time to complete, but not require much CPU time >>>> during that time, so running it in the main thread would be fine and have >>>> minimal impact.

    But how do you keep the GUI responsive if the event/main loop
    is doing something that is time consuming??

    You can add events to the main GTK loop (such as an I/O channel becoming
    ready) for GTK to listen on. Not sure if that is what Lawrence is thinking >> of.

    So the event loop is not executing the long running task, but
    it is asking the OS to do something and moves on, and then the
    OS stuff an event into the vent loop when whatever is done?


    If the long-running task is quickly kicking off some network request
    and then waiting for the result to arrive at some point in the future,
    then you can do all this in the GUI thread (provided you don't stall
    the GUI thread while creating the request).

    I have actually done this in the past with GTK on Linux.

    Still not sure if this is what Lawrence is thinking of however.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Oct 2 14:08:52 2024
    On 10/2/2024 2:04 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:32 PM, Simon Clubley wrote:
    On 2024-10-01, Arne Vajhøj <arne@vajhoej.dk> wrote:
    If I look at Windows GUI applications that also runs on Linux then I see: >>>>
    FireFox (just 1 tab open) - 96 threads
    ThunderBird - 72 threads
    LibreOffice - 22 threads

    Is it different on Linux?

    What makes you think those extra threads are doing anything directly
    with the GUI ?

    Also, I thought Windows was a single-thread GUI model (at least it was
    back in the traditional Win32 days IIRC). Has that changed recently ?

    Maybe we are not talking about the same.

    Are we talking about how many threads can update the GUI
    widgets/controls or are we talking about how many threads
    in the GUI application?

    How many threads can _directly_ update the GUI widgets/controls.

    I am not aware of any GUI frameworks where it is more than one.

    I showed the code for Java Swing and C# Win Forms for how to
    get the GUI update into the event thread from another thread.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Wed Oct 2 18:15:26 2024
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive
    settings) or does it always create a brand-new connection for the next
    request ?

    New connection.

    It is simulating multiple browser instances.

    Browser #1 open connection to request the page - keep
    the connection alive, because it may want to use it later.

    Browser #2 open connection to request the page - keep
    the connection alive, because it may want to use it later.


    Are you closing down the current instance of the client and then
    starting up a new instance of the client ?

    or

    Are you keeping the existing process running and creating a new
    instance from it ?

    In either case, are you _cleanly_ and _fully_ closing the existing
    connection _before_ you exit or create a new connection in the existing
    process ?

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Wed Oct 2 14:30:16 2024
    On 10/2/2024 2:15 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive >>> settings) or does it always create a brand-new connection for the next
    request ?

    New connection.

    It is simulating multiple browser instances.

    Browser #1 open connection to request the page - keep
    the connection alive, because it may want to use it later.

    Browser #2 open connection to request the page - keep
    the connection alive, because it may want to use it later.


    Are you closing down the current instance of the client and then
    starting up a new instance of the client ?

    or

    Are you keeping the existing process running and creating a new
    instance from it ?

    Existing process.

    In either case, are you _cleanly_ and _fully_ closing the existing
    connection _before_ you exit or create a new connection in the existing process ?

    No.

    Because browser instances do not do that. Browsers keeps
    connections open for a long time. I believe 300 seconds is common.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Oct 2 14:53:59 2024
    On 10/2/2024 2:30 PM, Arne Vajhøj wrote:
    On 10/2/2024 2:15 PM, Simon Clubley wrote:
    In either case, are you _cleanly_ and _fully_ closing the existing
    connection _before_ you exit or create a new connection in the existing
    process ?

    No.

    Because browser instances do not do that. Browsers keeps
    connections open for a long time. I believe 300 seconds is common.

    The client side is rather uninteresting.

    Chrome, Safari, Firefox etc. behave like they do - nothing
    to do about it.

    It is definitely possible to change config values in httpd.conf
    (which on VMS is in APACHE$ROOT:[CONF]).

    VSI could change the source code of VMS Apache and provide
    a new version.

    If they uploaded the source to their public Github repo, then
    in theory anyone could update the source code.

    That is the constraints.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to clubley@remove_me.eisner.decus.org- on Wed Oct 2 19:13:21 2024
    In article <vdk2ju$3bapl$1@dont-email.me>,
    Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close` >>>>>>> with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive >>> settings) or does it always create a brand-new connection for the next
    request ?

    New connection.

    It is simulating multiple browser instances.

    Browser #1 open connection to request the page - keep
    the connection alive, because it may want to use it later.

    Browser #2 open connection to request the page - keep
    the connection alive, because it may want to use it later.


    Are you closing down the current instance of the client and then
    starting up a new instance of the client ?

    or

    Are you keeping the existing process running and creating a new
    instance from it ?

    In either case, are you _cleanly_ and _fully_ closing the existing
    connection _before_ you exit or create a new connection in the existing >process ?

    It seems clear that it does not.

    When asked about keep-alives initially, Arne said that the
    client does not make use of persistent connections. Subsequent
    posts revelated that it actually does; he seemed to be confused
    about how the protocol actually works there.

    He also posted this was a bug in the VMS implementation of
    Apache, going as far as to suggest something about expectations
    due to careless porting. But the same behavior manifests itself
    on other systems.

    Arne keeps moving the goal posts of what, exactly, he claims is
    wrong and why, while being cagey about how exactly he's testing
    and what the experimental setup looks like. It's intern-level
    investigation, at best.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 19:38:26 2024
    In article <vdd2mr$1tq3s$4@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/29/2024 10:03 PM, Lawrence D'Oliveiro wrote:
    On Sun, 29 Sep 2024 21:58:45 -0400, Arne Vajhøj wrote:

    On 9/29/2024 9:46 PM, Lawrence D'Oliveiro wrote:

    On Sun, 29 Sep 2024 21:42:48 -0400, Arne Vajhøj wrote:

    On 9/29/2024 9:21 PM, Lawrence D'Oliveiro wrote:

    Then it asks another process for a copy of that socket descriptor. >>>>>> Perhaps there is one overall connection-management process that
    accepts all new connections; if not, another worker that has that
    socket can pass it along.

    It should not be a problem of copying a socket descriptor from one
    process to another process - I believe it is just an int.

    But will it work in the other process????

    That’s not how you do it. You pass it with the SCM_RIGHTS
    ancillary-data option in Unix-family sockets
    <https://manpages.debian.org/7/unix.7.en.html>.

    Worker A has a AF_INET socket to client so what AF_UNIX socket does it
    pass to worker B?

    You can pass any FD (AF_INET socket, file, pipe, even another AF_UNIX
    socket) over an AF_UNIX socket.

    Ah. Interesting. Very interesting.

    Access rights passing over Unix domain sockets was introduced in
    4.2BSD, in 1983: more than 40 years ago. The basic mechanism
    was updated in 4.4BSD, in 1994: 30 years ago. Here's a working
    example:

    // Passing access rights between processes over Unix domain
    // sockets.
    //
    // Dan Cross <cross@gajendra.net>

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/uio.h>

    #include <stddef.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>

    // Sends a file descripter, `fd`, over a Unix domain socket `sd`
    // via the 4.4BSD access rights passing mechanism.
    //
    // Returns 1 on success, -1 on failure.
    int
    sendfd(int sd, int fd)
    {
    struct msghdr mh;
    struct iovec iv;
    struct cmsghdr *ptr;
    size_t len;
    int ret;
    char dummy;

    // Construct the control message header. Note this is
    // malloc'ed to ensure proper alignment.
    len = CMSG_SPACE(sizeof(int));
    ptr = malloc(len);
    if (ptr == NULL)
    return -1;
    memset(ptr, 0, len);
    ptr->cmsg_len = len;
    ptr->cmsg_level = SOL_SOCKET;
    ptr->cmsg_type = SCM_RIGHTS;
    memcpy(CMSG_DATA(ptr), &fd, sizeof(int));

    // We send a single byte of dummy data in case the
    // implementation does not pass control data with an
    // otherwise empty data transfer.
    dummy = 0;
    memset(&iv, 0, sizeof(iv));
    iv.iov_base = &dummy;
    iv.iov_len = 1;

    // Construct the message header. Points to the dummy
    // data and the control message header.
    memset(&mh, 0, sizeof(mh));
    mh.msg_name = NULL;
    mh.msg_namelen = 0;
    mh.msg_iov = &iv;
    mh.msg_iovlen = 1;
    mh.msg_control = (caddr_t)ptr;
    mh.msg_controllen = len;
    mh.msg_flags = 0;

    // Loop in case there's no room in the kernel buffer
    // to send. Cf.Stevens et al.
    do {
    ret = sendmsg(sd, &mh, 0);
    } while (ret == 0);
    free(ptr);

    return ret;
    }

    // Receives a file descriptor over the Unix domain socket `sd`
    // and store it into `*fdp` on success.
    //
    // Returns 1 on success, 0 on EOF, -1 on error.
    int
    recv_fd(int sd, int *fdp)
    {
    struct msghdr mh;
    struct iovec iv;
    struct cmsghdr *ptr;
    size_t len;
    int ret;
    char dummy;

    if (fdp == NULL)
    return -1;

    // Allocate space for the control structure.
    len = CMSG_SPACE(sizeof(int));
    ptr = malloc(len);
    if (ptr == NULL)
    return -1;

    // Fill in an iovec to receive one byte of dummy data.
    // Required on some systems that do not pass control
    // messages on empty data transfers.
    memset(&iv, 0, sizeof(iv));
    iv.iov_base = &dummy;
    iv.iov_len = 1;

    // Fill in the msghdr structure. `recvmsg(2)` will
    // update it.
    memset(&mh, 0, sizeof(mh));
    mh.msg_name = NULL;
    mh.msg_namelen = 0;
    mh.msg_iov = &iv;
    mh.msg_iovlen = 1;
    mh.msg_control = ptr;
    mh.msg_controllen = len;
    mh.msg_flags = 0;

    ret = recvmsg(sd, &mh, 0);
    if (ret <= 0) {
    free(ptr);
    return ret;
    }
    if (mh.msg_flags != 0) {
    free(ptr);
    return -1;
    }
    memcpy(fdp, CMSG_DATA(ptr), sizeof(int));
    free(ptr);

    return 1;
    }

    But I am pretty sure that it will not work on VMS.

    There's some chatter that suggests Unix domain sockets were
    added in OpenVMS 8.4, in 2010: 14 years ago: https://de.openvms.org/TUD2011/Unix_Portability_Updates_and_Open_Source.pdf

    I haven't checked myself; even if the basic Unix domain sockets
    mechanism was added for IPC, it's not clear if the access rights
    transfer functionality was also implemented.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Wed Oct 2 20:15:37 2024
    In article <66fd7bc6$0$715$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 12:25 PM, Dan Cross wrote:
    [snip]
    So...Not a VMS problem at all.

    The basic mechanism is not VMS specific at all.

    That's odd, because in <vdjjl2$37f8q$1@dont-email.me> you wrote:
    Or taking code designed for a different OS and expecting
    it to work on another OS.

    But that's clearly not the case here.

    I assume that it is inherent in prefork MPM on all
    platforms and other servers that use a similar
    worker process model.

    As I have noted a couple of times then back when
    prefork MPM was common (20 years ago) then the question
    about whether to have keep alive on or off was
    often discussed.

    I wonder if you forget that you had done that until today?

    The problem does not seem to impact newer designs
    using threads. They obviously still need to keep
    the connection open, but I guess they do some
    select/poll/epoll/whatever to detect when there is a
    new request to keep resource usage minimal.

    But the mechanism hits VMS harder than other platforms.

    Nah. The issue is pretty much the same.

    The *nix fork is way more efficient than SYS$CREPRC for
    creating those hundreds or thousands of worker processes.

    This may be true, and it certainly is the common wisdom, but it
    would be useful to provide an actual profile showing it to be
    the case.

    We can have fewer worker processes on VMS and it creates
    longer delay to start them up.

    As described above.

    The real failure here is in mismatched expectations vis how the
    protocol works and the server configuration. If you wanted to
    do this in a real shop, one would hope you'd have some sort of
    caching load balancer in front of your apache servers. Then
    again, Apache is pretty long in the tooth for this kind of
    thing.


    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 2 21:48:13 2024
    On Wed, 2 Oct 2024 10:00:02 -0400, Arne Vajhøj wrote:

    Or taking code designed for a different OS and expecting it to work on another OS.

    Does VMS need its own natively-developed web server? Who would create it?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 2 21:56:59 2024
    On Wed, 2 Oct 2024 14:08:52 -0400, Arne Vajhøj wrote:

    How many threads can _directly_ update the GUI widgets/controls.

    I am not aware of any GUI frameworks where it is more than one.

    That’s quite usual. There should also be some call so a background thread
    can safely post a callback to be executed on the GUI thread when it gets
    an idle moment.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 2 21:58:35 2024
    On Wed, 2 Oct 2024 10:09:23 -0400, Arne Vajhøj wrote:

    On 10/1/2024 5:34 PM, Lawrence D'Oliveiro wrote:

    On Tue, 1 Oct 2024 16:17:18 -0400, Arne Vajhøj wrote:

    It does not really make any sense for the test client to send
    "Connection: close".

    I think you’re right, but it still should be closing the connection
    cleanly, so the server side can get notification of that.

    Browsers doesn't ...

    I’m sure they do.

    I have a Websocket test somewhere, which I wrote to detect when a browser closes a window/tab, because the Websocket connection gets closed at that point. That does work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Dan Cross on Wed Oct 2 17:14:49 2024
    On 10/2/24 2:38 PM, Dan Cross wrote:

    There's some chatter that suggests Unix domain sockets were
    added in OpenVMS 8.4, in 2010: 14 years ago: https://de.openvms.org/TUD2011/Unix_Portability_Updates_and_Open_Source.pdf

    I haven't checked myself; even if the basic Unix domain sockets
    mechanism was added for IPC, it's not clear if the access rights
    transfer functionality was also implemented.

    Last I heard the domain sockets were just an emulation, implemented in
    terms of loopback AF_INET sockets. The most annoying limitation of the implementation that I remember was that you had to define logical names
    in the system table to tell it what ports to use:

    $ define/system TCPIP$AF_UNIX_MIN_PORT 1000
    $ define/system TCPIP$AF_UNIX_MAX_PORT 5000


    SCM_RIGHTS _is_ defined in socket.h, but that may not mean much.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 18:56:10 2024
    On 10/2/2024 5:48 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 10:00:02 -0400, Arne Vajhøj wrote:
    Or taking code designed for a different OS and expecting it to work on
    another OS.

    Does VMS need its own natively-developed web server? Who would create it?

    2 such exist: OSU and WASD. Thanks to David Jones and Mark Daniels.

    But Apache with a different MPM would do fine as well. The winnt MPM
    would be best fit. But the hybrid process and thread MPM's that
    Linux has used for the last 15-20 years would also fit fine.
    Practically anything but Apache prefork MPM. Porting another MPM
    could be VSI as Apache is supported by VSI or a volunteer.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 17:35:59 2024
    On 10/2/24 4:48 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 10:00:02 -0400, Arne Vajhøj wrote:

    Or taking code designed for a different OS and expecting it to work on
    another OS.

    Does VMS need its own natively-developed web server? Who would create it?

    There are at least three that have already been created and have been
    available for a very long time (though I think Purveyor may no longer be available?).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Wed Oct 2 19:05:31 2024
    On 10/2/2024 6:14 PM, Craig A. Berry wrote:
    On 10/2/24 2:38 PM, Dan Cross wrote:
    There's some chatter that suggests Unix domain sockets were
    added in OpenVMS 8.4, in 2010: 14 years ago:
    https://de.openvms.org/TUD2011/
    Unix_Portability_Updates_and_Open_Source.pdf

    I haven't checked myself; even if the basic Unix domain sockets
    mechanism was added for IPC, it's not clear if the access rights
    transfer functionality was also implemented.

    Last I heard the domain sockets were just an emulation, implemented in
    terms of loopback AF_INET sockets.  The most annoying limitation of the implementation that I remember was that you had to define logical names
    in the system table to tell it what ports to use:

    $ define/system TCPIP$AF_UNIX_MIN_PORT 1000
    $ define/system TCPIP$AF_UNIX_MAX_PORT 5000

    SCM_RIGHTS _is_ defined in socket.h, but that may not mean much.

    It would be pretty hard to make it work as on *nix.

    The descriptor being moved is a kernel close thing
    on *nix, so for a kernel reassigning is work but not
    crazy much work.

    VMS is totally different. Especially for a file.
    A file descriptor is pointing to some user mode
    C RTL data structures that reference some RMS
    user mode data structures that reference some
    RMS executive mode data structures that reference
    some VMS kernel mode data structures. Lots of stuff
    to get copied over. Sockets would probably be a lot easier.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 19:07:19 2024
    On 10/2/2024 5:58 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 10:09:23 -0400, Arne Vajhøj wrote:
    On 10/1/2024 5:34 PM, Lawrence D'Oliveiro wrote:
    On Tue, 1 Oct 2024 16:17:18 -0400, Arne Vajhøj wrote:
    It does not really make any sense for the test client to send
    "Connection: close".

    I think you’re right, but it still should be closing the connection
    cleanly, so the server side can get notification of that.

    Browsers doesn't ...

    I’m sure they do.

    I have a Websocket test somewhere, which I wrote to detect when a browser closes a window/tab, because the Websocket connection gets closed at that point. That does work.

    Eventually they do.

    But it takes a long time. Way longer than the server side keep
    alive timeout.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 2 23:52:07 2024
    On Wed, 2 Oct 2024 19:07:19 -0400, Arne Vajhøj wrote:

    On 10/2/2024 5:58 PM, Lawrence D'Oliveiro wrote:

    I have a Websocket test somewhere, which I wrote to detect when a
    browser closes a window/tab, because the Websocket connection gets
    closed at that point. That does work.

    Eventually they do.

    For WebSockets, it happens immediately.

    But it takes a long time. Way longer than the server side keep alive
    timeout.

    OK, this I think I understand: not that the browser never (cleanly) closes
    the HTTP/HTTPS connection, but that it takes its time doing so, in the
    hope it can use it again.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Wed Oct 2 23:50:54 2024
    On Wed, 2 Oct 2024 19:05:31 -0400, Arne Vajhøj wrote:

    The descriptor being moved is a kernel close thing on *nix, so for a
    kernel reassigning is work but not crazy much work.

    VMS is totally different. Especially for a file.
    A file descriptor is pointing to some user mode C RTL data structures
    that reference some RMS user mode data structures that reference some
    RMS executive mode data structures that reference some VMS kernel mode
    data structures.

    If you leave RMS out of it, at the basic QIO level you have a channel,
    which is an index into the CCB array, which is in per-process P1 space (or whatever the 64-bit equivalent is). That in turn contains a reference to a
    WCB in system space, which is how VMS kept track of an open file --
    presumably there is some analogous structure for a comms socket etc.

    So sharing those in-kernel structures is not the hard part -- it would be
    easy enough to allocate a channel in the CCB array in another process and
    have it point back to the same in-kernel structures.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 19:56:20 2024
    On 10/2/2024 7:52 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:07:19 -0400, Arne Vajhøj wrote:
    On 10/2/2024 5:58 PM, Lawrence D'Oliveiro wrote:
    I have a Websocket test somewhere, which I wrote to detect when a
    browser closes a window/tab, because the Websocket connection gets
    closed at that point. That does work.

    Eventually they do.

    For WebSockets, it happens immediately.

    But it takes a long time. Way longer than the server side keep alive
    timeout.

    OK, this I think I understand: not that the browser never (cleanly) closes the HTTP/HTTPS connection, but that it takes its time doing so, in the
    hope it can use it again.

    They typical don't close the windows immediately.

    Server side keep alive timeout in Apache is 15 seconds.

    If the reader are done reading the page in less than 15 seconds
    then there is a problem with the content.

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 19:57:50 2024
    On 10/2/2024 7:50 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:05:31 -0400, Arne Vajhøj wrote:
    The descriptor being moved is a kernel close thing on *nix, so for a
    kernel reassigning is work but not crazy much work.

    VMS is totally different. Especially for a file.
    A file descriptor is pointing to some user mode C RTL data structures
    that reference some RMS user mode data structures that reference some
    RMS executive mode data structures that reference some VMS kernel mode
    data structures.

    If you leave RMS out of it, at the basic QIO level you have a channel,
    which is an index into the CCB array, which is in per-process P1 space (or whatever the 64-bit equivalent is). That in turn contains a reference to a WCB in system space, which is how VMS kept track of an open file -- presumably there is some analogous structure for a comms socket etc.

    So sharing those in-kernel structures is not the hard part -- it would be easy enough to allocate a channel in the CCB array in another process and have it point back to the same in-kernel structures.

    It would be a lot easier without the C RTL data structures and the
    RMS data structures.

    But they exist.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 00:04:09 2024
    On Wed, 2 Oct 2024 19:56:20 -0400, Arne Vajhøj wrote:

    They typical don't close the windows immediately.

    This was for a more interactive app-type thing, not consuming static
    content. Like a chat session or audio/video phone call.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 00:02:49 2024
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:

    On 10/2/2024 7:50 PM, Lawrence D'Oliveiro wrote:

    It would be a lot easier without the C RTL data structures and the RMS
    data structures.

    But they exist.

    VMS doesn’t force you to use them. And I’m not clear what the point of
    them is, for network I/O.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 20:14:20 2024
    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:
    It would be a lot easier without the C RTL data structures and the RMS
    data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally
    rare.

    And I’m not clear what the point of them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor
    over Unix socket as well.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Wed Oct 2 20:18:37 2024
    On 10/2/2024 4:15 PM, Dan Cross wrote:
    If you wanted to
    do this in a real shop, one would hope you'd have some sort of
    caching load balancer in front of your apache servers. Then
    again, Apache is pretty long in the tooth for this kind of
    thing.

    Apache got mod_cache. And there are a few caching reverse proxies
    available - including Varnish.

    But not so interesting for this. This was for dynamic
    content and that would typical not be cached.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 00:44:54 2024
    On Wed, 2 Oct 2024 20:36:48 -0400, Arne Vajhøj wrote:

    Terminal: yes.

    Mailboxes: yes.

    Tapes: yes.

    Disk file: not so much.

    I dabbled with that, too. How do you think RMS was implemented?

    But the C code cannot use it as a file descriptor.

    The C runtime can wrap it in the same sort of thing it does for any other channel.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 00:28:38 2024
    On Wed, 2 Oct 2024 20:14:20 -0400, Arne Vajhøj wrote:

    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:

    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:

    It would be a lot easier without the C RTL data structures and the RMS
    data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally rare.

    I did it all the time. For terminal stuff, it was much easier than trying
    to work through the cumbersome indirection layer imposed by RMS.

    And I’m not clear what the point of them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor
    over Unix socket as well.

    Remember that POSIX has no “RMS” layer. A VMS “channel” might be considered equivalent to a POSIX “file descriptor”, except that “files” are just streams of bytes, and “file descriptor” refers equally well to data on persistent storage, or pipes or sockets. On Linux, it even has
    other uses to do with certain kernel control/notification APIs, not for
    regular data transfer at all.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 20:36:48 2024
    On 10/2/2024 8:28 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:14:20 -0400, Arne Vajhøj wrote:

    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:

    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:

    It would be a lot easier without the C RTL data structures and the RMS >>>> data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally rare.

    I did it all the time. For terminal stuff, it was much easier than trying
    to work through the cumbersome indirection layer imposed by RMS.

    Terminal: yes.

    Mailboxes: yes.

    Tapes: yes.

    Disk file: not so much.

    And I’m not clear what the point of them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor
    over Unix socket as well.

    Remember that POSIX has no “RMS” layer. A VMS “channel” might be considered equivalent to a POSIX “file descriptor”,

    Yes.

    But the C code cannot use it as a file descriptor.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 20:51:54 2024
    On 10/2/2024 8:44 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:36:48 -0400, Arne Vajhøj wrote:
    Terminal: yes.

    Mailboxes: yes.

    Tapes: yes.

    Disk file: not so much.

    I dabbled with that, too.

    It is obviously doable, but it is cumbersome.

    But the C code cannot use it as a file descriptor.

    The C runtime can wrap it in the same sort of thing it does for any other channel.

    It would have to reimplement a lot of RMS functionality to be
    able to properly work with VMS files in an efficient manner.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 01:18:31 2024
    On Wed, 2 Oct 2024 20:51:54 -0400, Arne Vajhøj wrote:

    On 10/2/2024 8:44 PM, Lawrence D'Oliveiro wrote:

    The C runtime can wrap it in the same sort of thing it does for any
    other channel.

    It would have to reimplement a lot of RMS functionality to be able to properly work with VMS files in an efficient manner.

    I don’t see why RMS needs to come into it at all. RMS seems like a poor
    fit for the whole stdio/POSIX I/O model.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Wed Oct 2 21:57:06 2024
    On 10/2/2024 9:18 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:51:54 -0400, Arne Vajhøj wrote:
    On 10/2/2024 8:44 PM, Lawrence D'Oliveiro wrote:
    The C runtime can wrap it in the same sort of thing it does for any
    other channel.

    It would have to reimplement a lot of RMS functionality to be able to
    properly work with VMS files in an efficient manner.

    I don’t see why RMS needs to come into it at all. RMS seems like a poor
    fit for the whole stdio/POSIX I/O model.

    Process A creates a text file and start writing to it, process A send
    the channel to process B, process B want to write more data to it.

    B send "ABC\n" to wrapper.

    What does the wrapper write to disk?

    RFM=STMLF : 0x41 0x42 0x43 0x0A
    RFM=VAR : 0x03 0x00 0x41 0x42 0x43 0x00
    RFM=VFC : ...
    RFM=FIX MRS=512 : ...

    And that is just for sequential files. We also got index-sequential
    and relative files.

    Yes - C IO and RMS IO are not easy to align, but we have RMS whether we
    like it or no.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Hunter Goatley@21:1/5 to Craig A. Berry on Wed Oct 2 22:43:42 2024
    On 10/2/2024 6:35 PM, Craig A. Berry wrote:

    Does VMS need its own natively-developed web server? Who would create it?

    There are at least three that have already been created and have been available for a very long time (though I think Purveyor may no longer be available?).

    Purveyor was great in its day, but its day ended approximately 22 years
    ago. ;-)

    Hunter
    ------
    Hunter Goatley, Process Software, https://www.process.com/ goathunter@goatley.com https://hunter.goatley.com/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Oct 3 03:45:33 2024
    On Wed, 2 Oct 2024 21:57:06 -0400, Arne Vajhøj wrote:

    Yes - C IO and RMS IO are not easy to align, but we have RMS whether we
    like it or no.

    I’m not sure that RMS does enough (or any) in-system-space coordination
    among different processes to be able to solve the problem you think it is solving in this case.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to All on Thu Sep 26 07:38:35 2024
    On 9/25/24 6:14 PM, Arne Vajhøj wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    Does anyone know internals of Apache on VMS?

    Based on some messages in error_log it looks like
    it uses mailboxes APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between
    master process and a child process, then that could
    slow down things.

    I vaguely remember that there was a separate image installed with
    privileges that increased socket buffer size from 255 bytes to something reasonable and these sockets were used as pipes for IPC.

    The following links still seem to work if you want (old) sources:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-ALPHA-SRC-KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-I64-SRC-KIT.BCK_SFX_I64EXE

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Craig A. Berry on Thu Sep 26 09:30:04 2024
    On 9/26/24 7:38 AM, Craig A. Berry wrote:

    On 9/25/24 6:14 PM, Arne Vajhøj wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    Does anyone know internals of Apache on VMS?

    Based on some messages in error_log it looks like
    it uses mailboxes APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between
    master process and a child process, then that could
    slow down things.

    I vaguely remember that there was a separate image installed with
    privileges that increased socket buffer size from 255 bytes to something reasonable and these sockets were used as pipes for IPC.

    The following links still seem to work if you want (old) sources:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-ALPHA-SRC-KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-I64-SRC-KIT.BCK_SFX_I64EXE


    Trial and error shows that *slightly* later versions are available at
    the same place:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-ALPHA-SRC-KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-I64-SRC-KIT.BCK_SFX_I64EXE

    Dunno why VSI doesn't release source code for their v2.4 port.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to All on Thu Sep 26 09:44:14 2024
    On 9/25/24 4:17 PM, Arne Vajhøj wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    Apache on VMS is prefork MPM. Yuck.

    Which puzzles me.

    VMS is a threading OS not a forking OS.

    Preforking in Apache just means it creates subprocesses at start-up
    time. Whoever invented the term apparently thought fork() was the only
    way to create a subprocess. On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    And prefork MPM is really an early 90's traditional Unix design.

    Using worker MPM on VMS would make more sense IMHO.

    That requires everything running in each MPM process to be thread-safe.
    It also probably doesn't provide the scaling advantages on VMS that it
    would on unixen because there is no pthread_sigsetmask: all signals are delivered in the main thread. Which means that somewhere around where
    threads could provide a scaling advantage, the main thread will get
    saturated and the advantage disappears. This based on the assumption
    that signals would be used for things like asynchronous I/O completion;
    I don't really know that for sure, but it seems like a pretty safe
    assumption.

    The best would probably have been to create a VMS MPM
    based on the WinNT MPM.

    And all of the Apache extensions would have to be rewritten to use QIOs
    and ASTs? That's a pretty big ask.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Thu Sep 26 10:55:00 2024
    On 9/26/2024 10:44 AM, Craig A. Berry wrote:
    On 9/25/24 4:17 PM, Arne Vajhøj wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    Apache on VMS is prefork MPM. Yuck.

    Which puzzles me.

    VMS is a threading OS not a forking OS.

    Preforking in Apache just means it creates subprocesses at start-up
    time.  Whoever invented the term apparently thought fork() was the only
    way to create a subprocess.  On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    Yes. But they behave different from fork.

    And prefork MPM is really an early 90's traditional Unix design.

    Using worker MPM on VMS would make more sense IMHO.

    That requires everything running in each MPM process to be thread-safe.
    It also probably doesn't provide the scaling advantages on VMS that it
    would on unixen because there is no pthread_sigsetmask: all signals are delivered in the main thread. Which means that somewhere around where
    threads could provide a scaling advantage, the main thread will get
    saturated and the advantage disappears. This based on the assumption
    that signals would be used for things like asynchronous I/O completion;
    I don't really know that for sure, but it seems like a pretty safe assumption.

    Well - the threaded PHP engine that does run on VMS (Tomcat + Quercus)
    performs much better, so I am optimistic. I am pretty sure that the
    Java RT use standard socket IO and pthreads, so it must be possible
    to achieve the same numbers in C.

    The best would probably have been to create a VMS MPM
    based on the WinNT MPM.

    And all of the Apache extensions would have to be rewritten to use QIOs
    and ASTs?  That's a pretty big ask.

    Why would extensions require being rewritten to use QIO's and
    AST's?

    Thread safe IO does not require those.

    And most extensions are already available in a thread safe
    version. Obviously no guarantee that it will build unchanged
    on VMS, but ...

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to Craig A. Berry on Thu Sep 26 16:59:57 2024
    On 26/09/2024 15:30, Craig A. Berry wrote:
    On 9/26/24 7:38 AM, Craig A. Berry wrote:

    The following links still seem to work if you want (old) sources:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-ALPHA-SRC-KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-I64-SRC-KIT.BCK_SFX_I64EXE >>

    Trial and error shows that *slightly* later versions are available at
    the same place:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-ALPHA-SRC-KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-I64-SRC-KIT.BCK_SFX_I64EXE

    Dunno why VSI doesn't release source code for their v2.4 port.


    ISTR that for all the VSI versions of opensource that requires source to
    be available, they say they do not publish, will release source on
    request. Not sure how we request, or if there will be any caveats...

    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Thu Sep 26 15:44:51 2024
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 2:41 PM, Dan Cross wrote:
    In article <vd1bdp$3npm3$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 8:48 AM, Dan Cross wrote:
    Perhaps a simpler question: what sort of throughput does Apache
    on VMS give you if you just hit a simple static resource
    repeatedly?

    Now it becomes interesting.

    nop.php also gives 11 req/sec.

    And nop.txt also gives 11 req/sec.

    So the arrow is definitely pointing towards Apache.

    I should think so. Lesson #1: always verify your base
    assumptions when investigating something like this.

    So either something to speed up Apache or switching to WASD or OSU.

    Well, the question now becomes, "what makes Apache so slow?"

    I would concentrate on your nop.txt test; I assume that's a
    small (possibly empty) text file and as an example has the
    fewest number of variables.

    Do your logs give any indications of what might be going on?
    For example, do the logs have host names in them, possibly
    implying your stalling on reverse DNS lookups or something
    similar?

    Just logging IP address.

    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Chris Townley on Thu Sep 26 12:35:35 2024
    On 9/26/2024 11:59 AM, Chris Townley wrote:
    On 26/09/2024 15:30, Craig A. Berry wrote:
    On 9/26/24 7:38 AM, Craig A. Berry wrote:
    The following links still seem to work if you want (old) sources:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-ALPHA-SRC-
    KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-I64-SRC-
    KIT.BCK_SFX_I64EXE


    Trial and error shows that *slightly* later versions are available at
    the same place:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-ALPHA-SRC-
    KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-I64-SRC-
    KIT.BCK_SFX_I64EXE

    Dunno why VSI doesn't release source code for their v2.4 port.

    ISTR that for all the VSI versions of opensource that requires source to
    be available, they say they do not publish, will release source on
    request. Not sure how we request, or if there will be any caveats...

    (they have published some: https://github.com/vmssoftware)

    Apache httpd is under Apache license, which does not make such
    requirement.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Craig A. Berry on Thu Sep 26 20:40:03 2024
    On Thu, 26 Sep 2024 09:44:14 -0500, Craig A. Berry wrote:

    Whoever invented the term apparently thought fork() was the only
    way to create a subprocess.

    It is the most natural way in this case, because it creates a complete
    copy of the parent process, which is what you want.

    On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    Not only is that more expensive, it also requires additional setup to
    recreate the effect of fork(2).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Thu Sep 26 23:22:00 2024
    On Thu, 26 Sep 2024 19:15:40 -0400, Arne Vajhøj wrote:

    On 9/26/2024 4:40 PM, Lawrence D'Oliveiro wrote:

    On Thu, 26 Sep 2024 09:44:14 -0500, Craig A. Berry wrote:

    Whoever invented the term apparently thought fork() was the only
    way to create a subprocess.

    It is the most natural way in this case, because it creates a complete
    copy of the parent process, which is what you want.

    On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    Not only is that more expensive, it also requires additional setup to
    recreate the effect of fork(2).

    They have one big advantage over fork on VMS.

    They exist!

    Not enough to make up for the performance disadvantage, though ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Thu Sep 26 19:15:40 2024
    On 9/26/2024 4:40 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 09:44:14 -0500, Craig A. Berry wrote:
    Whoever invented the term apparently thought fork() was the only
    way to create a subprocess.

    It is the most natural way in this case, because it creates a complete
    copy of the parent process, which is what you want.

    On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    Not only is that more expensive, it also requires additional setup to recreate the effect of fork(2).

    They have one big advantage over fork on VMS.

    They exist!

    :-)

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Lawrence D'Oliveiro on Thu Sep 26 19:52:30 2024
    On 9/26/24 6:22 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 19:15:40 -0400, Arne Vajhøj wrote:

    On 9/26/2024 4:40 PM, Lawrence D'Oliveiro wrote:

    On Thu, 26 Sep 2024 09:44:14 -0500, Craig A. Berry wrote:

    Whoever invented the term apparently thought fork() was the only
    way to create a subprocess.

    It is the most natural way in this case, because it creates a complete
    copy of the parent process, which is what you want.

    On VMS it will obviously use LIB$SPAWN or SYS$CREPRC.

    Not only is that more expensive, it also requires additional setup to
    recreate the effect of fork(2).

    They have one big advantage over fork on VMS.

    They exist!

    Not enough to make up for the performance disadvantage, though ...

    The ability to restart Apache in a second or so on Linux rather than a
    couple seconds on VMS is nice but has nothing to do with the problem
    Arne reported, which is about performance after the worker processes are started.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Thu Sep 26 21:20:38 2024
    On 9/26/2024 10:30 AM, Craig A. Berry wrote:
    On 9/26/24 7:38 AM, Craig A. Berry wrote:
    On 9/25/24 6:14 PM, Arne Vajhøj wrote:
    Does anyone know internals of Apache on VMS?

    Based on some messages in error_log it looks like
    it uses mailboxes APACHE$AWS_CONTROL_MBX_nn.

    If every request result in mailbox comm between
    master process and a child process, then that could
    slow down things.

    I vaguely remember that there was a separate image installed with
    privileges that increased socket buffer size from 255 bytes to something
    reasonable and these sockets were used as pipes for IPC.

    The following links still seem to work if you want (old) sources:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-ALPHA-SRC-
    KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V20-2-I64-SRC-
    KIT.BCK_SFX_I64EXE

    Trial and error shows that *slightly* later versions are available at
    the same place:

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-ALPHA-SRC- KIT.BCK_SFX_AXPEXE

    https://ftp.hp.com/pub/openvms/apache/CSWS-V21-1-I64-SRC-KIT.BCK_SFX_I64EXE

    I took a look.

    It has:

    [.httpd.server.mpm.prefork]prefork.c with 1350 lines calling fork [.httpd.server.mpm.vms]prefork.c with 3900 lines calling sys$creprc

    So it looks like the porting approach was to reimplement prefork
    more or less from scratch for VMS.

    A very quick search make me think that the mailbox is only used
    for control not for data.

    So I am still stuck.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Craig A. Berry on Fri Sep 27 01:26:13 2024
    On Thu, 26 Sep 2024 19:52:30 -0500, Craig A. Berry wrote:

    The ability to restart Apache in a second or so on Linux rather than a
    couple seconds on VMS is nice but has nothing to do with the problem
    Arne reported, which is about performance after the worker processes are started.

    That could be to do with the more convoluted way to do nondeterministic
    I/O under VMS.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Fri Sep 27 01:26:51 2024
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajhøj wrote:

    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though. That and the need for all the ASTs.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Fri Sep 27 02:36:18 2024
    On Thu, 26 Sep 2024 22:17:29 -0400, Arne Vajhøj wrote:

    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:

    That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is a very common
    design today. DEC was ahead of time with that.

    Set attention AST → wait for AST to trigger → queue actual I/O → wait for AST to signal completion. Too many system calls and transitions back and
    forth between user and kernel modes.

    Note that Linux servers can efficiently handle thousands of concurrent
    client connections without this.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Thu Sep 26 22:17:29 2024
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajhøj wrote:
    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though.

    If it is only used for the parent to signal the child to terminate?

    That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is
    a very common design today. DEC was ahead of time with
    that.

    And implementation wise then the AST's worked on VAX 700
    series 45 years ago. Todays systems are extremely much
    faster - maybe a factor 10000 faster.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Thu Oct 3 12:06:42 2024
    On 2024-10-02, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 10/2/2024 2:15 PM, Simon Clubley wrote:

    Are you closing down the current instance of the client and then
    starting up a new instance of the client ?

    or

    Are you keeping the existing process running and creating a new
    instance from it ?

    Existing process.

    In either case, are you _cleanly_ and _fully_ closing the existing
    connection _before_ you exit or create a new connection in the existing
    process ?

    No.

    Because browser instances do not do that. Browsers keeps
    connections open for a long time. I believe 300 seconds is common.


    In that case, in order to accurately duplicate this behaviour, you need a
    VMS webserver capable of holding open 300 (or whatever the number of test clients is you are using) connections at the same time.

    This is a normal capabilty for a modern Linux Apache server BTW.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Thu Oct 3 12:11:07 2024
    In article <vdknst$3dnpf$6@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 4:15 PM, Dan Cross wrote:
    If you wanted to
    do this in a real shop, one would hope you'd have some sort of
    caching load balancer in front of your apache servers. Then
    again, Apache is pretty long in the tooth for this kind of
    thing.

    Apache got mod_cache. And there are a few caching reverse proxies
    available - including Varnish.

    But not so interesting for this. This was for dynamic
    content and that would typical not be cached.

    Load balancing is the critical part, here.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to Hunter Goatley on Thu Oct 3 12:10:46 2024
    On 2024-10-02, Hunter Goatley <goathunter@goatley.com> wrote:
    On 10/2/2024 6:35 PM, Craig A. Berry wrote:

    Does VMS need its own natively-developed web server? Who would create it? >>
    There are at least three that have already been created and have been
    available for a very long time (though I think Purveyor may no longer be
    available?).

    Purveyor was great in its day, but its day ended approximately 22 years
    ago. ;-)


    Careful Hunter, or you will wake Bob up... :-)

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 14:27:55 2024
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

    And what is the "problem" that
    you are imagining here? Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    Arne



    Are you assuming Apache is a well designed and implemented application?

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 14:29:19 2024
    On 10/2/2024 11:30 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

    And what is the "problem" that
    you are imagining here? Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    And the numbers are low due to keep alive.

    Basically Apache on VMS keep an entire process around for
    a kept alive connection.

    When Apache configuration does not allow more
    processes to start then new requests get queued
    until keep alive starts to timeout and processes
    free up.

    And one can not just increase number of processes
    allowed because they use 25 MB each. The system
    runs out of memory/pagefile fast.

    An it does not help that if Apache kills some
    processes then it is expensive to start a new one again,
    which means that either the large number of memory
    consuming processes are kept around or Apache
    will be slow to adjust to increasing load.

    Arne



    Are you assuming that Apache is a well designed and implemented application?

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Thu Oct 3 18:41:11 2024
    In article <vdmnof$3r08j$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/2/2024 11:20 AM, Arne Vajhøj wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.

    That request will block if the server can't serve it
    because all processes are busy.

    And what is the "problem" that
    you are imagining here? Please be specific.

    Go back to the first post in the thread.

    The numbers for Apache are low. Much lower than
    for other servers.

    Are you assuming Apache is a well designed and implemented application?

    Apache was fine for its era. It's the way that Arne is using it
    that's broken. Anyone wanting to host a high-performance web
    app on it would put a load balancer in front of it; that would,
    in turn, mux requests from actual clients and distribute them
    across a set of backend Apache instances. Caching would help
    somewhat, too, so that static resources (like images) were
    closer to the egress point of one's network (hence why I said,
    "caching load balancer" earlier; why take the latency hit for
    seldom-changing stuff?).

    That sort of architecture is more or less still the way that
    things work, but Apache as the backbone of the whole thing is
    rather long in the tooth. I'm sure it's still used all over, on
    a large number of sites. I'm equally sure if someone serious
    were architecting something today for high volume, low-latency
    web applications, Apache wouldn't be high on the list of servers
    for HTTP. Most would just build a web server directly into
    their application, which is almost trivially easy in a lot of
    modern ecosystems; Go and Rust have very nice libraries that
    make this really easy to do.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Dan Cross on Thu Oct 3 14:51:39 2024
    On 10/2/2024 3:13 PM, Dan Cross wrote:

    Arne keeps moving the goal posts of what, exactly, he claims is
    wrong and why, while being cagey about how exactly he's testing
    and what the experimental setup looks like. It's intern-level
    investigation, at best.

    Perhaps the question should be, "what is Arne's goal"?

    In another post he suggested that VSI release sources for their port. Perhaps he is trying to enhance that wish?

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Simon Clubley on Thu Oct 3 14:42:49 2024
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.


    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive settings) or does it always create a brand-new connection for the next request ?

    Simon.


    I don't work much with this kind of stuff, but I have questions?

    If a connection is persistent, then there is already a connection, no need for a
    "brand-new" connection. However, perhaps you're asking whether the client uses an existing connection, or always issues a new connection request?

    In the web services I've implemented in the past, the protocol was rather simple. Request a connection, perform transaction, close connection.

    It did bite us on the ass one time. The client would be requesting inventory status for individual parts. The programmer on the client side (not us) was issuing requests for one part number for each connection. That wasn't good. Once we pointed out to him/her that the protocol would accept multiple part numbers in a single transaction, could be thousands, the problem disappeared.

    The thing is, either have well defined transactions, or, be a "jack-of-all-trades" and do nothing well.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Lawrence D'Oliveiro on Thu Oct 3 14:56:14 2024
    On 10/2/2024 5:48 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 10:00:02 -0400, Arne Vajhøj wrote:

    Or taking code designed for a different OS and expecting it to work on
    another OS.

    Does VMS need its own natively-developed web server? Who would create it?


    Uh, that would be:

    Mark Daniel and WASD

    or

    David Jones and OSU

    as two examples.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 14:59:03 2024
    On 10/2/2024 6:56 PM, Arne Vajhøj wrote:
    On 10/2/2024 5:48 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 10:00:02 -0400, Arne Vajhøj wrote:
    Or taking code designed for a different OS and expecting it to work on
    another OS.

    Does VMS need its own natively-developed web server? Who would create it?

    2 such exist: OSU and WASD. Thanks to David Jones and Mark Daniels.

    But Apache with a different MPM would do fine as well. The winnt MPM
    would be best fit. But the hybrid process and thread MPM's that
    Linux has used for the last 15-20 years would also fit fine.
    Practically anything but Apache prefork MPM. Porting another MPM
    could be VSI as Apache is supported by VSI or a volunteer.

    Arne



    Ah-ha, my previous supposition gains traction ...

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Simon Clubley on Thu Oct 3 14:57:41 2024
    On 10/3/2024 8:10 AM, Simon Clubley wrote:
    On 2024-10-02, Hunter Goatley <goathunter@goatley.com> wrote:
    On 10/2/2024 6:35 PM, Craig A. Berry wrote:

    Does VMS need its own natively-developed web server? Who would create it? >>>
    There are at least three that have already been created and have been
    available for a very long time (though I think Purveyor may no longer be >>> available?).

    Purveyor was great in its day, but its day ended approximately 22 years
    ago. ;-)


    Careful Hunter, or you will wake Bob up... :-)

    Simon.


    Gasp .. please no ...

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 15:09:59 2024
    On 10/2/2024 8:14 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:
    It would be a lot easier without the C RTL data structures and the RMS
    data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally
    rare.

    Not around here.

    And I’m not clear what the point of
    them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor
    over Unix socket as well.

    I thought sockets was the issue?

    Before we closed down operations, I was looking at passing a socket to another process. Not sure if I could, didn't get that far. From the docs, I should be able to open a socket with the SHARE flag, then have another process open the same socket.


    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 15:11:54 2024
    On 10/2/2024 8:36 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:28 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:14:20 -0400, Arne Vajhøj wrote:

    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:

    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:

    It would be a lot easier without the C RTL data structures and the RMS >>>>> data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally rare.

    I did it all the time. For terminal stuff, it was much easier than trying
    to work through the cumbersome indirection layer imposed by RMS.

    Terminal: yes.

    Mailboxes: yes.

    Tapes: yes.

    Disk file: not so much.

    And I’m not clear what the point of them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor >>> over Unix socket as well.

    Remember that POSIX has no “RMS” layer. A VMS “channel” might be
    considered equivalent to a POSIX “file descriptor”,

    Yes.

    But the C code cannot use it as a file descriptor.

    So, don't use C ...


    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 15:13:41 2024
    On 10/2/2024 8:51 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:44 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:36:48 -0400, Arne Vajhøj wrote:
    Terminal: yes.

    Mailboxes: yes.

    Tapes: yes.

    Disk file: not so much.

    I dabbled with that, too.

    It is obviously doable, but it is cumbersome.

    But the C code cannot use it as a file descriptor.

    The C runtime can wrap it in the same sort of thing it does for any other
    channel.

    It would have to reimplement a lot of RMS functionality to be
    able to properly work with VMS files in an efficient manner.

    VMS files are not all RMS files. QIO works fine on VMS files. Think not? Then
    what do you think RMS uses to access VMS files?


    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Lawrence D'Oliveiro on Thu Oct 3 15:18:24 2024
    On 10/2/2024 11:45 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 21:57:06 -0400, Arne Vajhøj wrote:

    Yes - C IO and RMS IO are not easy to align, but we have RMS whether we
    like it or no.

    I’m not sure that RMS does enough (or any) in-system-space coordination among different processes to be able to solve the problem you think it is solving in this case.


    RMS global buffers might help ...

    Global sections can also be helpful ...

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to All on Thu Oct 3 15:16:29 2024
    On 10/2/2024 9:57 PM, Arne Vajhøj wrote:
    On 10/2/2024 9:18 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 20:51:54 -0400, Arne Vajhøj wrote:
    On 10/2/2024 8:44 PM, Lawrence D'Oliveiro wrote:
    The C runtime can wrap it in the same sort of thing it does for any
    other channel.

    It would have to reimplement a lot of RMS functionality to be able to
    properly work with VMS files in an efficient manner.

    I don’t see why RMS needs to come into it at all. RMS seems like a poor
    fit for the whole stdio/POSIX I/O model.

    Process A creates a text file and start writing to it, process A send
    the channel to process B, process B want to write more data to it.

    B send "ABC\n" to wrapper.

    What does the wrapper write to disk?

    RFM=STMLF : 0x41 0x42 0x43 0x0A
    RFM=VAR : 0x03 0x00 0x41 0x42 0x43 0x00
    RFM=VFC : ...
    RFM=FIX MRS=512 : ...

    And that is just for sequential files. We also got index-sequential
    and relative files.

    Yes - C IO and RMS IO are not easy to align, but we have RMS whether we like it
    or no.

    Arne



    And if you don't like RMS?

    DAS and VIO are two products that I have some passing familiarity with.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Thu Oct 3 20:28:58 2024
    In article <vdmp51$3r91s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/2/2024 3:13 PM, Dan Cross wrote:

    Arne keeps moving the goal posts of what, exactly, he claims is
    wrong and why, while being cagey about how exactly he's testing
    and what the experimental setup looks like. It's intern-level
    investigation, at best.

    Perhaps the question should be, "what is Arne's goal"?

    In another post he suggested that VSI release sources for their port. Perhaps >he is trying to enhance that wish?

    He'd probably have better luck asking VSI to do that, as opposed
    to posting here.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert A. Brooks@21:1/5 to Dan Cross on Thu Oct 3 16:52:47 2024
    On 10/3/2024 4:28 PM, Dan Cross wrote:
    In article <vdmp51$3r91s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/2/2024 3:13 PM, Dan Cross wrote:

    Arne keeps moving the goal posts of what, exactly, he claims is
    wrong and why, while being cagey about how exactly he's testing
    and what the experimental setup looks like. It's intern-level
    investigation, at best.

    Perhaps the question should be, "what is Arne's goal"?

    In another post he suggested that VSI release sources for their port. Perhaps
    he is trying to enhance that wish?

    He'd probably have better luck asking VSI to do that, as opposed
    to posting here.

    I'm trying to sort this out; we appear to have some open source stuff on github, so
    imagine that's how we'd made the Apache sources available.


    --
    -- Rob

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Thu Oct 3 20:40:33 2024
    In article <vdmokf$3r6ke$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/2/2024 1:52 PM, Simon Clubley wrote:
    On 2024-10-02, Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 11:07 AM, Dan Cross wrote:
    In article <vdjmq4$37f8q$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/2/2024 10:47 AM, Dan Cross wrote:
    [snip]
    You do not seem to understand how this is qualitatively
    different from your test program not sending `Connection: close`
    with its single request per connection, and then blocking until
    the server times it out.

    It is qualitative different from what you are imaging.

    The client does not block until the server times out.

    So what, exactly, does it do?

    It moves on to next request.


    Does it reuse an existing connection for the next request (which is
    what you have told the server you are going to do due to your keep-alive
    settings) or does it always create a brand-new connection for the next
    request ?

    I don't work much with this kind of stuff, but I have questions?

    If a connection is persistent, then there is already a connection, no need for a
    "brand-new" connection. However, perhaps you're asking whether the client uses
    an existing connection, or always issues a new connection request?

    I think the last place I saw Arne's goalposts, he was trying to
    match the behavior he expects from a bunch of "browser" users;
    these would presumably connect to his service independently, but
    if they tied up a bunch of resources with idle connections, they
    would starve other users. The issue here is that an Apache
    instance in the configuration he's using is only capable of
    handling a single _connection_ per instance; if that connection
    is idle, then that instance is blocked from performing otherwise
    useful work.

    The issue here is that a browser may open a connection to the
    server and the user may wander away; if that connection is
    persistent, then it's going to tie up an Apache instance, since
    the user has gone to get a cup of coffee or whatever and isn't
    actively using it.

    Of course, this isn't specific to VMS, or a function of how VSI
    ported it or whatever else Arne initially thought. The issue
    was, Arne insisting that his test driver wasn't using persistent
    connections, that it actually was since he didn't know to send a
    `Connection: close` header with HTTP/1.1 to turn off
    keep-alives. It's not a bug in Apache, either, despite his
    protestations that it was because disabling keep-alive on the
    server increased throughput for him; it's curious that he would
    do that for the exact behavior he claimed he was warning people
    about 20 years ago.

    It's odd that he hadn't heard about Unix file descriptor
    passing, which has been around since 1983; particularly since
    when I suggested that a way to build an application like this
    is for a master process to accept a connection and then pass it
    off to a worker process and he said, "that's how it's usually
    done." Given that he was unaware of the mechanism by which one
    might transfer the connection from one process to another, one
    must wonder how he thought it was done?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Dan Cross on Thu Oct 3 16:22:03 2024
    On 10/3/24 3:40 PM, Dan Cross wrote:

    The issue here is that a browser may open a connection to the
    server and the user may wander away; if that connection is
    persistent, then it's going to tie up an Apache instance, since
    the user has gone to get a cup of coffee or whatever and isn't
    actively using it.

    Of course, this isn't specific to VMS, or a function of how VSI
    ported it or whatever else Arne initially thought.

    What's specific to VMS is that pre-fork MPM is the only game in town if
    you want to use Apache. Whether the other mechanisms in use on other
    platforms and designed specifically to address the problem Arne
    encountered could be made to work on VMS is an open question, but not
    something anyone outside VSI could try without the sources. I think
    event is out because there is no kqueue or epoll. The worker model
    might be possible. Or a custom one using ASTs instead of pthreads.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Craig A. Berry on Thu Oct 3 21:41:43 2024
    On Thu, 3 Oct 2024 16:22:03 -0500, Craig A. Berry wrote:

    Or a custom one using ASTs instead of pthreads.

    Trying to work at the AST level would be a lot more complex than doing it
    with threads. That’s why threads were invented.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to Dave Froble on Fri Oct 4 00:00:30 2024
    On 03/10/2024 20:09, Dave Froble wrote:
    On 10/2/2024 8:14 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:
    It would be a lot easier without the C RTL data structures and the RMS >>>> data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally
    rare.

    Not around here.

                                        And I’m not clear what the point of
    them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor
    over Unix socket as well.

    I thought sockets was the issue?

    Before we closed down operations, I was looking at passing a socket to another process.  Not sure if I could, didn't get that far.  From the
    docs, I should be able to open a socket with the SHARE flag, then have another process open the same socket.

    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...


    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to Craig A. Berry on Thu Oct 3 23:30:49 2024
    In article <vdn1tr$3sh36$1@dont-email.me>,
    Craig A. Berry <craigberry@nospam.mac.com> wrote:

    On 10/3/24 3:40 PM, Dan Cross wrote:

    The issue here is that a browser may open a connection to the
    server and the user may wander away; if that connection is
    persistent, then it's going to tie up an Apache instance, since
    the user has gone to get a cup of coffee or whatever and isn't
    actively using it.

    Of course, this isn't specific to VMS, or a function of how VSI
    ported it or whatever else Arne initially thought.

    What's specific to VMS is that pre-fork MPM is the only game in town if
    you want to use Apache. Whether the other mechanisms in use on other >platforms and designed specifically to address the problem Arne
    encountered could be made to work on VMS is an open question, but not >something anyone outside VSI could try without the sources. I think
    event is out because there is no kqueue or epoll. The worker model
    might be possible. Or a custom one using ASTs instead of pthreads.

    Apache is open source, it would be possible for someone outside
    of VSI to mount a porting effort and do a threads backend. But
    I do take your point that that would be a bit of work, versus
    modifying what VSI has already done.

    It strikes me that `select` is surely available; this could be
    used to increase scalability quite a bit. It's not as nice as
    kqueue or epoll or whatnot, but it's better than synchronous
    reads blocking on a single socket. Sadly, any of these would
    be subject to head-of-line blocking, but it would scale _better_
    than the prefork-MPM stuff, provided the time to serve requests
    is relatively small (and it probably is).

    Of course, there's a limit to what one can do with a single HTTP
    server instance using _any_ model, be it threads, pre-created
    processes, or some sort of event-driven async task model. And
    then there's a limit to what one can do on a single machine,
    real or virtual. Once you hit a certain scale, you just have to
    be a bit more circumspect with design, and in particular,
    capacity planning; that's where things like load balancers start
    to come into play.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Michael S on Thu Oct 10 23:01:13 2024
    On 10/7/2024 4:07 AM, Michael S wrote:
    On Mon, 7 Oct 2024 00:35:36 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:

    On 10/6/2024 11:12 AM, Michael S wrote:
    On Fri, 4 Oct 2024 17:43:02 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    - Dan C.


    Troll or not, but the question about ability to pass open TCP
    socket to child process (or, may be, to unrelated process) under
    VMS is a good question.
    As a lurker, I am waiting for the expert answer with interest.


    Well, some of the issue is in the text of the question. What does
    one mean be "pass socket"?

    When creating a socket, one can specify it to be shared. What I was
    doing was passing the information to a worker process, then letting
    the worker process open the existing socket.

    So, would that be considered "passing an open socket"?


    Yes, it would be.

    On Windows one has to go through similar 3-stage procedure:
    - [in parent process] acquire magic record from the open socket by
    means of WSADuplicateSocket()
    - pass the record to child by any of available IPC mechanisms
    - [in child process] use magic record to re-open socket with
    WSASocket()

    I never had a need of for it in practice. Looking at docs it seems
    that the procedure above has at least one inconvenient aspect - the
    target process has to exist at the moment of WSADuplicateSocket() call. Still, I suppose that it's better than nothing.

    I can post some of the development code is anyone is interested. I
    was working on the inter-process communications when I dropped the
    project. I believe I did open the shared socket in the worker
    process.


    May be, others are interested in the code.
    For me, I'd rather read textual description of the procedure and war
    story of making it work.


    Actually, simple.

    1) Create the socket in listener process
    2) Pass device name to worker process
    3) Assign a channel to the device in worker process
    4) deassign the channel in listener process (if desired)

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Dan Cross on Thu Oct 10 23:33:34 2024
    On 10/7/2024 4:17 PM, Dan Cross wrote:
    In article <ve1f1t$1mvdn$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/7/2024 11:52 AM, Dan Cross wrote:
    $ cc zz

    len = CMSG_SPACE(sizeof(int));
    .........^
    %CC-I-IMPLICITFUNC, In this statement, the identifier "CMSG_SPACE" is
    implicitly declared as a function.
    at line number 33 in file DKA0:[arne]zz.c;1
    [snip]

    Why would you try to build that under VMS? It obviously would
    not build or work there.

    Yeah, also wondered ...

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Dan Cross on Thu Oct 10 23:46:54 2024
    On 10/7/2024 2:01 PM, Dan Cross wrote:
    As Dave has mentioned, setting SO_SHARE on a socket would be another way
    to accomplish this.

    Neither of these sounds the same as descriptor passing over Unix
    domain sockets on Unix/Linux; the auxiliary server sounds more
    like `inetd`, in that there's some service that's listening and
    accepting connections on some TCP/IP port, and then creating a
    server to handle each incoming connection.

    I would claim that what I did is NOT passing a descriptor, or whatever, to another process. Not really sure what that means. All I passed was the device name, and let the second process assign a channel to the "existing" device (socket).

    SO_SHARE is different again; it appears that the shared socket
    must be created before the subprocesses that use it are created.

    I don't know why you would say that. A process must exist before it can do anything, but, a socket can exist in a process, and then connected to in another
    process, regardless of when the second process is created. For example, if a bank of worker processes exist, and a task comes in, the connection socket could
    be opened by the existing selected worker process.


    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to Dave Froble on Fri Oct 11 13:11:51 2024
    On Thu, 10 Oct 2024 23:01:13 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:

    On 10/7/2024 4:07 AM, Michael S wrote:
    On Mon, 7 Oct 2024 00:35:36 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:

    On 10/6/2024 11:12 AM, Michael S wrote:
    On Fri, 4 Oct 2024 17:43:02 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave!
    ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    - Dan C.


    Troll or not, but the question about ability to pass open TCP
    socket to child process (or, may be, to unrelated process) under
    VMS is a good question.
    As a lurker, I am waiting for the expert answer with interest.


    Well, some of the issue is in the text of the question. What does
    one mean be "pass socket"?

    When creating a socket, one can specify it to be shared. What I
    was doing was passing the information to a worker process, then
    letting the worker process open the existing socket.

    So, would that be considered "passing an open socket"?


    Yes, it would be.

    On Windows one has to go through similar 3-stage procedure:
    - [in parent process] acquire magic record from the open socket by
    means of WSADuplicateSocket()
    - pass the record to child by any of available IPC mechanisms
    - [in child process] use magic record to re-open socket with
    WSASocket()

    I never had a need of for it in practice. Looking at docs it seems
    that the procedure above has at least one inconvenient aspect - the
    target process has to exist at the moment of WSADuplicateSocket()
    call. Still, I suppose that it's better than nothing.

    I can post some of the development code is anyone is interested. I
    was working on the inter-process communications when I dropped the
    project. I believe I did open the shared socket in the worker
    process.


    May be, others are interested in the code.
    For me, I'd rather read textual description of the procedure and war
    story of making it work.


    Actually, simple.

    1) Create the socket in listener process
    2) Pass device name to worker process
    3) Assign a channel to the device in worker process
    4) deassign the channel in listener process (if desired)


    There are few pieces in your simple explanation that I don't understand:
    - How does listener get a device name?
    - What is "channel"? Is it the same as 'socket'?
    - How one "assigns" channel to device? I would guess that device has to
    be open before that?
    - Is device name of the socket system-global?
    If yes, does it mean that any process in the system that happens to
    know a name can open a device and assign it to channel?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Fri Sep 27 13:00:33 2024
    On 2024-09-26, Arne Vajh°j <arne@vajhoej.dk> wrote:
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajh°j wrote:
    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though.

    If it is only used for the parent to signal the child to terminate?

    That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is
    a very common design today. DEC was ahead of time with
    that.

    And implementation wise then the AST's worked on VAX 700
    series 45 years ago. Todays systems are extremely much
    faster - maybe a factor 10000 faster.


    Can you try this on an Alpha system (emulated or otherwise) and see
    how the figures compare ?

    Just wondering if this performance overhead is something that is x86-64 specific.

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Fri Sep 27 09:55:48 2024
    On 9/27/2024 9:18 AM, Craig A. Berry wrote:
    On 9/26/24 9:17 PM, Arne Vajhøj wrote:
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajhøj wrote:
    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though.

    If it is only used for the parent to signal the child to terminate?

                                         That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is
    a very common design today. DEC was ahead of time with
    that.

    And implementation wise then the AST's worked on VAX 700
    series 45 years ago. Todays systems are extremely much
    faster - maybe a factor 10000 faster.

    There are some limitations around ASTs, especially when mixed with
    threads.  The definitive wizard article is here:

    https://forum.vmssoftware.com/viewtopic.php?t=5198

    Technically interesting.

    But I don't think it is a big problem. To me it is either an event
    driven model with single thread and everything non-blocking where
    AST's make sense or a thread model with multiple threads and everything blocking and no need for AST's.

    But I think your basic question is why Apache is slower than Tomcat,
    right?

    Yes - it can be worded that way.

    The question is why Apache (with PHP but that does not seem to matter)
    is so slow.

    Tomcat (with Quercus to provide PHP support) having much higher
    numbers on the same system proves that it is not HW or VMS.

    Also Apache on Windows on same CPU have much higher numbers
    (number of threads have been bumped).

      The only thing I can think of that hasn't already been mentioned
    is that Tomcat code is JIT-compiled, which is likely to be pretty good, optimized code, whereas Apache is probably either cross-compiled or native-compiled with an early enough field test compiler that there are
    no optimizations.

    That is a possible explanation.

    But the difference in numbers are crazy big.

    Apache getting a static text file with 2 bytes: 22 req/sec

    Tomcat with Quercus and PHP getting data out of a MySQL database on
    Windows and outputting HTML: over 200 req/sec

    Tomcat using JSP (which get triple compiled) getting data out of a MySQL database on Windows (with db connection pool) and outputting HTML: over
    600 req/sec.

    My gut feeling is that cross-compilation may contribute to but not
    fully explain the difference.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 09:59:16 2024
    On 9/26/2024 10:36 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 22:17:29 -0400, Arne Vajhøj wrote:
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is a very common
    design today. DEC was ahead of time with that.

    Set attention AST → wait for AST to trigger → queue actual I/O → wait for
    AST to signal completion. Too many system calls and transitions back and forth between user and kernel modes.

    I don't think anyone would use that flow.

    You setup a read attention AST, it triggers and then you know that
    there are data to be read. There is no reason to make reading async
    then, because you know it will not block.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to All on Fri Sep 27 08:18:07 2024
    On 9/26/24 9:17 PM, Arne Vajhøj wrote:
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajhøj wrote:
    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though.

    If it is only used for the parent to signal the child to terminate?

                                         That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is
    a very common design today. DEC was ahead of time with
    that.

    And implementation wise then the AST's worked on VAX 700
    series 45 years ago. Todays systems are extremely much
    faster - maybe a factor 10000 faster.

    There are some limitations around ASTs, especially when mixed with
    threads. The definitive wizard article is here:

    https://forum.vmssoftware.com/viewtopic.php?t=5198

    But I think your basic question is why Apache is slower than Tomcat,
    right? The only thing I can think of that hasn't already been mentioned
    is that Tomcat code is JIT-compiled, which is likely to be pretty good, optimized code, whereas Apache is probably either cross-compiled or native-compiled with an early enough field test compiler that there are
    no optimizations.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Fri Sep 27 10:26:02 2024
    On 9/27/2024 9:00 AM, Simon Clubley wrote:
    Can you try this on an Alpha system (emulated or otherwise) and see
    how the figures compare ?

    Just wondering if this performance overhead is something that is x86-64 specific.

    Getting a tiny text file on a slow Alpha emulator gives 5 req/sec.
    Which is damn good compared to the 22 req/sec on 4 VCPU x86-64.
    But then it is probably not a CPU issue.

    I suspect that performance on that slow Alpha emulator would be
    bad doing something more CPU intensive (like actually running PHP).

    The interesting number comparison is:

    Apache: 5 req/sec
    OSU: 100 req/sec

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Sep 27 11:02:26 2024
    On 9/25/2024 11:49 AM, Arne Vajhøj wrote:
    nop.php also gives 11 req/sec.

    And nop.txt also gives 11 req/sec.

    So the arrow is definitely pointing towards Apache.

    So either something to speed up Apache or switching to WASD or OSU.

    Increasing spare servers made it possible to increase performance for
    nop.txt from 11 to 22 req/sec.

    But OSU (with no tuning at all) nop.txt gives 373 req/sec. Which may
    not be great, but is good enough for me.

    Maybe I should try get PHP working with OSU or WASD.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 14:16:31 2024
    In article <vd6dh4$nrif$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 9:18 AM, Craig A. Berry wrote:
    On 9/26/24 9:17 PM, Arne Vajhøj wrote:
    On 9/26/2024 9:26 PM, Lawrence D'Oliveiro wrote:
    On Thu, 26 Sep 2024 21:20:38 -0400, Arne Vajhøj wrote:
    A very quick search make me think that the mailbox is only used for
    control not for data.

    Could still be a bottleneck, though.

    If it is only used for the parent to signal the child to terminate?

                                         That and the need for all the ASTs.

    Why should AST's be a problem?

    The "call this function when task is done" approach is
    a very common design today. DEC was ahead of time with
    that.

    And implementation wise then the AST's worked on VAX 700
    series 45 years ago. Todays systems are extremely much
    faster - maybe a factor 10000 faster.

    There are some limitations around ASTs, especially when mixed with
    threads.  The definitive wizard article is here:

    https://forum.vmssoftware.com/viewtopic.php?t=5198

    Technically interesting.

    But I don't think it is a big problem. To me it is either an event
    driven model with single thread and everything non-blocking where
    AST's make sense or a thread model with multiple threads and everything >blocking and no need for AST's.

    But I think your basic question is why Apache is slower than Tomcat,
    right?

    Yes - it can be worded that way.

    The question is why Apache (with PHP but that does not seem to matter)
    is so slow.

    Tomcat (with Quercus to provide PHP support) having much higher
    numbers on the same system proves that it is not HW or VMS.

    Also Apache on Windows on same CPU have much higher numbers
    (number of threads have been bumped).

      The only thing I can think of that hasn't already been mentioned
    is that Tomcat code is JIT-compiled, which is likely to be pretty good,
    optimized code, whereas Apache is probably either cross-compiled or
    native-compiled with an early enough field test compiler that there are
    no optimizations.

    That is a possible explanation.

    But the difference in numbers are crazy big.

    Apache getting a static text file with 2 bytes: 22 req/sec

    Tomcat with Quercus and PHP getting data out of a MySQL database on
    Windows and outputting HTML: over 200 req/sec

    Tomcat using JSP (which get triple compiled) getting data out of a MySQL >database on Windows (with db connection pool) and outputting HTML: over
    600 req/sec.

    My gut feeling is that cross-compilation may contribute to but not
    fully explain the difference.

    Almost certainly not; this is an IO bound application, not CPU
    bound.

    My strong suspicion is that what you're seeing is the result of
    a serious impedance mismatch between the multi-process model
    Apache was written to use, and its realization using the event
    signalling infrastructure on VMS. You're undoubtedly hitting
    some sort of serialization point, but with added overhead; at
    that point, Amdahl's law dominates.

    Again, I would try to establish a baseline. Cut out the MPM
    stuff as much as you can; ideally, see what kind of numbers you
    can get fetching your text file from a single Apache process.
    Simply adding more threads or worker processes is unlikely to
    significantly increase performance, and indeed the numbers you
    posted are typical of performance collapse one usually sees due
    to some kind of contention bottleneck.

    Some things to consider: are you creating a new network
    connection for each incoming request? It's possible that that's
    hitting a single listener, which is then trying to dispatch the
    connection to an available worker, using some mechanism that is
    slow on VMS. Is there a profiler available? If you can narrow
    down where it's spending its time, that'd provide a huge clue.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 12:06:09 2024
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    Note that even if it had performed great then it would not
    have been a solution because the real thing the PHP scripts
    has significant latency when interacting with external database
    so parallelization is a must.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Chris Townley on Fri Sep 27 12:47:18 2024
    On 9/27/2024 12:28 PM, Chris Townley wrote:
    I would have thought you would have done something with Java, then used tomcat

    If I were to create a web app on VMS to be used for a specific
    purpose, then I would probably chose something JVM based.

    JSF (that I actually like!), Spring MVC or Grails.

    (JSF would mean Tomcat, Spring MVC either Tomcat or Spring Boot and
    Grails either Tomcat or standalone)

    But even though I have a preference for everything J, then
    I am also interested in other stuff.

    And now I wanted to take a deeper dive in Apache and PHP -
    especially those low performance numbers.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to All on Fri Sep 27 17:28:45 2024
    On 27/09/2024 17:06, Arne Vajhøj wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj  <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    Note that even if it had performed great then it would not
    have been a solution because the real thing the PHP scripts
    has significant latency when interacting with external database
    so parallelization is a must.

    Arne


    I would have thought you would have done something with Java, then used
    tomcat

    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 12:41:03 2024
    On 9/27/2024 10:16 AM, Dan Cross wrote:
    In article <vd6dh4$nrif$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 9:18 AM, Craig A. Berry wrote:
      The only thing I can think of that hasn't already been mentioned >>> is that Tomcat code is JIT-compiled, which is likely to be pretty good,
    optimized code, whereas Apache is probably either cross-compiled or
    native-compiled with an early enough field test compiler that there are
    no optimizations.

    That is a possible explanation.

    But the difference in numbers are crazy big.

    Apache getting a static text file with 2 bytes: 22 req/sec

    Tomcat with Quercus and PHP getting data out of a MySQL database on
    Windows and outputting HTML: over 200 req/sec

    Tomcat using JSP (which get triple compiled) getting data out of a MySQL
    database on Windows (with db connection pool) and outputting HTML: over
    600 req/sec.

    My gut feeling is that cross-compilation may contribute to but not
    fully explain the difference.

    Almost certainly not; this is an IO bound application, not CPU
    bound.

    With static content yes.

    With dynamic content and the volume Apache+mod_php delivers yes.

    With dynamic content and high volume then CPU can matter. Tomcat
    and Quercus can do over 200 req/sec, but CPU utilization fluctuate
    between 150% and 250% - 4 VCPU used so not CPU bound, but could
    have been if it had been just 2 VCPU.

    My strong suspicion is that what you're seeing is the result of
    a serious impedance mismatch between the multi-process model
    Apache was written to use, and its realization using the event
    signalling infrastructure on VMS.

    Yes.

    Or actually slightly worse.

    Prefork MPM is the multi-process model used in Apache 1.x - it is still
    around in Apache 2.x, but Apache 2.x on Linux use event or worker
    MPM (that are a mix of processes and threads) and Apache 2.x on Windows
    use winnt MPM (that is threads only).

    Again, I would try to establish a baseline. Cut out the MPM
    stuff as much as you can;

    MPM is the core of the server.

    ideally, see what kind of numbers you
    can get fetching your text file from a single Apache process.
    Simply adding more threads or worker processes is unlikely to
    significantly increase performance, and indeed the numbers you
    posted are typical of performance collapse one usually sees due
    to some kind of contention bottleneck.

    It increases but not enough.

    1 -> 0.1 req/sec
    150 -> 11 req/sec
    300 -> 22 req/sec

    Some things to consider: are you creating a new network
    connection for each incoming request?

    Yes. Having the load test program keep connections alive
    would be misleading as real world clients would be on different
    systems.

    It's possible that that's
    hitting a single listener, which is then trying to dispatch the
    connection to an available worker,

    That is the typical web server model.

    using some mechanism that is
    slow on VMS.

    It is a good question how Apache on VMS is actually doing that.

    All thread based solutions (OSU, Tomcat etc.) just pass a
    pointer/reference in memory to the thread. Easy.

    Fork create a process copy with the open socket. I am not quite
    sure about the details of how it works, but it works.

    If the model on VMS is:

    ---(HTTP)---parent---(IPC)---child

    then it could explain being so slow.

    I may have to read some of those bloody 3900 lines of code (in a
    single file!).

    Is there a profiler available? If you can narrow
    down where it's spending its time, that'd provide a huge clue.

    Or I take another path.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 19:16:31 2024
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    Note that even if it had performed great then it would not
    have been a solution because the real thing the PHP scripts
    has significant latency when interacting with external database
    so parallelization is a must.

    We're not at the point of discussing solutions. You still don't
    understand what the actual problem is; we're trying to figure
    that out right now.

    Again, it's about understanding the baseline performance
    characteristics first. Your goal right now ought to be figure
    out why requests for a simple static resource, like a text file,
    are so slow; the point by trying something simple is to reduce
    noise due to confounding variables.

    The fact that this is as slow as it is tells you something. Had
    this performed better, that would tell you something as well,
    but in this case, you know that there's some sort of basic slow
    down even in the simplest cases. If you can figure out why that
    is, and address it, _then_ you move on to re-evaluating your
    actual use case, and if necessary, investigate other slow downs.
    But right now, there's little point in doing that: you know you
    see a non-linear slowdown as you increase threads (you _did_
    notice that, right?).

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 19:40:48 2024
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    How long does it take to serve a single request?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 15:27:14 2024
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 19:39:21 2024
    In article <vd6n70$q3fm$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 10:16 AM, Dan Cross wrote:
    In article <vd6dh4$nrif$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 9:18 AM, Craig A. Berry wrote:
      The only thing I can think of that hasn't already been mentioned >>>> is that Tomcat code is JIT-compiled, which is likely to be pretty good, >>>> optimized code, whereas Apache is probably either cross-compiled or
    native-compiled with an early enough field test compiler that there are >>>> no optimizations.

    That is a possible explanation.

    But the difference in numbers are crazy big.

    Apache getting a static text file with 2 bytes: 22 req/sec

    Tomcat with Quercus and PHP getting data out of a MySQL database on
    Windows and outputting HTML: over 200 req/sec

    Tomcat using JSP (which get triple compiled) getting data out of a MySQL >>> database on Windows (with db connection pool) and outputting HTML: over
    600 req/sec.

    My gut feeling is that cross-compilation may contribute to but not
    fully explain the difference.

    Almost certainly not; this is an IO bound application, not CPU
    bound.

    With static content yes.

    Correct. That's all you ought to be looking at under you
    understand why that's slow.

    With dynamic content and the volume Apache+mod_php delivers yes.

    Maybe, but without a profile you really don't know. But beyond
    that, it is currently irrelevant. You see approximately the
    same numbers with static and dynamic content; this heavily
    implies that the dynamic content case is not related to the
    present slow-down, including it now is premature, and likely
    just masks what's _actually_ wrong.

    With dynamic content and high volume then CPU can matter. Tomcat
    and Quercus can do over 200 req/sec, but CPU utilization fluctuate
    between 150% and 250% - 4 VCPU used so not CPU bound, but could
    have been if it had been just 2 VCPU.

    See above. You know that there's a problem with Apache and
    static content, but you don't know _what_ that problem is. Why
    would you jump ahead of yourself worrying about things like that
    until you actually understand what's going on?

    In this case, concentrating on static content, CPU time consumed
    by Apache itself due to poor optimization or something seems
    like a low-probability root cause of the performance problems
    you are seeing, as static file service like this is IO, not
    compute, bound. Keep your eye on the ball.

    My strong suspicion is that what you're seeing is the result of
    a serious impedance mismatch between the multi-process model
    Apache was written to use, and its realization using the event
    signalling infrastructure on VMS.

    Yes.

    Maybe. You really haven't done enough investigation to know, at
    least going by what you've reported here.

    Or actually slightly worse.

    Prefork MPM is the multi-process model used in Apache 1.x - it is still >around in Apache 2.x, but Apache 2.x on Linux use event or worker
    MPM (that are a mix of processes and threads) and Apache 2.x on Windows
    use winnt MPM (that is threads only).

    Ok, sure. But as you posted earlier, Apache on VMS, as you're
    using it, is using the MPM model, no?

    Again, I would try to establish a baseline. Cut out the MPM
    stuff as much as you can;

    MPM is the core of the server.

    No, you misunderstand. Try to cut down on contention due to
    coordination between multiple entities; you do this by
    _lowering_ the number of things at play (processes, threads,
    whatever). The architecture of the server is irrelevant in
    this case; what _is_ relevant is minimizing concurrency in its
    _configuration_. Does that make sense?

    ideally, see what kind of numbers you
    can get fetching your text file from a single Apache process.
    Simply adding more threads or worker processes is unlikely to
    significantly increase performance, and indeed the numbers you
    posted are typical of performance collapse one usually sees due
    to some kind of contention bottleneck.

    It increases but not enough.

    1 -> 0.1 req/sec
    150 -> 11 req/sec
    300 -> 22 req/sec

    Some things to consider: are you creating a new network
    connection for each incoming request?

    Yes. Having the load test program keep connections alive
    would be misleading as real world clients would be on different
    systems.

    Again, you're getting ahead of yourself. Try simulating a
    single client making multiple, repeated tests to a single
    server, ideally reusing a single HTTP connection. This will
    tell you whether the issue is with query processing _inside_
    the server, or if it has something to do with handling new
    connections for each request. If you use HTTP keep alives
    and the number of QPS jumps up, you've narrowed down your
    search space. If it doesn't, you've eliminated one more
    variable, and again, you've cut down on your search space.

    Does that make sense?

    It's possible that that's
    hitting a single listener, which is then trying to dispatch the
    connection to an available worker,

    That is the typical web server model.

    No, it is _a_ common model, but not _the_ "typical" model. For
    instance, many high-performance web solutions are built on an
    asynchronous model, which effectively implement state machines
    where state transitions yield callbacks that are distributed
    across a collection of executor threads. There's no single
    "worker" or dedicated handoff.

    Moreover, there are many different _ways_ to implement the
    "listener hands connection to worker" model, and it _may_ be
    that the way that Apache on VMS is trying to do it is
    inherently slow. We don't know, do we? But that's what we're
    trying to figure out, and that's why I'm encouraging you to
    start simply and build on what you can actually know from
    observation, as opposed to faffing about making guesses.

    using some mechanism that is
    slow on VMS.

    It is a good question how Apache on VMS is actually doing that.

    All thread based solutions (OSU, Tomcat etc.) just pass a
    pointer/reference in memory to the thread. Easy.

    Fork create a process copy with the open socket. I am not quite
    sure about the details of how it works, but it works.

    If the model on VMS is:

    ---(HTTP)---parent---(IPC)---child

    then it could explain being so slow.

    I may have to read some of those bloody 3900 lines of code (in a
    single file!).

    Precisely. And maybe run some more experiments.

    Is there a profiler available? If you can narrow
    down where it's spending its time, that'd provide a huge clue.

    Or I take another path.

    This is a useful exercise either way; getting to the root cause
    of a problem like this may teach you something you could apply
    to other, similar, problems in the future.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 16:11:36 2024
    On 9/27/2024 3:40 PM, Dan Cross wrote:
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests >>>>>> from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    How long does it take to serve a single request?

    Based on the above information it should be 200 seconds.

    But it is actually more like 340 seconds. So apparently the 0.1
    req/sec is rounded up a bit.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 20:13:50 2024
    In article <vd73ho$q3hr$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:40 PM, Dan Cross wrote:
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests >>>>>>> from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down.
    What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    How long does it take to serve a single request?

    Based on the above information it should be 200 seconds.

    But it is actually more like 340 seconds. So apparently the 0.1
    req/sec is rounded up a bit.

    Ok, just to clarify, you hit the web server with a single
    request for a small static resource, while no other traffic was
    hitting it, and that request took more than _five minutes_ to
    complete?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 16:22:02 2024
    On 9/27/2024 4:13 PM, Dan Cross wrote:
    In article <vd73ho$q3hr$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:40 PM, Dan Cross wrote:
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests >>>>>>>> from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down. >>>>>>> What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    How long does it take to serve a single request?

    Based on the above information it should be 200 seconds.

    But it is actually more like 340 seconds. So apparently the 0.1
    req/sec is rounded up a bit.

    Ok, just to clarify, you hit the web server with a single
    request for a small static resource, while no other traffic was
    hitting it, and that request took more than _five minutes_ to
    complete?

    340 seconds is with 20 client threads.

    With 1 client thread time is 17 seconds.

    As expected.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 20:50:00 2024
    In article <vd745a$q3hr$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 4:13 PM, Dan Cross wrote:
    In article <vd73ho$q3hr$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:40 PM, Dan Cross wrote:
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests >>>>>>>>> from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down. >>>>>>>> What happens if you set these super low, ideally so there's a
    single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding
    requests.

    How long does it take to serve a single request?

    Based on the above information it should be 200 seconds.

    But it is actually more like 340 seconds. So apparently the 0.1
    req/sec is rounded up a bit.

    Ok, just to clarify, you hit the web server with a single
    request for a small static resource, while no other traffic was
    hitting it, and that request took more than _five minutes_ to
    complete?

    340 seconds is with 20 client threads.

    With 1 client thread time is 17 seconds.

    So again, to clarify, the time to issue one request against an
    otherwise idle server and retrieve a small amount of static data
    in response to that request is 17 seconds?

    As expected.

    It is always good to verify. I might add that there's no
    relevant environment where that's a reasonable expectation.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 17:10:05 2024
    On 9/27/2024 4:50 PM, Dan Cross wrote:
    In article <vd745a$q3hr$3@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 4:13 PM, Dan Cross wrote:
    In article <vd73ho$q3hr$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:40 PM, Dan Cross wrote:
    In article <66f70712$0$711$14726298@news.sunsite.dk>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 3:16 PM, Dan Cross wrote:
    In article <vd6l5h$pmt5$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/26/2024 11:44 AM, Dan Cross wrote:
    In article <vd1u8j$3qqpg$1@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides >>>>>>>>>> these numbers are absurd high to handle a simulator doing requests >>>>>>>>>> from just 20 threads.

    But not sure what else I can change.

    My guess is that communications overhead is slowing things down. >>>>>>>>> What happens if you set these super low, ideally so there's a >>>>>>>>> single process handling requests, then see what sort of QPS
    numbers you get for your trivial text file.

    I set it down to 1.

    0.1 req/sec

    So a single request takes 10 seconds? Or you can only make one
    request every 10 seconds, but the time taken to process that
    request is relatively small?

    It is throughput.

    N / time it takes to get response for N requests

    With 20 threads in client then there will always be 20 outstanding >>>>>> requests.

    How long does it take to serve a single request?

    Based on the above information it should be 200 seconds.

    But it is actually more like 340 seconds. So apparently the 0.1
    req/sec is rounded up a bit.

    Ok, just to clarify, you hit the web server with a single
    request for a small static resource, while no other traffic was
    hitting it, and that request took more than _five minutes_ to
    complete?

    340 seconds is with 20 client threads.

    With 1 client thread time is 17 seconds.

    So again, to clarify, the time to issue one request against an
    otherwise idle server and retrieve a small amount of static data
    in response to that request is 17 seconds?

    Yes.

    As expected.

    It is always good to verify. I might add that there's no
    relevant environment where that's a reasonable expectation.

    I was referring the math 17 = 340 / 20.

    There is nothing reasonable about those numbers.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Fri Sep 27 21:18:19 2024
    In article <vd76vd$q3hr$4@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/27/2024 4:50 PM, Dan Cross wrote:
    [snip]
    So again, to clarify, the time to issue one request against an
    otherwise idle server and retrieve a small amount of static data
    in response to that request is 17 seconds?

    Yes.

    As expected.

    It is always good to verify. I might add that there's no
    relevant environment where that's a reasonable expectation.

    I was referring the math 17 = 340 / 20.

    There is nothing reasonable about those numbers.

    Agreed. I reiterate my request from https://comp.os.vms.narkive.com/uWy2ouua/apache-mod-php-performance#post50:
    do those numbers change substantially if you send
    multiple queries over a single connection?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Fri Sep 27 23:13:06 2024
    On Fri, 27 Sep 2024 09:59:16 -0400, Arne Vajhøj wrote:

    You setup a read attention AST, it triggers and then you know that there
    are data to be read. There is no reason to make reading async then,
    because you know it will not block.

    I wouldn’t bother with ASTs at all, though I would use async QIOs with I/O status blocks. Here is my proposed control flow, which is very similar to
    a *nix-style poll loop:

    0) Clear the event flag you are going to use in the next step.
    1) Start the initial set of async QIOs on all the channels I want to
    monitor. Give them all the same event flag to set on completion (e.g. the
    usual default EFN 0). Don’t specify any completion ASTs, but do specify
    I/O status blocks.
    2) Wait for the specified EFN to become set.
    3) Clear that EFN.
    4) Go through all your I/O status blocks, and process all I/Os that have completed (status field ≠ 0). Queue new async I/Os for those channels (and any new ones) as appropriate.
    5) If you still have a nonempty set of async QIOs outstanding (i.e. a
    nonempty set of channels being monitored), then go back to step 2.
    Otherwise, you are shutting down, so stop.

    How does that sound?

    Hmmm ... I just realized ... doesn’t QIO immediately clear the EFN you specify, before queueing the actual I/O request? That might blow the whole thing ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 19:34:07 2024
    On 9/27/2024 7:16 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 12:06:09 -0400, Arne Vajhøj wrote:
    ... PHP scripts has significant latency
    when interacting with external database so parallelization is a must.

    I haven’t noticed such latency (albeit mainly with intranet apps written for an SME),

    Sending SQL query from web server to database server over the network,
    having database server find data and sending data from database server
    to web server over the network takes time. Milliseconds.

    but what I have noticed is getting the data with fewer
    queries is faster than getting the same data with more queries.

    total latency from queries = number of queries * average latency of one
    query

    It adds up.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Sep 27 20:07:13 2024
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    And we have a solution.

    httpd.conf

    KeepAlive On

    KeepAlive Off

    And numbers improve dramatically.

    nop.txt 281 req/sec
    nop.php 176 req/sec
    real PHP no db con pool 94 req/sec
    real PHP db con pool 103 req/sec

    Numbers are not great, but within acceptable.

    It is a bug in the code.

    Comment in httpd.conf say:

    # KeepAlive: Whether or not to allow persistent connections (more than
    # one request per connection). Set to "Off" to deactivate.

    It does not say that it will reduce throughput to 1/10'th if on.

    And note that keep alive was not needed for me, but it is needed in many
    other scenarios:
    - web pages with lots of graphics
    - high volume server to server web services

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 20:13:01 2024
    On 9/27/2024 7:55 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 19:34:07 -0400, Arne Vajhøj wrote:
    Sending SQL query from web server to database server over the network,
    having database server find data and sending data from database server
    to web server over the network takes time. Milliseconds.

    You know we can use AF_UNIX sockets within the same machine, right?

    If supported.

    But in that case latency will be small. Microseconds.

    But running application and database on same system is not
    an option if it is a high volume solution or a high availability
    solution with load sharing application and failover database.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Fri Sep 27 23:16:20 2024
    On Fri, 27 Sep 2024 12:06:09 -0400, Arne Vajhøj wrote:

    ... PHP scripts has significant latency
    when interacting with external database so parallelization is a must.

    I haven’t noticed such latency (albeit mainly with intranet apps written
    for an SME), but what I have noticed is getting the data with fewer
    queries is faster than getting the same data with more queries.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Fri Sep 27 23:55:38 2024
    On Fri, 27 Sep 2024 19:34:07 -0400, Arne Vajhøj wrote:

    Sending SQL query from web server to database server over the network,
    having database server find data and sending data from database server
    to web server over the network takes time. Milliseconds.

    You know we can use AF_UNIX sockets within the same machine, right?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Dan Cross on Fri Sep 27 21:11:15 2024
    On 9/27/2024 8:38 PM, Dan Cross wrote:
    In article <vd7hbi$tgu3$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    And we have a solution.

    httpd.conf

    KeepAlive On

    KeepAlive Off

    And numbers improve dramatically.

    Hmm. You had already said that you were _Not_ using keep alives
    because that would somehow mimic multiple machines querying
    simultaneously.

    That is correct.

    The client was not using keep alive.

    But the server was configured to support keep alive.

    Turning that capability off on the server solved the performance
    problem.

    No changes on client.

    No keep alive used before - no keep alive used after.

    Just disabling the capability on the server.

    This was, of course, the area of investigation I had suggested
    to you previously to try and nail down the baseline. I question
    whether this will impact your single query latency, however, or
    whether this is masking it in your benchmark.

    nop.txt 281 req/sec
    nop.php 176 req/sec
    real PHP no db con pool 94 req/sec
    real PHP db con pool 103 req/sec

    Numbers are not great, but within acceptable.

    What is your single query latency? Not calculated, but
    actually measured.

    It is a rather uninteresting number.

    But easy to test. It obviously vary a bit, but they
    are all in the 50-100 millisecond range.

    It is a bug in the code.

    The evidence in hand is insufficient to make that claim.

    I believe that server config supporting keep alive
    causing performance to drop to 1/10'th for clients
    not using keep alive is a bug.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to arne@vajhoej.dk on Sat Sep 28 00:38:18 2024
    In article <vd7hbi$tgu3$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 9/25/2024 5:10 PM, Arne Vajhøj wrote:
    It must be Apache.

    Apache on VMS is prefork MPM. Yuck.

    MaxSpareServers 10 -> 50
    MaxClients 150 -> 300

    actually did improve performance - double from 11 to 22
    req/sec.

    But the system did not like further increases. And besides
    these numbers are absurd high to handle a simulator doing requests
    from just 20 threads.

    But not sure what else I can change.

    And we have a solution.

    httpd.conf

    KeepAlive On

    KeepAlive Off

    And numbers improve dramatically.

    Hmm. You had already said that you were _Not_ using keep alives
    because that would somehow mimic multiple machines querying
    simultaneously.

    This was, of course, the area of investigation I had suggested
    to you previously to try and nail down the baseline. I question
    whether this will impact your single query latency, however, or
    whether this is masking it in your benchmark.

    nop.txt 281 req/sec
    nop.php 176 req/sec
    real PHP no db con pool 94 req/sec
    real PHP db con pool 103 req/sec

    Numbers are not great, but within acceptable.

    What is your single query latency? Not calculated, but
    actually measured.

    It is a bug in the code.

    The evidence in hand is insufficient to make that claim.

    Comment in httpd.conf say:

    # KeepAlive: Whether or not to allow persistent connections (more than
    # one request per connection). Set to "Off" to deactivate.

    It does not say that it will reduce throughput to 1/10'th if on.

    And note that keep alive was not needed for me, but it is needed in many >other scenarios:
    - web pages with lots of graphics
    - high volume server to server web services

    Actually, it's useful for any scenario in which you may send
    several requests to the same server at roughly the same time,
    such as an HTML document and separate CSS stylesheet, not just
    graphics or "server to server web services".

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Sep 27 21:54:54 2024
    On 9/27/2024 8:13 PM, Arne Vajhøj wrote:
    On 9/27/2024 7:55 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 19:34:07 -0400, Arne Vajhøj wrote:
    Sending SQL query from web server to database server over the network,
    having database server find data and sending data from database server
    to web server over the network takes time. Milliseconds.

    You know we can use AF_UNIX sockets within the same machine, right?

    If supported.

    But in that case latency will be small. Microseconds.

    But running application and database on same system is not
    an option if it is a high volume solution or a high availability
    solution with load sharing application and failover database.

    Note that besides the Unix sockets then some databases also
    supports shared memory.

    That includes both MS SQLserver and Oracle Rdb.

    Oracle Rdb is interesting because it out of the box
    supports loadsharing database, which makes application
    and database on same servers a bit easier.

    In that regard Rdb is pretty cool!

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 01:54:11 2024
    On Fri, 27 Sep 2024 20:13:01 -0400, Arne Vajhøj wrote:

    On 9/27/2024 7:55 PM, Lawrence D'Oliveiro wrote:

    On Fri, 27 Sep 2024 19:34:07 -0400, Arne Vajhøj wrote:

    Sending SQL query from web server to database server over the network,
    having database server find data and sending data from database server
    to web server over the network takes time. Milliseconds.

    You know we can use AF_UNIX sockets within the same machine, right?

    If supported.

    But in that case latency will be small. Microseconds.

    Also loopback network connections should be similarly fast. It’s just that Unix sockets allow peers to verify each other’s identity, to shortcut authentication issues.

    But running application and database on same system is not an option if
    it is a high volume solution ...

    Of course it’s an option. Performance is a tradeoff between conflicting system parameters.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 21:58:57 2024
    On 9/27/2024 9:54 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 20:13:01 -0400, Arne Vajhøj wrote:
    But running application and database on same system is not an option if
    it is a high volume solution ...

    Of course it’s an option. Performance is a tradeoff between conflicting system parameters.

    If volume requires sharding then ...

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 02:01:56 2024
    On Fri, 27 Sep 2024 21:58:57 -0400, Arne Vajhøj wrote:

    On 9/27/2024 9:54 PM, Lawrence D'Oliveiro wrote:

    On Fri, 27 Sep 2024 20:13:01 -0400, Arne Vajhøj wrote:

    But running application and database on same system is not an option
    if it is a high volume solution ...

    Of course it’s an option. Performance is a tradeoff between conflicting
    system parameters.

    If volume requires sharding then ...

    “Sharding” means “split across multiple physical persistent storage”.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 22:13:09 2024
    On 9/27/2024 10:01 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 21:58:57 -0400, Arne Vajhøj wrote:
    On 9/27/2024 9:54 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 20:13:01 -0400, Arne Vajhøj wrote:
    But running application and database on same system is not an option
    if it is a high volume solution ...

    Of course it’s an option. Performance is a tradeoff between conflicting >>> system parameters.

    If volume requires sharding then ...

    “Sharding” means “split across multiple physical persistent storage”.

    It means that you have N active database servers each with 1/N of the
    data (possible with replication to N or 2N passive database servers).

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 02:03:18 2024
    On Fri, 27 Sep 2024 21:54:54 -0400, Arne Vajhøj wrote:

    Note that besides the Unix sockets then some databases also supports
    shared memory.

    That includes both MS SQLserver and Oracle Rdb.

    I wonder what are the biggest-scale applications where these products have
    been deployed?

    Facebook, for example, has billions of active users. And Facebook uses
    MySQL.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 01:55:12 2024
    On Fri, 27 Sep 2024 21:11:15 -0400, Arne Vajhøj wrote:

    I believe that server config supporting keep alive causing performance
    to drop to 1/10'th for clients not using keep alive is a bug.

    I would too, since the very reason keepalive was introduced was to improve performance.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 22:18:39 2024
    On 9/27/2024 10:03 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 21:54:54 -0400, Arne Vajhøj wrote:
    Note that besides the Unix sockets then some databases also supports
    shared memory.

    That includes both MS SQLserver and Oracle Rdb.

    I wonder what are the biggest-scale applications where these products have been deployed?

    Rdb probably not so big. Despite the coolness factor.

    SQLServer is used at a few high volume places like MS own Office 365 web
    and StackExchange.

    Facebook, for example, has billions of active users. And Facebook uses
    MySQL.

    FaceBook have a lot of MySQL/MariaDB servers. Sharded! :-)

    They also use some PostgreSQL.

    And for the the real big data they use HBase.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 02:19:38 2024
    On Fri, 27 Sep 2024 22:13:09 -0400, Arne Vajhøj wrote:

    On 9/27/2024 10:01 PM, Lawrence D'Oliveiro wrote:

    On Fri, 27 Sep 2024 21:58:57 -0400, Arne Vajhøj wrote:

    On 9/27/2024 9:54 PM, Lawrence D'Oliveiro wrote:

    On Fri, 27 Sep 2024 20:13:01 -0400, Arne Vajhøj wrote:

    But running application and database on same system is not an option >>>>> if it is a high volume solution ...

    Of course it’s an option. Performance is a tradeoff between
    conflicting system parameters.

    If volume requires sharding then ...

    “Sharding” means “split across multiple physical persistent storage”.

    It means that you have N active database servers each with 1/N of the
    data (possible with replication to N or 2N passive database servers).

    Quite unnecessary, given that the bottleneck is the usually the latency
    and bandwidth of the persistent storage, not the CPU.

    Particularly since your network connections introduce latency and
    bandwidth limitations of their own.

    See what I mean about “tradeoffs”?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Fri Sep 27 22:27:30 2024
    On 9/27/2024 10:18 PM, Arne Vajhøj wrote:
    On 9/27/2024 10:03 PM, Lawrence D'Oliveiro wrote:
    Facebook, for example, has billions of active users. And Facebook uses
    MySQL.

    FaceBook have a lot of MySQL/MariaDB servers. Sharded! :-)

    Also note that FaceBook are using a rather customized
    version. RocksDB as storage engine not normal InnoDB.
    And they have done some stuff to manage failover and
    replication (Raft based??).

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Lawrence D'Oliveiro on Fri Sep 27 22:42:10 2024
    On 9/27/2024 10:19 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 22:13:09 -0400, Arne Vajhøj wrote:
    On 9/27/2024 10:01 PM, Lawrence D'Oliveiro wrote:
    On Fri, 27 Sep 2024 21:58:57 -0400, Arne Vajhøj wrote:
    If volume requires sharding then ...

    “Sharding” means “split across multiple physical persistent storage”.

    It means that you have N active database servers each with 1/N of the
    data (possible with replication to N or 2N passive database servers).

    Quite unnecessary, given that the bottleneck is the usually the latency
    and bandwidth of the persistent storage, not the CPU.

    I don't think Facebook could move their 1800 MySQL shards onto
    a single server.

    Particularly since your network connections introduce latency and
    bandwidth limitations of their own.

    That is not the problem with shards. Applications are usually OK
    with network latency.

    The problem with shards is that not all data usage models fit
    nicely with sharding.

    If you need to get/update a row by primary key then sharding
    works perfect - you go to the right server and just do it.

    If you need to get/update a number of rows and you don't
    know which servers they are on, then it means querying all
    servers, which both create performance and consistency
    problems.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 05:08:18 2024
    On Fri, 27 Sep 2024 22:18:39 -0400, Arne Vajhøj wrote:

    SQLServer is used at a few high volume places like MS own Office 365 web
    and StackExchange.

    I wonder if it was used as part of that London Stock Exchange system that imploded so spectacularly?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 05:07:49 2024
    On Fri, 27 Sep 2024 22:27:30 -0400, Arne Vajhøj wrote:

    On 9/27/2024 10:18 PM, Arne Vajhøj wrote:

    On 9/27/2024 10:03 PM, Lawrence D'Oliveiro wrote:

    Facebook, for example, has billions of active users. And Facebook uses
    MySQL.

    FaceBook have a lot of MySQL/MariaDB servers. Sharded! :-)

    Also note that FaceBook are using a rather customized version. RocksDB
    as storage engine not normal InnoDB.
    And they have done some stuff to manage failover and replication (Raft based??).

    And being Open Source, they can do that kind of thing.

    They even developed their own PHP implementation, HHVM, which they have open-sourced.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sat Sep 28 05:09:18 2024
    On Fri, 27 Sep 2024 22:42:10 -0400, Arne Vajhøj wrote:

    If you need to get/update a row by primary key then sharding works
    perfect - you go to the right server and just do it.

    If you need to get/update a number of rows and you don't know which
    servers they are on, then it means querying all servers, which both
    create performance and consistency problems.

    Well, you were the one who brought up sharding, not me ...

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to Dan Cross on Fri Oct 4 19:14:41 2024
    On 04/10/2024 18:43, Dan Cross wrote:
    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    - Dan C.


    I was looking on comp.lang.python and I see a post saying has been
    banned from the list, and requesting anybody seeing usenet posts to
    ignore him!

    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Chris Townley on Fri Oct 4 13:28:18 2024
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    On 03/10/2024 20:09, Dave Froble wrote:
    On 10/2/2024 8:14 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:
    It would be a lot easier without the C RTL data structures and the RMS >>>>> data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally
    rare.

    Not around here.

    And I’m not clear what the point of >>>> them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file descriptor >>> over Unix socket as well.

    I thought sockets was the issue?

    Before we closed down operations, I was looking at passing a socket to another
    process. Not sure if I could, didn't get that far. From the docs, I should >> be able to open a socket with the SHARE flag, then have another process open >> the same socket.

    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...



    I'm not sure whether I've been insulted?

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chris Townley@21:1/5 to Dave Froble on Fri Oct 4 19:12:53 2024
    On 04/10/2024 18:28, Dave Froble wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    On 03/10/2024 20:09, Dave Froble wrote:
    On 10/2/2024 8:14 PM, Arne Vajhøj wrote:
    On 10/2/2024 8:02 PM, Lawrence D'Oliveiro wrote:
    On Wed, 2 Oct 2024 19:57:50 -0400, Arne Vajhøj wrote:
    It would be a lot easier without the C RTL data structures and the >>>>>> RMS
    data structures.

    But they exist.

    VMS doesn’t force you to use them.

    True. But using $QIO(W) or $IO_PERFOM(W) for IO is exceptionally
    rare.

    Not around here.

                                        And I’m not clear what the
    point of
    them is, for network I/O.

    None.

    But I believe you said that on *nix you could transfer a file
    descriptor
    over Unix socket as well.

    I thought sockets was the issue?

    Before we closed down operations, I was looking at passing a socket
    to another
    process.  Not sure if I could, didn't get that far.  From the docs, I
    should
    be able to open a socket with the SHARE flag, then have another
    process open
    the same socket.

    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...



    I'm not sure whether I've been insulted?

    Sorry, I wasn't calling you a troll

    --
    Chris

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Fri Oct 4 17:43:02 2024
    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to news@cct-net.co.uk on Fri Oct 4 18:34:47 2024
    In article <vdpbaj$6l1q$1@dont-email.me>,
    Chris Townley <news@cct-net.co.uk> wrote:
    On 04/10/2024 18:43, Dan Cross wrote:
    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave! ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    I was looking on comp.lang.python and I see a post saying has been
    banned from the list, and requesting anybody seeing usenet posts to
    ignore him!

    Shocking. :-)

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Michael S on Fri Oct 11 08:00:42 2024
    On 10/11/2024 6:11 AM, Michael S wrote:
    On Thu, 10 Oct 2024 23:01:13 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:
    Actually, simple.

    1) Create the socket in listener process
    2) Pass device name to worker process
    3) Assign a channel to the device in worker process
    4) deassign the channel in listener process (if desired)


    There are few pieces in your simple explanation that I don't understand:
    - How does listener get a device name?

    There may be multiple ways, but if using the SYS$QIO(W)
    interface then the code has a channel and SYS$GETDVI(W)
    can get the device name from that.

    - What is "channel"? Is it the same as 'socket'?

    I assume a VMS channel as one get from SYS$ASSIGN.

    - How one "assigns" channel to device? I would guess that device has to
    be open before that?

    Call SYS$ASSIGN.

    - Is device name of the socket system-global?
    If yes, does it mean that any process in the system that happens to
    know a name can open a device and assign it to channel?

    Device names are system wide.

    But there are access controls in place.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to already5chosen@yahoo.com on Fri Oct 11 12:35:48 2024
    In article <20241011131151.00003a02@yahoo.com>,
    Michael S <already5chosen@yahoo.com> wrote:
    On Thu, 10 Oct 2024 23:01:13 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:
    [snip]
    Actually, simple.

    1) Create the socket in listener process
    2) Pass device name to worker process
    3) Assign a channel to the device in worker process
    4) deassign the channel in listener process (if desired)


    There are few pieces in your simple explanation that I don't understand:
    - How does listener get a device name?

    There's a system service (system call) that let's you do that;
    it is called `$GETDVI` ("GET Device/Volume Information"). There
    is a wrapper in the standard library that makes it a little
    easier to work with, `LIB$GETDVI`.

    - What is "channel"? Is it the same as 'socket'?

    A channel is a process-unique identifier for some resource you
    want to interact with, such as a device or mailbox. A rough
    analogue from the Unix/Linux world is a file descriptor. On VMS
    a socket is a "device", so to interact with it, you must
    associate a channel with it.

    - How one "assigns" channel to device? I would guess that device has to
    be open before that?

    There's a system service for that. Section 7.5 of the "VMS
    Programming Concepts (volume 2)" manual on the VSI web site goes
    into detail about exactly how to do it, but `$ASSIGN` takes a
    devine name and allocates and assigns a channel to it.

    - Is device name of the socket system-global?

    Yes.

    If yes, does it mean that any process in the system that happens to
    know a name can open a device and assign it to channel?

    No, there are authorization checks and so forth that the system
    makes before assignment completes successfully; there's also the
    matter that, if a device is already assigned exclusively, by
    default it can't be assigned to another process at the same
    time. That's what all of this business about the SHARE
    privilege is about; section 7.2.8 of the programming concepts
    manual talks about this, but basically, if a process has the
    `SHARE` privilege, it can `$ASSIGN` another device accessed
    "exclusively" by another process's device. A subprocess of a
    process can also assign a channel to a device that's assigned
    to the parent (I dunno if that last bit is always true; it was
    in section 18.3 of the "VAX/VMS Internals and Data Structures"
    book for VMS 4.4, which is pretty old).

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Michael S@21:1/5 to All on Fri Oct 11 16:11:05 2024
    On Fri, 11 Oct 2024 12:35:48 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    Thank you.
    I am more that a little out of my VMS knowledge depth, but after your explanations I certainly understand more.

    Thank you to Arne too.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Fri Oct 11 14:14:53 2024
    In article <vea6ak$3h25s$2@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/7/2024 4:17 PM, Dan Cross wrote:
    In article <ve1f1t$1mvdn$2@dont-email.me>,
    Arne Vajhøj <arne@vajhoej.dk> wrote:
    On 10/7/2024 11:52 AM, Dan Cross wrote:
    $ cc zz

    len = CMSG_SPACE(sizeof(int));
    .........^
    %CC-I-IMPLICITFUNC, In this statement, the identifier "CMSG_SPACE" is
    implicitly declared as a function.
    at line number 33 in file DKA0:[arne]zz.c;1
    [snip]

    Why would you try to build that under VMS? It obviously would
    not build or work there.

    Yeah, also wondered ...

    I think he was confused. His justification that VMS must not
    support descriptor passing because of the errors he saw, and he
    was just saying that, doesn't hold much water, either.

    As I mentioned back in <vdk7fi$jdm$1@reader1.panix.com>, the
    descriptor passing mechanism was added in 4.2BSD, back in 1983,
    but it was _updated_ in 4.4BSD, in 1994. The code I posted
    used the 4.4BSD mechansim. Clearly, that isn't supported on VMS
    as he showed, but that's not the only way to do it.

    In particular, the 4.3BSD mechanism uses different fields in the
    `struct msghdr` to move descriptors around, and those are at
    least in the struct definitions on VMS. Do they do anything? I
    kind of tend to doubt it, but for example the code below does
    compile on Eisner, though I haven't written a driver to see if
    it actually _works_.

    - Dan C.

    /*
    * Example code to demonstrate file descriptor passing
    * over Berkeley sockets.
    *
    * Dan Cross <cross@gajendra.net>
    */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/uio.h>
    #include <sys/un.h>
    #include <sys/wait.h>

    #include <fcntl.h>
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>

    int
    unix_server(char *path)
    {
    int nsd, sd;
    socklen_t clen;
    struct sockaddr_un sock;

    sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
    perror("socket");
    exit(EXIT_FAILURE);
    }
    memset(&sock, 0, sizeof(sock));
    sock.sun_family = AF_UNIX;
    strncpy(sock.sun_path, path, sizeof(sock.sun_path));
    if (bind(sd, (struct sockaddr *)&sock, sizeof(sock)) < 0) {
    perror("bind");
    exit(EXIT_FAILURE);
    }
    if (listen(sd, 5) < 0) {
    perror("listen");
    exit(EXIT_FAILURE);
    }
    clen = sizeof(sock);
    nsd = accept(sd, (struct sockaddr *)&sock, &clen);
    if (nsd < 0) {
    perror("accept");
    exit(EXIT_FAILURE);
    }
    close(sd);

    return(nsd);
    }

    int
    unix_client(char *path)
    {
    int sd;
    struct sockaddr_un sock;

    sd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sd < 0) {
    perror("socket");
    exit(EXIT_FAILURE);
    }
    memset(&sock, 0, sizeof(sock));
    sock.sun_family = AF_UNIX;
    strncpy(sock.sun_path, path, sizeof(sock.sun_path));
    if (connect(sd, (struct sockaddr *)&sock, sizeof(sock)) < 0) {
    perror("connect");
    exit(EXIT_FAILURE);
    }

    return(sd);
    }

    /* Send a file descriptor; returns 1 on success, -1 on error */
    int
    send_fd(int sd, int fd)
    {
    struct msghdr mh;
    struct iovec iv;
    char dummy;

    memset(&iv, 0, sizeof(iv));
    iv.iov_base = &dummy;
    iv.iov_len = sizeof(char);

    memset(&mh, 0, sizeof(mh));
    mh.msg_name = NULL;
    mh.msg_namelen = 0;
    mh.msg_iov = &iv;
    mh.msg_iovlen = 1;

    /* Now we copy in the file descriptor. */
    mh.msg_accrights = (caddr_t)&fd;
    mh.msg_accrightslen = sizeof(int);

    return(sendmsg(sd, &mh, 0));
    }

    /* Returns 1 on success, 0 on EOF, -1 on error. */
    int
    recv_fd(int sd, int *fdp)
    {
    struct msghdr mh;
    struct iovec iv;
    int ret;
    char dummy;

    if (fdp == NULL)
    return(-1);

    memset(&iv, 0, sizeof(iv));
    iv.iov_base = &dummy;
    iv.iov_len = 1;

    memset(&mh, 0, sizeof(mh));
    mh.msg_name = NULL;
    mh.msg_namelen = 0;
    mh.msg_iov = &iv;
    mh.msg_iovlen = 1;
    mh.msg_accrights = (caddr_t)fdp;
    mh.msg_accrightslen = sizeof(int);

    if ((ret = recvmsg(sd, &mh, 0)) < 0)
    return(ret);

    if (mh.msg_accrightslen != sizeof(int))
    return(-1);

    return(1);
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Fri Oct 11 13:30:51 2024
    In article <vea73n$3h7jt$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/7/2024 2:01 PM, Dan Cross wrote:
    As Dave has mentioned, setting SO_SHARE on a socket would be another way >>> to accomplish this.

    Neither of these sounds the same as descriptor passing over Unix
    domain sockets on Unix/Linux; the auxiliary server sounds more
    like `inetd`, in that there's some service that's listening and
    accepting connections on some TCP/IP port, and then creating a
    server to handle each incoming connection.

    I would claim that what I did is NOT passing a descriptor, or whatever, to >another process. Not really sure what that means. All I passed was the device
    name, and let the second process assign a channel to the "existing" device (socket).

    Ok. Conceptually, this is pretty much the same thing, then, at
    least as far as sockets are concerned.

    SO_SHARE is different again; it appears that the shared socket
    must be created before the subprocesses that use it are created.

    I don't know why you would say that.

    I was just wrong.

    A process must exist before it can do
    anything, but, a socket can exist in a process, and then connected to in another
    process, regardless of when the second process is created. For example, if a >bank of worker processes exist, and a task comes in, the connection socket could
    be opened by the existing selected worker process.

    The mechanism on Unix remains a little bit different, maybe, in
    that there's no need to set the socket to be sharable at all;
    indeed, Unix has no analogue of the `SO_SHARE` socket option on
    VMS.

    Vis process creation time, a scenario that could happen on Unix
    is that two processes, A and B, are started; they can run for
    indefinitely long, but at some point well after creation/start,
    A could create a (named) Unix domain socket that is then opened
    by B. A could then create a listening socket and begin
    accepting incoming connections on it, and pass those over the
    Unix domain socket to B. The two processes needn't share any
    kind of parent/child relationship, nor do they have to run as
    the same user, etc; as long as B has appropriate permissions to
    open the socket created by A, this will all work as expected.
    Indeed, this is desireable, as it provides a mechanism for
    privilege separation across a process boundary.

    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to Dan Cross on Fri Oct 11 14:28:35 2024
    In article <vebbst$6qv$1@reader1.panix.com>,
    Dan Cross <cross@spitfire.i.gajendra.net> wrote:
    In particular, the 4.3BSD mechanism uses different fields in the
    `struct msghdr` to move descriptors around, and those are at
    least in the struct definitions on VMS. Do they do anything? I
    kind of tend to doubt it, but for example the code below does
    compile on Eisner, though I haven't written a driver to see if
    it actually _works_.
    [snip]

    PS: I've added this code, along with a driver I tested on
    illumos and the other programs that I've written and posted
    lately (with some bug fixes; ahem) to a repository on github,
    for anyone who's interested in this stuff.

    https://github.com/dancrossnyc/socket-examples

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Dan Cross on Fri Oct 11 12:31:03 2024
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    In article <vea73n$3h7jt$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/7/2024 2:01 PM, Dan Cross wrote:
    As Dave has mentioned, setting SO_SHARE on a socket would be another way >>>> to accomplish this.

    Neither of these sounds the same as descriptor passing over Unix
    domain sockets on Unix/Linux; the auxiliary server sounds more
    like `inetd`, in that there's some service that's listening and
    accepting connections on some TCP/IP port, and then creating a
    server to handle each incoming connection.

    I would claim that what I did is NOT passing a descriptor, or whatever, to >> another process. Not really sure what that means. All I passed was the device
    name, and let the second process assign a channel to the "existing" device (socket).

    Ok. Conceptually, this is pretty much the same thing, then, at
    least as far as sockets are concerned.

    SO_SHARE is different again; it appears that the shared socket
    must be created before the subprocesses that use it are created.

    I don't know why you would say that.

    I was just wrong.

    A process must exist before it can do
    anything, but, a socket can exist in a process, and then connected to in another
    process, regardless of when the second process is created. For example, if a
    bank of worker processes exist, and a task comes in, the connection socket could
    be opened by the existing selected worker process.

    The mechanism on Unix remains a little bit different, maybe, in
    that there's no need to set the socket to be sharable at all;
    indeed, Unix has no analogue of the `SO_SHARE` socket option on
    VMS.

    Vis process creation time, a scenario that could happen on Unix
    is that two processes, A and B, are started; they can run for
    indefinitely long, but at some point well after creation/start,
    A could create a (named) Unix domain socket that is then opened
    by B. A could then create a listening socket and begin
    accepting incoming connections on it, and pass those over the
    Unix domain socket to B. The two processes needn't share any
    kind of parent/child relationship, nor do they have to run as
    the same user, etc; as long as B has appropriate permissions to
    open the socket created by A, this will all work as expected.
    Indeed, this is desireable, as it provides a mechanism for
    privilege separation across a process boundary.

    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    - Dan C.


    The share flag is for the device.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Michael S on Fri Oct 11 12:20:36 2024
    On 10/11/2024 6:11 AM, Michael S wrote:
    On Thu, 10 Oct 2024 23:01:13 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:

    On 10/7/2024 4:07 AM, Michael S wrote:
    On Mon, 7 Oct 2024 00:35:36 -0400
    Dave Froble <davef@tsoft-inc.com> wrote:

    On 10/6/2024 11:12 AM, Michael S wrote:
    On Fri, 4 Oct 2024 17:43:02 -0000 (UTC)
    cross@spitfire.i.gajendra.net (Dan Cross) wrote:

    In article <vdp8kn$a67s$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/3/2024 7:00 PM, Chris Townley wrote:
    [snip]
    I don't remember George, but we have certainly woken up Dave!
    ;)

    and I am sure the troll is happy...

    I'm not sure whether I've been insulted?

    I suspect the "troll" reference is to Lawrence. Sadly, Arne can
    not help himself when it comes to resisting arguing with that
    clown.

    - Dan C.


    Troll or not, but the question about ability to pass open TCP
    socket to child process (or, may be, to unrelated process) under
    VMS is a good question.
    As a lurker, I am waiting for the expert answer with interest.


    Well, some of the issue is in the text of the question. What does
    one mean be "pass socket"?

    When creating a socket, one can specify it to be shared. What I
    was doing was passing the information to a worker process, then
    letting the worker process open the existing socket.

    So, would that be considered "passing an open socket"?


    Yes, it would be.

    On Windows one has to go through similar 3-stage procedure:
    - [in parent process] acquire magic record from the open socket by
    means of WSADuplicateSocket()
    - pass the record to child by any of available IPC mechanisms
    - [in child process] use magic record to re-open socket with
    WSASocket()

    I never had a need of for it in practice. Looking at docs it seems
    that the procedure above has at least one inconvenient aspect - the
    target process has to exist at the moment of WSADuplicateSocket()
    call. Still, I suppose that it's better than nothing.

    I can post some of the development code is anyone is interested. I
    was working on the inter-process communications when I dropped the
    project. I believe I did open the shared socket in the worker
    process.


    May be, others are interested in the code.
    For me, I'd rather read textual description of the procedure and war
    story of making it work.


    Actually, simple.

    1) Create the socket in listener process
    2) Pass device name to worker process
    3) Assign a channel to the device in worker process
    4) deassign the channel in listener process (if desired)


    There are few pieces in your simple explanation that I don't understand:

    I posted the sample code.

    Understand, I used the QIO interface, not CRTL.

    - How does listener get a device name?

    Note that we're discussing BG devices.

    - What is "channel"? Is it the same as 'socket'?

    Channel is VMS channel

    - How one "assigns" channel to device? I would guess that device has to
    be open before that?

    If one has a device name, then one can assign a channel to that device.

    - Is device name of the socket system-global?

    Yes, I think so.

    If yes, does it mean that any process in the system that happens to
    know a name can open a device and assign it to channel?

    If shared access is specified, then yes.


    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Fri Oct 11 17:45:30 2024
    In article <vebjse$3nq13$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    [snip]
    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    The share flag is for the device.

    Ok, sure. But does that mean that there's _no_ authorization
    checking of any kind to access the device? For example, no
    checking UICs or ACLs or something? If I set SO_SHARE on a
    socket, can _any_ process on the system, regardless of who it is
    running as, access that socket?

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Dan Cross on Fri Oct 11 13:26:04 2024
    On 10/11/24 12:45 PM, Dan Cross wrote:
    In article <vebjse$3nq13$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    [snip]
    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    The share flag is for the device.

    Ok, sure. But does that mean that there's _no_ authorization
    checking of any kind to access the device? For example, no
    checking UICs or ACLs or something? If I set SO_SHARE on a
    socket, can _any_ process on the system, regardless of who it is
    running as, access that socket?

    $ show device/full

    on any BG device shows normal-looking device protections just as you
    would see on any other device, e.g.:

    Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL

    I don't think socket sharing is a privilege any more than file sharing
    is; more likely it's just a hint to the driver that it needs to do extra
    work to keep its internal state consistent when two processes are
    accessing it.

    There is an old Ask-the-Wizard article about socket sharing that uses a
    mailbox to send the BG device name to the child process:

    https://forum.vmssoftware.com/viewtopic.php?f=35&t=3511&p=7513

    The example code sends UCX$C_SHARE using the QIO interface rather than
    SO_SHARE and setsockopt(); I'm guessing it amounts to the same thing but
    I can't find current relevant documentation for either.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to Craig A. Berry on Fri Oct 11 18:56:53 2024
    In article <vebqjs$3oaus$1@dont-email.me>,
    Craig A. Berry <craigberry@nospam.mac.com> wrote:

    On 10/11/24 12:45 PM, Dan Cross wrote:
    In article <vebjse$3nq13$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    [snip]
    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    Just to be clear, because I think there may be some confusion,
    but nowhere above was I suggesting that the `SHARE` _privilege_
    is the same as the `SO_SHARE` _option_ on a socket.

    The share flag is for the device.

    Ok, sure. But does that mean that there's _no_ authorization
    checking of any kind to access the device? For example, no
    checking UICs or ACLs or something? If I set SO_SHARE on a
    socket, can _any_ process on the system, regardless of who it is
    running as, access that socket?

    $ show device/full

    on any BG device shows normal-looking device protections just as you
    would see on any other device, e.g.:

    Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL

    Interestingly, for BG devies, they're _all_ the same, with the R
    bit set for everyone, which, if they just used the default
    scheme, would mean that any socket device was ASSIGNable to
    anyone, right? That does not sound correct. For example, here
    is an `ssh` socket on Eisner:

    |Device BG8729:, device type unknown, is online, record-oriented device, network
    | device, mailbox device.
    |
    | Error count 0 Operations completed 210
    | Owner process "SSHD 0012" Owner UIC [SYSTEM]
    | Owner process ID 00003C50 Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL
    | Reference count 2 Default buffer size 256

    Surely the device protection field here is misleading, at best?

    I don't think socket sharing is a privilege any more than file sharing
    is; more likely it's just a hint to the driver that it needs to do extra
    work to keep its internal state consistent when two processes are
    accessing it.

    That seems right, given what we've seen. Anyway, I think this
    put's to rest Arne's assertion that there's no way to give some
    process access to a socket created by another process.

    There is an old Ask-the-Wizard article about socket sharing that uses a >mailbox to send the BG device name to the child process:

    https://forum.vmssoftware.com/viewtopic.php?f=35&t=3511&p=7513

    The example code sends UCX$C_SHARE using the QIO interface rather than >SO_SHARE and setsockopt(); I'm guessing it amounts to the same thing but
    I can't find current relevant documentation for either.

    I saw that; most of the solutions in this space look more or
    less the same. I confess I remain mystified by the seeming lack
    of an authorizaton mechanism, however.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Craig A. Berry on Fri Oct 11 21:07:18 2024
    On Fri, 11 Oct 2024 13:26:04 -0500, Craig A. Berry wrote:

    I don't think socket sharing is a privilege any more than file sharing
    is; more likely it's just a hint to the driver that it needs to do extra
    work to keep its internal state consistent when two processes are
    accessing it.

    Surely having channels from two processes assigned to the same device is
    no different, as far as the device is concerned, from having two channels assigned to it in the same process. In VMS, process scheduling is
    completely decoupled from I/O management; once an I/O is queued, nothing further happens to affect the process until the completed request gets
    back to the I/O post-processing system, at which point it no longer
    concerns the device driver any more.

    At least, that’s how it used to work in the VMS of old.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to davef@tsoft-inc.com on Fri Oct 11 21:29:34 2024
    In article <vec4sb$3qc1e$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 1:45 PM, Dan Cross wrote:
    In article <vebjse$3nq13$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    [snip]
    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    The share flag is for the device.

    Ok, sure. But does that mean that there's _no_ authorization
    checking of any kind to access the device? For example, no
    checking UICs or ACLs or something? If I set SO_SHARE on a
    socket, can _any_ process on the system, regardless of who it is
    running as, access that socket?

    Dan, it's been quite a while, so I'd have to research that question.

    If I had to guess, I'd expect all VMS protections and such to be respected. I >doubt one could just go out and access any BG device without having access.

    I should hope so, Dave, but as it is, it looks under
    documented at best.

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dave Froble@21:1/5 to Dan Cross on Fri Oct 11 17:21:06 2024
    On 10/11/2024 1:45 PM, Dan Cross wrote:
    In article <vebjse$3nq13$1@dont-email.me>,
    Dave Froble <davef@tsoft-inc.com> wrote:
    On 10/11/2024 9:30 AM, Dan Cross wrote:
    [snip]
    As I gather, on VMS the analogous mechanism works since a) every
    socket on the system is associated with a unique device name in
    some global namespace, and b) once known, an unrelated process
    can $ASSIGN that device name, subject to authorization checking
    enforced by the system. The authorization checks seem to be
    either, a) a process/subprocess relationship, or b) the
    assigning process has the SHARE privilege; it's not clear to me
    what else could go into those checks and how that interacts with
    e.g. SO_SHARE; presumably at least UIC checks or something must
    be completed?

    The share flag is for the device.

    Ok, sure. But does that mean that there's _no_ authorization
    checking of any kind to access the device? For example, no
    checking UICs or ACLs or something? If I set SO_SHARE on a
    socket, can _any_ process on the system, regardless of who it is
    running as, access that socket?

    - Dan C.


    Dan, it's been quite a while, so I'd have to research that question.

    If I had to guess, I'd expect all VMS protections and such to be respected. I doubt one could just go out and access any BG device without having access.

    --
    David Froble Tel: 724-529-0450
    Dave Froble Enterprises, Inc. E-Mail: davef@tsoft-inc.com
    DFE Ultralights, Inc.
    170 Grimplin Road
    Vanderbilt, PA 15486

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Craig A. Berry@21:1/5 to Dan Cross on Fri Oct 11 16:43:26 2024
    On 10/11/24 1:56 PM, Dan Cross wrote:
    In article <vebqjs$3oaus$1@dont-email.me>,
    Craig A. Berry <craigberry@nospam.mac.com> wrote:

    $ show device/full

    on any BG device shows normal-looking device protections just as you
    would see on any other device, e.g.:

    Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL

    Interestingly, for BG devies, they're _all_ the same, with the R
    bit set for everyone, which, if they just used the default
    scheme, would mean that any socket device was ASSIGNable to
    anyone, right? That does not sound correct. For example, here
    is an `ssh` socket on Eisner:

    |Device BG8729:, device type unknown, is online, record-oriented device, network
    | device, mailbox device.
    |
    | Error count 0 Operations completed 210
    | Owner process "SSHD 0012" Owner UIC [SYSTEM]
    | Owner process ID 00003C50 Dev Prot S:RWPL,O:RWPL,G:RWPL,W:RWPL
    | Reference count 2 Default buffer size 256

    Surely the device protection field here is misleading, at best?

    Well, you _can_ change the values:

    $ show security/class=device bg111

    _BG111: object of class DEVICE
    Owner: [SYSTEM]
    Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: RWPL)
    Access Control List: <empty>

    $ set security/class=device/protection=(w:r) bg111
    $ show security/class=device bg111

    _BG111: object of class DEVICE
    Owner: [SYSTEM]
    Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: R)
    Access Control List: <empty>

    Note that World is now read, but write, physical, and logical have been removed. But I don't really know if that accomplished anything. It
    seems unlikely that BGDRIVER would just fill in values in a template
    that don't mean anything, but testing out exactly what the protections
    get you sounds like work.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Craig A. Berry on Fri Oct 11 18:52:01 2024
    On 10/11/2024 5:43 PM, Craig A. Berry wrote:
    Well, you _can_ change the values:

    $ show security/class=device bg111

    _BG111: object of class DEVICE
         Owner: [SYSTEM]
         Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: RWPL)
         Access Control List: <empty>

    $ set security/class=device/protection=(w:r) bg111
    $ show security/class=device bg111

    _BG111: object of class DEVICE
         Owner: [SYSTEM]
         Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: R)
         Access Control List: <empty>

    Note that World is now read, but write, physical, and logical have been removed.  But I don't really know if that accomplished anything.  It
    seems unlikely that BGDRIVER would just fill in values in a template
    that don't mean anything, but testing out exactly what the protections
    get you sounds like work.

    The names give strong associations.

    So I would expect:

    IO$_READVBLK - need R
    IO$_READLBLK - need R and L
    IO$_READPBLK - need R and P
    IO$_WRITEVBLK - need W
    IO$_WRITELBLK - need W and L
    IO$_WRITEPBLK - need W and P

    And the guide to system security says:

    <quote>
    5.3.2. Types of Access
    Devices can be shared and thus have concurrent users or be unshared and
    have a single user.
    Shared devices support the following types of access:
    Read Gives you the right to read data from the device
    Write Gives you the right to write data to the device
    Physical Gives you the right to perform physical I/O operations to the
    device
    Logical Gives you the right to perform logical I/O operations to the device Control Gives you the right to change the protection elements and owner
    of the device
    Unshared devices support only read, write, and control access. The
    device driver rather than the
    operating system's security policy defines the access requirements for
    other types of operations.
    ...
    $QIO to file-oriented devices: disks and tapes
    With file-oriented devices, logical I/O and physical I/O functions have
    common elements. Any
    logical I/O function requires physical or logical access plus read
    access to read a block (READLBLK)
    or write access to write a block (WRITELBLK). Any physical I/O function requires physical
    access plus either read access to read a block (READPBLK) or write
    access to write a block
    (WRITEPBLK). Logical and physical I/O also require LOG_IO and PHY_IO privileges, respectively.
    ...
    $QIO to devices that are not file-oriented
    With non-file-oriented devices, OpenVMS converts virtual read and write
    I/O requests to logical I/O
    before processing them. Other kinds of access requests are not processed
    by OpenVMS; instead, the
    request is passed to the device driver for processing.
    In general, access requirements for devices that are not file oriented
    depend on whether the device is
    shareable or nonshareable:
    • Shareable device
    With shareable devices, such as mailboxes, any virtual I/O function
    other than READVBLK/
    WRITEVBLK is handled by the system I/O driver program. Any logical I/O
    function requires
    privilege or logical access to the device. Any physical I/O function
    requires privilege or physical
    access to the device.
    • Unshareable devices
    With unshareable devices, such as terminals or printers, the operating
    system checks only for read
    or write access to perform virtual and logical I/O functions. Any
    physical I/O function requires
    privilege.
    </quote>

    Which I read as confirmation. It works like expected for
    file oriented devices and for shareable non file oriented
    devices, but non shareable non file oriented devices ignore
    L and P. BG devices are shareable non file oriented
    devices.

    Arne




    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mark Daniel@21:1/5 to Craig A. Berry on Sat Oct 12 09:38:52 2024
    On 12/10/2024 08:13, Craig A. Berry wrote:

    On 10/11/24 1:56 PM, Dan Cross wrote:
    8< snip 8<
    Surely the device protection field here is misleading, at best?

    Well, you _can_ change the values:

    $ show security/class=device bg111

    _BG111: object of class DEVICE
         Owner: [SYSTEM]
         Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: RWPL)
         Access Control List: <empty>

    $ set security/class=device/protection=(w:r) bg111
    $ show security/class=device bg111

    _BG111: object of class DEVICE
         Owner: [SYSTEM]
         Protection: (System: RWPL, Owner: RWPL, Group: RWPL, World: R)
         Access Control List: <empty>

    Note that World is now read, but write, physical, and logical have been removed.  But I don't really know if that accomplished anything.  It
    seems unlikely that BGDRIVER would just fill in values in a template
    that don't mean anything, but testing out exactly what the protections
    get you sounds like work.

    Bit fiddly but to show the protections apply the original BG_EXAMPLE.C
    was modified to wait for a read from the telnet connection

    chan = decc$get_sdc (csock);
    printf ("chan: %d\n", chan);
    if (!chan) return (vaxc$errno);

    cptr = GetBgDevice (chan);
    printf ("BgDevice: |%s|\n", cptr);

    memset (buf, 0, sizeof(buf));
    count = recv (csock, buf, sizeof(buf), 0);
    printf ("count: %d |%s|\n", count, buf);
    if (count <= 0) return (vaxc$errno);

    and the executable installed to provide the SHARE privilege for an
    otherwise unprivileged account

    X86VMS$ install replace DKA100:[SCRATCH]bg2_example.exe /priv=share

    The listener output then became

    X86VMS$ mcr []bg2_example
    accept()
    chan: 304
    BgDevice: |BG11402:|

    The SYSTEM account (fully privileged) could write to the socket

    X86VMS$ mcr []bg2_example BG11402:
    sys$setprv() %X00000001
    sys$assign() %X00000001
    sys$qiow() 14 %X00000001 %X00000001
    write() 14 %X00000001

    %TELNET-I-SESSION, Session 01, host localhost, port 8765
    -TELNET-I-ESCAPE, Escape character is ^]
    abcdefghij

    klmnopqrst

    As could the unprivileged account (using the INSTALLed SHARE privilege)

    12-OCT-2024 09:26:08.36 User: MGD Process ID: 000045A3
    Node: X86VMS Process name: "MGD"

    Authorized privileges:
    NETMBX TMPMBX

    Process privileges:
    NETMBX may create network device
    TMPMBX may create temporary mailbox

    X86VMS$ mcr []bg2_example BG11402:
    sys$setprv() %X00000001
    sys$assign() %X00000001
    sys$qiow() 14 %X00000001 %X00000001
    write() 14 %X00000001

    but after modifying the BG device security (pasted as quotation to
    circumvent wrapping)

    X86VMS$ set sec BG11402: /class=device /prot=(world)
    X86VMS$ show dev /full BG11402:

    Device BG11402:, device type unknown, is online, mounted, record-oriented
    device, network device, mailbox device.

    Error count 0 Operations completed 2
    Owner process "FTA10_SYSTEM" Owner UIC [SYSTEM]
    Owner process ID 00001599 Dev Prot S:RWPL,O:RWPL,G:RWPL,W
    Reference count 1 Default buffer size 256

    X86VMS$ mcr []bg2_example BG11402:
    sys$setprv() %X00000001
    sys$assign() %X00000024
    write() -1 %X0000013C
    X86VMS$ exit %X00000024
    %SYSTEM-F-NOPRIV, insufficient privilege or object protection violation
    X86VMS$ exit %X00000024

    while the owner (SYSTEM) continued to have access

    X86VMS$ mcr []bg2_example BG11402:
    sys$setprv() %X00000001
    sys$assign() %X00000001
    sys$qiow() 14 %X00000001 %X00000001
    write() 14 %X00000001

    --
    Anyone, who using social-media, forms an opinion regarding anything
    other than the relative cuteness of this or that puppy-dog, needs
    seriously to examine their critical thinking.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Dan Cross@21:1/5 to mark.daniel@wasd.vsm.com.au on Sat Oct 12 00:29:59 2024
    In article <aeiOO.1076078$jVLc.666165@fx15.ams4>,
    Mark Daniel <mark.daniel@wasd.vsm.com.au> wrote:
    [snip]
    Bit fiddly but to show the protections apply the original BG_EXAMPLE.C
    was modified to wait for a read from the telnet connection

    [snip]
    but after modifying the BG device security (pasted as quotation to
    circumvent wrapping)

    X86VMS$ set sec BG11402: /class=device /prot=(world)
    X86VMS$ show dev /full BG11402:

    Device BG11402:, device type unknown, is online, mounted, record-oriented
    device, network device, mailbox device.

    Error count 0 Operations completed 2
    Owner process "FTA10_SYSTEM" Owner UIC [SYSTEM]
    Owner process ID 00001599 Dev Prot S:RWPL,O:RWPL,G:RWPL,W
    Reference count 1 Default buffer size 256

    X86VMS$ mcr []bg2_example BG11402:
    sys$setprv() %X00000001
    sys$assign() %X00000024
    write() -1 %X0000013C
    X86VMS$ exit %X00000024
    %SYSTEM-F-NOPRIV, insufficient privilege or object protection violation >X86VMS$ exit %X00000024

    while the owner (SYSTEM) continued to have access

    [snip]

    Perfect; thanks. I think this shows definitely how the access
    mechanism applies to BG devices. I wonder why the default is to
    be W:R....

    - Dan C.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)