Possible CPU/MEM issue with Linux/Win and POSTs, HandleURL

Howdy there.

I followed these steps here: https://www.youtube.com/watch?v=vCGNB94y0DU

Off on my own, I recreated these in Mac OS X and they work fine with no issues. I test the server part out on a Linux system and every time its POSTs the CPU usage goes up and stays up, regardless of any further use. To get it to be noticeable, have to POST about 30-40 times. I’ve gotten CPU usage to 60% and left it alone to see if it’ll ever return to normal and it doesn’t over 10 minutes.

Has anyone seen this issue?

I don’t see anything between “Howdy” and the words “I followed these steps…”.

There was nothing there but a link. DB Communication with Xojo, Part 1 . I’m not sure what happened.

I’ll explained the video a bit.

Create a Web App with the HandleURL event for a RESTful API (example shows for quotes).
Create Desktop app to POST.
Then I use Desktop app to POST 30-40 times and watch the Web App CPU usage go up and stay up, but on Linux. Mac seems to work fine.

I’ll see if I can get a video of the behavior this weekend at some point.

What version of Xojo are you using?

Xojo 2015r3.1

Ok, I did not get a video, but I am able to reproduce on Windows Server 2012. Unfortunately I can’t figure out the remote debugging stuff for Web Apps and how to connect. If anyone can compile the POSTLeak for me I can get a video of this issue.

I uploaded the two files to basically demonstrate what I am using to see the issue. It grows even faster when I have other work being done. With Windows I see the memory grow and eventually will see the CPU rise and steady at a percentage despite not doing noticeable work.

Files: POSTLeak and DesktopQuoteClient, which is similar to the video tutorial mentioned above, except it posts a chess PGN for a larger size.

