WebRequest question

I’m trying to understand what exactly WebRequest does when not used with WebApplication.HandleSpecialURL. Suppose a CGI Web app method does this:

Dim r As New WebRequest MsgBox Str(r.Status)

Since I have not targeted an external URL in the above code, is r.Status in the above code actually giving me the HTTP status of the Web app’s URL?

The reason I ask this is to find a way to get an App.Open Timer to periodically check the status of the app, and kill that app if it sees it returning Error 500. A Timer method something like this:

Dim r As New WebRequest If r.Status = 500 Then Self.Quit

But I have a feeling that using WebRequest this way is naive, and not really understanding what it does. I asked about this over here , but I think it might need a separate thread to better understand WebRequest.

I can’t imagine that it would. A WebRequest wouldn’t mean anything apart from a real request. I suppose a web app could try calling itself via HTTPSocket, thereby generating a WebRequest and a test condition on either side (in the request handler or in the socket). But that could only test for certain errors. If the app freezes the test timer won’t fire.

Write a separate console application which:

  • Calls a URL on your web app.
  • Determines if the web app is OK.
  • Issues a command to the OS to restart it if it’s not.

[quote=439342:@Daniel Taylor]I can’t imagine that it would. A WebRequest wouldn’t mean anything apart from a real request. I suppose a web app could try calling itself via HTTPSocket, thereby generating a WebRequest and a test condition on either side (in the request handler or in the socket). But that could only test for certain errors. If the app freezes the test timer won’t fire.

Write a separate console application which:

  • Calls a URL on your web app.
  • Determines if the web app is OK.
  • Issues a command to the OS to restart it if it’s not.[/quote]
    Thanks, Daniel.

Well, when I test this on a server, this Button Action returns a 200:

Dim r As New WebRequest MsgBox Str(r.Status)

That’s one reason I wondered if it was actually testing the status of the actual app where I pressed that button.

Also, I know an App.Open Timer can run while the CGI app is responding with an Error 500, because I currently rely on such a timer to allow me to kill the app by just renaming the CGI file. That timer watches for the existence of the CGI file and kills the app when it’s not found.

There’s no reason to make a web request object. The only mechanism that uses them are HandleURL and HandleSpecialURL and they provide the one that you should use… and the default value for Status is 200 (OK).

We probably should have made it so users couldn’t create them from scratch.

[quote=439345:@Greg O’Lone]There’s no reason to make a web request object. The only mechanism that uses them are HandleURL and HandleSpecialURL and they provide the one that you should use… and the default value for Status is 200 (OK).

We probably should have made it so users couldn’t create them from scratch.[/quote]
Thanks, Greg. I’m reading and rereading the HandleURL Event doc and am wondering if I put this in that App Event Hander, I get what I want:

If Request.Status = 500 Then Self.Quit

If your app is frozen, you won’t be getting HandleURL events. I think you have this whole thing backwards. Your web app won’t be able to tell if it is hung. Use an external app to poll your web app and check for status 500 being returned.

[quote=439347:@Ralph Alvy]Thanks, Greg. I’m reading and rereading the HandleURL Event doc and am wondering if I put this in that App Event Hander, I get what I want:

If Request.Status = 500 Then Self.Quit

No. In this case Status is what is being sent back to the browser with whatever data you print to the request in response to a request from a browser.

Ralph - a WebRequest represents an incoming request from a HTTP client. If you create a WebRequest in your server application it simply has default values. Those values have no meaning. Status is not the status of your application, it’s just the default status which would normally be returned to a client.

There’s no reliable way for your application to self test in this situation.

On linux if you have terminal/ssh access try system.debuglog and view it trought the system logging.

Probably possible with “journalctl -b” as it shows all output since the boot.

Or prefix the system.debuglog(“myapp: “+ debugstring)
And use “journalctl -b | grep “myapp:”

This way you can at least see something if your app is running. Output from unhandledexception etc.

I get it now. Thanks Daniel. I had a feeling I really didn’t understand WebRequest. Obviously I didn’t.

The reason I was looking for a way to self-test during a CGI Error 500 is that my experience is that in such a situation the app is running, but not creating sessions anymore. My evidence that it’s running is that my App.Open Timer that watches for the existence of the CGI file works fine. If I rename that file, the app is killed and the next attempt to hit it successfully creates a session. No more Error 500.

That timer also kills the app if it sees no sessions (I have found that AutoQuit sometimes fails to work during an Error 500). That also works fine during an Error 500 because the app is actually running.

But I’d like to start running this app 24/7 without it quitting, because I have found these occasional Error 500 situations only arise when a user hits a non-running app. So I was considering keeping it running (AutoQuit=False) and come up with a way for it to quit if it ever did get an Error 500 when a user hit the running app (which I have yet to see).

So given that it’s running during an Error 500, I was looking for something an App.Open Timer could watch out for, and kill the app if it found it. I have thought about running an external CGI app to poll the app in question, but that sounded like an odd solution, since that external CGI app could end up in an Error 500 situation itself. And I don’t think I can run an external console app to do the polling on ServerWarp.

I imagine all this stuff goes away with standalone apps.

It depends on what’s causing the 500 errors and where they’re coming from. For instance, if your app got caught in a tight loop for some reason and couldn’t respond, Apache (or whatever web server you are running) is the one to return the server error 500. That would still be true if the app didn’t respond to the request from your load balancer or reverse proxy.

There are other reasons I would say to run a console or stand alone web app for this purpose, but it should not matter if the tester ends up in a 500 state…if this state does not freeze the app…since it’s not serving pages.

As to self testing, I’m going to preface this with: I think self testing is a bad idea. Self testing won’t help if your app freezes for some reason.

If the 500 situation does not stop the Timer from firing then you may be able to self test and Quit on 500. I haven’t extensively tested this, but on macOS a web app can create a HTTPSocket and call itself. So your Timer could create a socket, call itself, and check the resulting HTTPStatusCode.

Why not?

These 500 errors, when they happen, are always associated with the CGI process (on ServerWarp) not getting past CGI Line 118. And I never get an App or Session unhandled exception written to file when they happen; or any other time, for that matter. I’ve tested the code for writing such exceptions to file with a forced exception on the first line of App.Open and Session.Open, and the unhandled exception code works.

For now, making sure the app is killed when SessionCount=0 has saved me from intervening in this. It doesn’t stop the errors from occurring periodically, but it keeps them from enduring.

[quote=439449:@Daniel Taylor]And I don’t think I can run an external console app to do the polling on ServerWarp.

Why not?[/quote]
Not sure I have terminal access on that account. I have SFTP access. I think that’s all.

That’s a game changer for me. Didn’t think of that. I’ll just create an external test app to handle this now. Thanks.