TCPSocket Wait Advice?

I need some advice. I have a sub class of TCPSocket. In the DataAvailable event I’m handling the message input from the client app. The data is processed through a method which parses it and returns a response that the socket then writes back to the client. My issue is I have had to add a process in the processing method that could take some time, up to 10 seconds. How do I ensure that the socket waits for the message to be fully processed before it tries to send a response back without holding up my application? Thanks for any advice.

My code in the DataAvailable event of the TCPSocket:

[code]
if isDataIn then //Checks to make sure all data is received from the client before processing

cIn = strBuffer //Data In
strMessage  = ProcessInput(cIn) //Method that parses/processes
me.Write strMessage + EndOfLine //Need this line to wait for the ProcessInput method to complete before sending the message

end[/code]

Start a thread to process the data instead of calling the method directly?

It might be worthwhile to post your 10-second-taking code too to see if there is room for optimization.

[quote=273616:@Ryan Haynes]I need some advice. I have a sub class of TCPSocket. In the DataAvailable event I’m handling the message input from the client app. The data is processed through a method which parses it and returns a response that the socket then writes back to the client. My issue is I have had to add a process in the processing method that could take some time, up to 10 seconds. How do I ensure that the socket waits for the message to be fully processed before it tries to send a response back without holding up my application? Thanks for any advice.

My code in the DataAvailable event of the TCPSocket:

[code]
if isDataIn then //Checks to make sure all data is received from the client before processing

cIn = strBuffer //Data In
strMessage  = ProcessInput(cIn) //Method that parses/processes
me.Write strMessage + EndOfLine //Need this line to wait for the ProcessInput method to complete before sending the message

end[/code][/quote]

I would not do that in DataAvailable. By definition anything that takes time is not recommended in sockets events.

If ProcessInput is a normal, synchronous methods, anyway, the following line cannot execute until it is finished.

Otherwise,

  • Place the ProcessInput method in a thread
  • At the end of your code, replace the two last lines by
myThread.Run
  • In the thread, at the end of the code, place the method code, and at the end, trigger a timer with the last line that writes the message. The timer can be set to execute after the delay you wish.

@Kem Tekinay That’s exactly what’s causing the issue. I’ve moved the main processing code into a thread because I need to send a request to a cloud server using plink. For reliability for the plink connection and the response from the php script I am using the thread to allow 5 seconds for the connection and 5 seconds for the response back before proceeding to put the response back for the socket.

@Michel Bujardet That’s exactly what I am trying at the moment. Using a timer like you suggested. I was hoping maybe there was a way to use one of the socket events instead.

Thanks to you both.

Never fear timers. They are the normal way of creating events in an event oriented programming language. And they consume extremely little processing power, unlike all the wait loops used in the past.

I’m a bit confused. I suggested the main processing code in a Thread, but you said you moved it into a Timer. The Timer.Action will always run on the main thread so it will block other actions like the GUI. A Thread won’t.

That was a mistype by me Kem sorry, I’ve since edited it. :slight_smile:

I should also point out this a service/console app. I should have put that in my main question.

[quote=273621:@Michel Bujardet]I would not do that in DataAvailable. By definition anything that takes time is not recommended in sockets events.

If ProcessInput is a normal, synchronous methods, anyway, the following line cannot execute until it is finished.

Otherwise,

  • Place the ProcessInput method in a thread
  • At the end of your code, replace the two last lines by
myThread.Run
  • In the thread, at the end of the code, place the method code, and at the end, trigger a timer with the last line that writes the message. The timer can be set to execute after the delay you wish.[/quote]

One last question @Michel Bujardet are you saying that until the method in DataAvailable receives it’s return data then the next line will not execute anyway? Even if it takes 10 seconds?

strMessage = ProcessInput(cIn) //Until strMessage gets it's data from ProcessInput(cIn) me.Write strMessage + EndOfLine //This line will not execute??????????

Yes, that’s exactly how it works. Functions are not called asynchronously in Xojo.

But seriously, post your ProcessInput code.

@Kem Tekinay It’s far too massive to post. It’s basically handling my entire messaging routine for my server with many different request types and database operations. Thanks though for all the help from you both. I believe I have a couple different solutions I can work on. You guys helped me a lot! :slight_smile:

What about putting the DataArival-data in a SQLite-in-memory database by a simple INSERT INTO query and make a running thread responsible for the processing of all the records. A timer-event can look for records to be send and throw them out via the socket. This is not time critical.

Data available should append the data to a buffer and that buffer is process by a thread / timer so that data available can be VERY quick. The thread / timer code then determines if a “full message” has been received and calls whatever code handles full messages.

Its how YOU should write your code for dataavailable
Especially if you need anything fairly hi speed

DataAvailable literally means “some bytes arrived”
And if you take a long time figuring out if those bytes you received before plus these bytes make a full “message” AND if they do then also take a long time handling that message you will drop data or end up with other weird issues.

Hence the advice to have dataavailable just grab the data & have “something else” process it so you can separate the incoming data handling from the processing

[quote=273637:@Norman Palardy]Its how YOU should write your code for dataavailable
Especially if you need anything fairly hi speed

DataAvailable literally means “some bytes arrived”
And if you take a long time figuring out if those bytes you received before plus these bytes make a full “message” AND if they do then also take a long time handling that message you will drop data or end up with other weird issues.

Hence the advice to have dataavailable just grab the data & have “something else” process it so you can separate the incoming data handling from the processing[/quote]
Sorry I deleted that comment I figured out what you meant pretty quickly. Thanks for your advice! :slight_smile:

http://blog.xojo.com/2015/03/17/but_it_said_dataavailable_where_is_it/

@Norman Palardy @Michel Bujardet @Kem Tekinay I’ve tried to implement the thread / timer solution using addhandlers and I’m getting a windows crash. Could you guys please take a look at this thread I created and give me some advice? Thanks…

https://forum.xojo.com/33490-using-addhandler-in-service-app-system-crashing/0