B4J Question B4J server & timers

LucaMs

Expert
Licensed User
Longtime User
Can I have problems if I start many timers (500 or 1000, I hope :)) in the main thread?

I'm thinking to create a class containing a timer and I could have 1000 instances of this class.
Usually the timer interval will be set to 20,000 ms.


Thank you
 

LucaMs

Expert
Licensed User
Longtime User
Thank you for your answer.



I don't know them. Reading your tutorial, I see two things:

1) StartMessageLoop inside the "worker" (I thought I should only use this instruction once and that confuses me).

2)
It must be set before the call to Server.Start.
So you need to know the number of instances you need beforehand.


I try to better specify my "need".

My (not so good) idea is to create N instances of a "game room class". These objects have an object helpful to handle some "return receipts" from clients.
Once all the players (clients) have sent their "receipts" the "receipts handler object" will raise an event to inform the game room object; the "receipts handler object" should have a timer as a kind of countdown, so that it will raise the event also if not all receipts are received.

So I need to create many objects at runtime.

Do you think that I can anyway use those "background workers" in some way?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
1) Each thread has a different message queue. So if you want the background worker thread to keep running, you need to call StartMessageLoop in the worker class.

2) You can have a single background worker that creates any number of the game room classes. It is better than letting the main thread do the work as the main thread will be free for other tasks.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
2) You can have a single background worker that creates any number of the game room classes. It is better than letting the main thread do the work as the main thread will be free for other tasks.
Yes, I understand; this way I will have two threads, better than one only. But then I should use anyway the timers in this second thread, right?
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
However I don't recommend you to do it until you find out that it is really required.
This is the question. I'm still trying to solve the sync problems and searching for an (the) "ideal" way :(.

The idea is:

1) the server sends to all the clients a "job" to do;
2) each client complete its job and send a "done" to the server;
3) when all "done" are received, the server executes its next job (not waiting, it meanwhile will handle other group of clients - game room).

But the server should set a timeout for the client's job, then it should use a timer for this and so there will be "many" active timers (with interval usually set to 20 s.).

All this is the reason for the question:
Can I have problems if I start many timers (500 or 1000, I hope :)) in the main thread?

You can have 1000 timers if the interval is not too short.


Determining how many clients can be managed seems to me an arduous task.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
This is the question. I'm still trying to solve the sync problems and searching for an (the) "ideal" way :(.

The idea is:

1) the server sends to all the clients a "job" to do;
2) each client complete its job and send a "done" to the server;
3) when all "done" are received, the server executes its next job (not waiting, it meanwhile will handle other group of clients - game room).

But the server should set a timeout for the client's job, then it should use a timer for this and so there will be "many" active timers (with interval usually set to 20 s.).

All this is the reason for the question:

Determining how many clients can be managed seems to me an arduous task.
I don't understand why you want to use so many timers. You just need a loop (or I don't understand the request):
B4X:
   Dim AllDoneReceived As Boolean = True 'should be global and set to true the first time and when all done are received
   Dim Start As Long = DateTime.Now
   Do While True
     Dim CurrentTime As Long = DateTime.Now
     Dim Elapsed As Long = CurrentTime - Start
     If Elapsed > 20000 Or AllDoneReceived Then
       'SEND TO ALL CLIENTS
       '...
       Start = CurrentTime
     End If
   Loop

EDIT: this must be run on a background thread.
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Thank you, @Informatix, that could be a better solution.

this must be run on a background thread.

If I'm not mistaken, there is a thread library that also works with b4j.

In my case I should create a thread for each game room and dynamically, because the rooms are created and destroyed. I never used that library so I do not know if it's possible to create and destroy threads and "bind" them to the game rooms.

Will all this work be lighter for the server?


(in your code you should not declare long variables inside the loop ;))
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Thank you, @Informatix, that could be a better solution.



If I'm not mistaken, there is a thread library that also works with b4j.

In my case I should create a thread for each game room and dynamically, because the rooms are created and destroyed. I never used that library so I do not know if it's possible to create and destroy threads and "bind" them to the game rooms.

Will all this work be lighter for the server?


(in your code you should not declare long variables inside the loop ;))
Yes, you should create a thread for each game room, but you can do it with AddBackgroundWorker instead of using the Thread library.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
A timer will be more efficient than a busy loop unless the wait period is very very short. It is true that you can use a single timer with a short interval.
It's not the DoWhile that is very important here, it's the loop contents. I should have put all of this in a Tick event of a single timer, I agree, but the interval of this timer should be set to something a lot smaller than 20 sec if you want to handle cases like this one, which shows the interest of this approach:
B4X:
   Dim CurrentTime As Long = DateTime.Now
   For i = 0 to MAX_CLIENTS - 1
      Clients(i).Elapsed = CurrentTime - Clients(i).Start
      If Clients(i).Elapsed > Clients(i).TimeOut Then
         ...
         Clients(i).Start = CurrentTime
      End If
   Next
This kind of code is very common in a game for animations and timeouts. It avoids the management of hundreds of timers, which would turn quickly into a nightmare and does not work very well in practice.
 
Upvote 0
Top