I’m trying to pull chunks asynchronously from the my server. The chunks are being sent from the server asynchronously, but the requests for the chunk from the client are not, or at least behave in that manner.
I can prove the requests are jamming the GL thread because my loading screen at first sends all the requests for them (due to the pager requesting them all at once when I set the location to it for the first time). At that point the game freezes, and only becomes responsive once all requests have been sent and it starts receiving them. On a local version of the game (non-networked) using the same algorithms everything is nice and smooth, and I have removed the line where the chunks are added to the scene amongst other things to try to find any other cause. The only differences are that in the networked game is they are requested via a network state (local, same pc).
At first I presumed that sending 3-400 requests was causing a bit of a backlog, but during the game as I move around, it only requests 3 chunks at a time (the three chunks in front). The data is small, just 3 integers denoting the bitshifted grid position.
Any ideas on what I’m missing?
Hard to say from here but things to look at are deadlocks in your other messaging code.
For example, if all of these are going over the same channel as other messages then some other synchronous call could be blocking them from being received while it waits for the client to do something.
You could try moving these requests and responses to their own channel to at least isolate it from other communication. If it suddenly starts working then you know it was deadlocked with some other messaging.
Edit: also, why are the requests sent synchronously instead of async?
Yea, it sounds like something is deadlocking. My game runs network code even in single player and I haven’t run into any cases like that. I’ve made some changes to the detailed profiler in jME but i’ve found it very useful for figuring out performance issues. Code that I thought was the cause of slowdowns wasn’t. You could always do some internal time testing on the methods you are using by just measuring start and end time in a method and outputting the result. I used that technique to figure out my chunk loading code was periodically spiking much higher than I realized and causing a rendering freak out (like 12ms+).
They are, they share the same WorldSession interface, I just worded it wierdly, sorry.
package com.jayfella.animalia.shared;
import com.jme3.network.service.rmi.Asynchronous;
public interface WorldSession {
String getWorldName();
int getPlayerCount();
int getMaxPlayers();
@Asynchronous
void requestChunk(ChunkRequest request);
@Asynchronous
void requestChunkHashCode(ChunkRequest request);
}
Thanks for the hints. I’ll report back when I find it.
Ok, well, I’m 99.99% sure that async requests cannot block. I left 0.01% in there just in case there is some framework level thing I haven’t considered… but I do know that SpiderMonkey generally has the exact opposite problem in that you can spam and endless number of messages to it and it will happily gobble up all RAM trying to queue them for sending.
So I feel like these calls may not really be the issue.
Both the server and client use a threadpool and have around 32 threads each. All the work was sent at once so the CPU just got bogged down generating tons of density fields and meshes at the same time. I reduced the thread count on them both and additionally eliminated any micro-stutter by limiting requests to 128 requests or something per frame on the terrain pager. Thank you for the help 