SFS Pro - Help with offloading heavy tasks to a new thread

Need help with SmartFoxServer? You didn't find an answer in our documentation? Please, post your questions here!

Moderators: Lapo, Bax

CaptainHug
Posts: 8
Joined: 09 Sep 2016, 16:26

SFS Pro - Help with offloading heavy tasks to a new thread

Postby CaptainHug » 09 Sep 2016, 16:34

Hi.
We have some request handlers in handleRequest of a zone level extension that often take over 1 second to complete.

Currently we have to keep the Extension and System handler thread counts as 1 because our game logic is not yet thread safe.

What I am trying to do is offload some of these slow tasks, that do not affect gameplay, to another thread. I am trying to do this using the actionscript setInterval server side function, passing in a low interval value to fire this thread off immediately.

What we are seeing though, is that setInterval doesn't appear to be creating a new thread. The handleRequest function is still taking the same amount of time to complete when the function inside is triggered by a setInterval.

Does setInterval have some internal optimisation, where it does not create a thread if the interval value is below a certain level?

Please could you share with me a way to achieve this, offloading heavy tasks from the Extension Handler thread using the actionscript server side API? Is there another way to guarantee generating a new thread?

Thanks!
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: SFS Pro - Help with offloading heavy tasks to a new thread

Postby Lapo » 10 Sep 2016, 08:42

Hi,
the setInterval() function does create a new Thread behind the scenes.
If you're not seeing improvements in execution time you're probably not looking in "the right place", meaning that what you're running separately is probably not the cause of the problem.

Could you give us more details about these heavy tasks that you're running in your code?

Also what kind of hardware are you using to run SmartFoxServer? Is it a dedicated server? What CPU/RAM/OS?

Thanks
Lapo
--
gotoAndPlay()
...addicted to flash games
CaptainHug
Posts: 8
Joined: 09 Sep 2016, 16:26

Re: SFS Pro - Help with offloading heavy tasks to a new thread

Postby CaptainHug » 10 Sep 2016, 12:10

At the moment, our server is running on a DigitalOcean "droplet" (virtualised machine). The specs are as follows:

Ubuntu 14.04.2 LTS
8x Intel(R) Xeon(R) CPU E5-2630L v2 @ 2.40GHz CPUs
16 GiB RAM

All services smartfox, apache, mysql, etc are running on the same server.

We are looking at moving to a dedicated server with OVH in the near future to eliminate the current shared host as an issue.

In the short term, we are profiling the extension request handler and trying to make it run as smoothly as possible.
We are profiling the handler code in this way (paraphrasing code in these examples to keep it short):

Code: Select all


function handleRequest(cmd, params, user, fromRoom)
{
   var startTime = getTimer();

   switch(cmd) {
      case "getFriendList":
      {
         getFriendList(/*args...*/);
         break;
      }

      case ...
      ...

      default:
         break;
   }

   var endTime = getTimer();
   var timeTaken = endTime - startTime;
   if (timeTaken > 250) {
      // Only log if request took longer than a 250ms
      trace("handleRequest: " + cmd + " took " + timeTaken + " milliseconds");
   }
}



The user database contains around 500,000 users and even though we have optimised the queries and tuned mysql, this sometimes still takes nearly a second to complete. This wouldn't be as much of an issue if it didn't block the Extension Handler thread, so what we are looking at doing is offloading this kind of function to it's own thread to allow other handlers to process while this is being worked on. The getFriendList function uses the smartfox database functions to execute the query.

What I've been trying to do is something like this:

Code: Select all


function handleRequest(cmd, params, user, fromRoom)
{
   var startTime = getTimer();

   switch(cmd) {
      case "getFriendList":
      {
         setInterval("getFriendList", 1, {/*args...*/}})
         break;
      }

      case ...
      ...

      default:
         break;
   }

   var endTime = getTimer();
   var timeTaken = endTime - startTime;
   if (timeTaken > 250) {
      // Only log if request took longer than a 250ms
      trace("handleRequest: " + cmd + " took " + timeTaken + " milliseconds");
   }
}



I clear the interval in the getFriendList function and then process as we normally would.

What we are seeing at the moment is that the trace is still being hit with the same values as without the setInterval code, which is confusing me as I was assuming that the setInterval would return immediately and therefore the timeTaken would always be relatively low.

I appreciate your help in this matter. Thank you.
CaptainHug
Posts: 8
Joined: 09 Sep 2016, 16:26

Re: SFS Pro - Help with offloading heavy tasks to a new thread

Postby CaptainHug » 10 Sep 2016, 12:40

Could it be that if we had a simple select at the top of the handleRequest, eg:

Code: Select all


function handleRequest(cmd, params, user, fromRoom)
{
   // simple database select statement here - get 1 field from a 1 row table
   var rs = g_db.executeQuery("select setting from settings");
   
   // rest of code as above ...
}



Then that could be waiting for a previous database query (in a different thread) to finish executing before continuing with the rest of the handleRequest function?
CaptainHug
Posts: 8
Joined: 09 Sep 2016, 16:26

Re: SFS Pro - Help with offloading heavy tasks to a new thread

Postby CaptainHug » 12 Sep 2016, 16:27

I've added some extra logging in and it looks like you were correct - the Intervals do appear to have created a thread successfully, so it looks like our problems lie elsewhere.

Would you be able to answer if the calls to the mysql / jdbc database through the SFS DatabaseManager are blocking in relation to running queries in separate threads? ie. if I use the DatabaseManager to execute a long running query in a thread I have spawned with setInterval, will the Extension Handler thread still be able to make it's own calls to the database through the DatabaseManager, or will they be forced to wait for the completion of the long running query?
User avatar
Lapo
Site Admin
Posts: 23008
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: SFS Pro - Help with offloading heavy tasks to a new thread

Postby Lapo » 12 Sep 2016, 18:07

CaptainHug wrote:Would you be able to answer if the calls to the mysql / jdbc database through the SFS DatabaseManager are blocking in relation to running queries in separate threads?

Queries are always blocking calls.
If you run them in a separate thread they will not (of course) block your main thread although you will need some way (e.g. callback system) to handle the result when it is ready.

if I use the DatabaseManager to execute a long running query in a thread I have spawned with setInterval, will the Extension Handler thread still be able to make it's own calls to the database through the DatabaseManager, or will they be forced to wait for the completion of the long running query?

No, you can run as many DBManager queries as you want as long as the database can handle them.

Just to be clear, is the 8 core/16GB machine dedicated to your project or is it a shared hosting in the sense that other websites and apps are running too? In any case to see if there's a hardware issue you can simply monitor your CPU usage and see if it's running with enough free resources or not.

cheers
Lapo

--

gotoAndPlay()

...addicted to flash games

Return to “SmartFoxServer 1.x Discussions and Help”

Who is online

Users browsing this forum: No registered users and 37 guests