To reproduce:

  1. Start POSTLeak on host.
  2. Open Task Manager or top and watch POSTLeak.
  3. Edit DesktopQuoteClient Button 1 to match URL (http://:8080/pgn)
  4. Run DesktopQuoteClient.
  5. In a separate command terminal on Mac or Linux run: while true; do curl -X POST http://<ip>:8080/pgn; echo "POST"; done
  6. In DesktopQuoteClient click Button 1 (or 2 if you changed that too).
  7. Continually hit Button 1 or 2, fast or slow, doesn’t matter.
  8. In Windows watch memory go up first, and right around 16mb CPU begins kicking in.
  9. In Linux CPU will go up, memory not so much.
  10. Keep clicking Button 1 or 2.
  11. After getting the CPU to a respectable 10-20%, stop all CURL and Button pressing.
  12. The CPU will lower slightly maybe by 5%, but never reduce to the idle its suppose to be.

I hope this helps someone reproduce this. Or shows me what I’m doing wrong even.

Whelp, it has been a while so I’m going to bump this as still a problem. What it looks like is that its not closing extra threads from multiple quick connects from a single entity. Lets say a process from a POST takes 5 seconds to complete, and the person double connects with the same POST information. The second instance stays open forever while the first closes. The person does another double, it’ll create another single instance forever which will make two forever instances.

The problem comes in when the person does like 5-10 connects, and you get 4-9 forever instances.

Using 2015r4 and a Web app with a POST and a semi CPU intensive set of DB calls with ~200 connections over a minute the CPU and memory never recover.

Single connections run fine with no CPU or memory hits. Everything returns to normal when its done. One connection every 5-10 seconds is fine, no ill effects.

I have a web app running right now that’s forever sitting at 88% CPU usage and some change in memory for around 30 minutes. All processes are completed, its just sitting there eating CPU. I can close it sure and start over, but why are the extra threads not closing?

Truthfully I’m guessing its a sessions issue and somehow since all I’m doing is a HandleURL and a set of DB calls something is getting screwy with the sessions. Harder to duplicate when there’s no work, but impossible to miss if each api call is doing work.

Session.Quit at the beginning of code doesn’t seem to, but something must somewhere. Just need to find it.

[quote=245278:@Jeffry Walsh]Truthfully I’m guessing its a sessions issue and somehow since all I’m doing is a HandleURL and a set of DB calls something is getting screwy with the sessions. Harder to duplicate when there’s no work, but impossible to miss if each api call is doing work.

Session.Quit at the beginning of code doesn’t seem to, but something must somewhere. Just need to find it.[/quote]

If all you need is handleURL why don’t you consider using a Console program and ServerSocket instead ? Maybe the whole apparatus of a web app is overkill here.

I have considered lots of options since seeing this issue, implemented what I’m working on in other languages and even used AWS’s API+lambda+Aurora.

But I would like to stick with Xojo Web. I was going to snap up the web license back at Black Friday but decided to stress test first. If I did get the license, and then was told to switch to Xojo console and custom make my web stuff, or even us it as a backend for another API implementation from some other language I would be at a loss.

With all that said, the tutorial was by Paul Lefebvre and referenced as making RESTful APIs easy using Xojo Web. I tried it and it is easy and I would like to stick with this. What I’m seeing is either a bug or there something the tutorial miss in regards of DoS protections/Session closing via POST that I don’t have the experience with Xojo to spot. I was hoping someone else would try to duplicate the issue as to not make me sound insane and just imagining things.

Any ideas on how to close previous connections from the same IP? No Session.Open anywhere. Just two quick connects to the api+post part.

This has been demonstrated before if you search the forums. If you fire successive requests to a Xojo Web app it will ultimately lock up as it cannot handle the context switching fast enough (or so it seems). See: https://forum.xojo.com/25688-web-app-hangs-randomly-100-cpu/9#p213169

Xojo is not multi-core aware so there is def limitations to how many requests it can handle at any given moment per process. What those limitations are depend entirely on circumstance.

In order to be successful with Xojo for high traffic scenarios you need to deploy defensively. Use load balancers, multiple processes, and process recovery when they do inevitably crash.

I have searched the forum and I have come across that thread. It does not explain the same issue, or if it is the same issue its a framework bug and not my coding since I don’t use TCPSocket or Flush. Their example does not use the web framework and is instead a console app. I can reproduce it with nothing but:

[code]Project: POSTLeak
App

Class App

Inherits WebApplication

Events

Function HandleURL(Request As WebRequest) As Boolean Select Case Request.Path
Case “search” // http://url.com/search
If Request.QueryString <> “” Then 'Request.Print(SearchQuery(Request.QueryString))
Request.Print(ReturnJSONMsg(“error”, “Broken”))
Else
Request.Print(ReturnJSONMsg(“error”, “Query string Empty”))
End If
Return True
Case “pgn” // http://url.com/pgn requires a POST
Dim Result as String = ProcessRequest(Request)
Request.Print(Result)
Return True
End Select
Return False
End Function

Sub Open(args() as String) End Sub

Methods

Private Function ProcessRequest(request as WebRequest) As String
Dim postData as String = DefineEncoding(request.Entity, Encodings.UTF8)
Return ReturnJSONMsg(“error”, “No POST data”)
End Function

Private Function ReturnJSONMsg(JSONKey as String, JSONMessage as String) As String
dim JSONError as new JSONItem
//This object is manipulated like a dictionary
JSONError.Value(JSONKey) = JSONMessage
Return JSONError.ToString
End Function

Properties
dbDatabaseName As String
dbHost As String
dbPassword As String
dbPort As Integer
dbUserName As String
End Class
[/code]

And I know its cooperative threading and I can handle that. Also, I know how to deploy defensively and load balance and have done my homework with both pound and haproxy. Thanks though.

I’ll try moving everything into “session” instead of “app” I guess.

Sorry I didn’t mean to imply it was your code. From my experience and others on the forum eventually too many requests locks up a web app. The fix is unknown at this point.

For reference, I started one Web App instance, and after ~20 HTTP POSTs, here is what it looks like in ps tree format:

3569 root 20 0 2208M 82056 15616 S 27.8 2.0 1:57.57 ?? ?? ???? ./ChessAPI 3744 root 20 0 2208M 82056 15616 S 0.0 2.0 0:02.06 ?? ?? ???? ./ChessAPI 3743 root 20 0 2208M 82056 15616 S 0.7 2.0 0:02.02 ?? ?? ???? ./ChessAPI 3737 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.99 ?? ?? ???? ./ChessAPI 3736 root 20 0 2208M 82056 15616 S 0.0 2.0 0:02.20 ?? ?? ???? ./ChessAPI 3730 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.93 ?? ?? ???? ./ChessAPI 3729 root 20 0 2208M 82056 15616 S 0.0 2.0 0:01.90 ?? ?? ???? ./ChessAPI 3723 root 20 0 2208M 82056 15616 S 1.3 2.0 0:01.87 ?? ?? ???? ./ChessAPI 3722 root 20 0 2208M 82056 15616 S 0.0 2.0 0:01.89 ?? ?? ???? ./ChessAPI 3721 root 20 0 2208M 82056 15616 S 0.0 2.0 0:01.84 ?? ?? ???? ./ChessAPI 3715 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.87 ?? ?? ???? ./ChessAPI 3714 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.85 ?? ?? ???? ./ChessAPI 3708 root 20 0 2208M 82056 15616 S 0.0 2.0 0:01.85 ?? ?? ???? ./ChessAPI 3707 root 20 0 2208M 82056 15616 S 0.0 2.0 0:01.83 ?? ?? ???? ./ChessAPI 3706 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.90 ?? ?? ???? ./ChessAPI 3705 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.85 ?? ?? ???? ./ChessAPI 3699 root 20 0 2208M 82056 15616 S 1.3 2.0 0:01.91 ?? ?? ???? ./ChessAPI 3698 root 20 0 2208M 82056 15616 S 1.3 2.0 0:01.88 ?? ?? ???? ./ChessAPI 3697 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.91 ?? ?? ???? ./ChessAPI 3691 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.87 ?? ?? ???? ./ChessAPI 3690 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.89 ?? ?? ???? ./ChessAPI 3688 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.83 ?? ?? ???? ./ChessAPI 3682 root 20 0 2208M 82056 15616 S 0.7 2.0 0:01.87 ?? ?? ???? ./ChessAPI

Of course the tree is a bit longer. Killing any one of them kills all of them.