Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 42 |
Nodes: | 6 (0 / 6) |
Uptime: | 02:04:20 |
Calls: | 220 |
Calls today: | 1 |
Files: | 824 |
Messages: | 121,544 |
Posted today: | 6 |
I am not impressed by Apache + mod_php performance on VMS.
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.
With no further details, I'd wonder if you're not caching
connections to the database between queries.
Does not matter.
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
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 ?
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?
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.
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.
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?
But the system did not like further increases.
Apache on VMS is prefork MPM. Yuck.
Using worker MPM on VMS would make more sense IMHO.
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.
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.
Using worker MPM on VMS would make more sense IMHO.
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.
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.
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.
On VMS you can use select if using the socket API and IO$_SETMODE|IO$M_READATTN if using $QIO(W) API.
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.
Sending "Connection: close" with every request is the client
way to disable keep alive. And the unusual scenario.
Disabling keep alive client side not surprisingly has
the same effect as disabling keep alive server side.
But while disabling keep alive server side makes sense
then it doesn't make sense to disable it client side.
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.
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
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?
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
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.
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.
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.
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.
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 claiming this happens in the real world. Things aren't that clean.
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.
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".
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.
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.
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.
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.
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.
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.
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.
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.
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??
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?
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.
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 ?
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.
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 ?
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.
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?
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?
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.
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.
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 ?
In either case, are you _cleanly_ and _fully_ closing the existing
connection _before_ you exit or create a new connection in the existing process ?
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.
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 ?
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.
But I am pretty sure that it will not work on VMS.
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.
Or taking code designed for a different OS and expecting
it to work on another OS.
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.
Or taking code designed for a different OS and expecting it to work on another OS.
How many threads can _directly_ update the GUI widgets/controls.
I am not aware of any GUI frameworks where it is more than one.
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 ...
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.
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?
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?
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.
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.
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.
But it takes a long time. Way longer than the server side keep alive
timeout.
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.
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.
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.
They typical don't close the windows immediately.
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.
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.
And I’m not clear what the point of them is, for network I/O.
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.
Terminal: yes.
Mailboxes: yes.
Tapes: yes.
Disk file: not so much.
But the C code cannot use it as a file descriptor.
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.
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”,
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.
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.
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.
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.
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?).
Yes - C IO and RMS IO are not easy to align, but we have RMS whether we
like it or no.
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.
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
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.
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.
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.
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.
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...
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.
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!
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).
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 ...
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
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.
A very quick search make me think that the mailbox is only used for
control not for data.
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.
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.
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.
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.
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. ;-)
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
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
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?
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.
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.
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?
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
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.
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.
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.
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.
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.
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
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?
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.
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?
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.
Or a custom one using ASTs instead of pthreads.
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.
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.
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.
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.
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.
SO_SHARE is different again; it appears that the shared socket
must be created before the subprocesses that use it are created.
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)
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.
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.
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.
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.
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.
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.
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 would have thought you would have done something with Java, then used tomcat
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
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.
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.
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.
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.
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.
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?
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.
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?
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.
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?
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.
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.
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.
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.
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.
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.
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?
... PHP scripts has significant latency
when interacting with external database so parallelization is a must.
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.
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.
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
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.
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 ...
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.
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 ...
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”.
Note that besides the Unix sockets then some databases also supports
shared memory.
That includes both MS SQLserver and Oracle Rdb.
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.
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.
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).
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! :-)
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.
Particularly since your network connections introduce latency and
bandwidth limitations of their own.
SQLServer is used at a few high volume places like MS own Office 365 web
and StackExchange.
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??).
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.
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.
On 03/10/2024 20:09, Dave Froble wrote:
On 10/2/2024 8:14 PM, Arne Vajhøj wrote:I don't remember George, but we have certainly woken up Dave! ;)
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.
and I am sure the troll is happy...
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:I don't remember George, but we have certainly woken up Dave! ;)
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.
and I am sure the troll is happy...
I'm not sure whether I've been insulted?
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?
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!
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?
- 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?
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?
- 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?
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 ...
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.
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]
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.
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?
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.
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?
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.
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.
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.
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.
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.
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.
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
[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]