Why does SpiderMonkey use its own NIO Impl?

Hi,



why does spiderMonkey take care of the whole NIO stuff ? I saw some conceptual design problems. I dont’ want to criticize the project but I’m really interested why the author of SpiderMondey don’t use a more professional framework… (Netty3, Apache Mina, xSockets)



For instance the threading model seems very poor… One thread for one client ? If you use a thread-per-client model you can just use usual sockets… NIO creates some overhead and without a clever threading model you won’t have any performance boost but some overhead…



Using one of the proven frameworks would give you the chance to concentrate on the important stuff… I’m talking about classes which would help you to sync multiple objects without the need to know about network stuff… Well, of cource… A game programmer should be fit in network programming to optimize his games.



so… its just a thought… i mean why to invent the wheel twice ;-0 And it is the same with the other candidate… kryonet…



regards,



Chris

Well as you know, the author unfortunately doesn’t hang out here any more, so there’s little hope of any definite answer (I’ll send him a note though). I’d especially like to see @ractoc and @sbook share their thoughts though, seeing as they’ve expressed an interest in maintaining SpiderMonkey.



If you could be interested in developing SpiderMonkey further, we’re all ears, even if that means considering critical changes like this one now and again.

Well… i would suggest to use http://www.jboss.org/netty for a stable basis. The author created Apache Mina as well and IMHO it’s the best framework.



Maybe we could just replace the whole network stuff in SpiderMonkey by a Netty3 implementation. I know that’s a lot of work I’m talking about… But I’m sure that this is a much better strategy than building own NIO frameworks…



In addition: With nio you’re usually able to serve 10.000+ of client concurrently… But with SpiderMonkey you won’t come over 300 … One thread per clients means you need 10.000 threads for 10.000 clients…



Alright, a few years ago i developed a tiny serializing library similiar to the one of SpiderMonkey. Maybe i find it somewhere on my hard drives … The combination of netty3 and my old system shouldn’t be much work… I’ll have a look when I’ve got some time the next week :wink:



regards,



Chris

SM does so to be able to be ported to any platform in a self-contained way.

Which platform is not supported by Netty3 which is supported by SM ?

I dont want to argue with you.

Sorry when my englisch sounds like i want to start an argue :wink: That was not my intention!

I just don’t get your point…

My point is that SM aims to be platform independent and thus organizes the bytes itself. If you have developed a better SM just post the code here, the question why a specific library is not used is kind of silly. Also bloating the classpath with libraries for all kinds of uses is not really nice, so I still don’t know why we should use one for serializing.

Its not true that SpiderMonkey is a thread-per-client model. Do a search for “new Thread” on it and see for yourself



If another system is to replace SpiderMonkey, then it must satisfy the following requirements:


  • Supports UDP and TCP, and only use 1 port for each

  • Has an object serialization system that is independent of jME3 "Savables" and Java's "Serializable" interfaces

  • Uses NIO

  • Supports sending messages, and receiving messages (through listeners)

  • Supports sending/receiving streams

  • Lightweight. Must be less than 1 MB total for itself plus any dependent jars

  • Low latency is the highest priority

  • Has a player ID / client ID system so that connections can be identified through the ID

  • Does not crash unexpectedly, regardless of whatever circumstances occur



It just so happens that SpiderMonkey does not actually satisfy the last two requirements... So if there's another library that does satisfy them I am all ears. Currently I am using JGN for a project and I am quite happy with it. There's also Kyronet, however it has less features than JGN but should suffice as well.
1 Like

I have to correct you there Momoko_Fan, SM DOES have a client id with which to identify the client connection. Just use Server.getClientByID(int clientID); That should work like a charm. There currently is no way to link the client connection id with the actual player id though, yo have to do that yourself.



As to the whole, why don’t you use framework X, Y or Z; I’m not really sure what the thoughts about this were from Lars. But the requirements mentioned above might have something to do with that. Almost all external libraries bloat the classpath a lot. And even if they don’t they hardly ever meet the strict demands set by a game engine. Which mean we would still have to code a big chunk around them to make them work like we want to. Which kind of defeats the whole purpose of using the framework in the first place.

ractoc said:
I have to correct you there Momoko_Fan, SM DOES have a client id with which to identify the client connection. Just use Server.getClientByID(int clientID); That should work like a charm. There currently is no way to link the client connection id with the actual player id though, yo have to do that yourself.

The client ID unfortunately is not unique for a client, those are allocated as needed. For example on a message listener, you have a different client ID each time even though the connection is the same. Additionally, the client ID for a given client is different on the server and the client that has the ID which defeats the whole purpose.

I was talking about replacing the network stuff not replacing SpiderMonkey … So you can just use SpiderMonkeys serialization lib and the client id and the other stuff you like… What about making SpiderMonkey abstract so that everybody can decide which “SpiderMonky - Provider” he wants to use… Just replace the whole nio stuff and replace it… that was my idea… nothing more :wink:

BTW: netty3 is 780kb … so it should be “lightweight”, right ?^^



@Momoko_fan:



“Its not true that SpiderMonkey is a thread-per-client model. Do a search for “new Thread” on it and see for yourself”



I did and thats the reason i said it :wink:



[java]

/**

  • Start this server.

    *
  • @throws IOException When an error occurs.

    */

    public void start() throws IOException {

    if (!isBound) {

    tcp.bind(lastTCPAddress);

    udp.bind(lastUDPAddress);

    }

    new Thread(thread = new ConnectionRunnable(tcp, udp)).start(); // <

log.log(Level.INFO, "[{0}][???] Started server.", label);
}

/**
* Start this client.
*/
public void start()
{
new Thread(thread = new ConnectionRunnable(tcp, udp)).start(); // <
}

[/java]


Since netty3 is very easy to use it won't be that much work...

Soo....

780kb for serialization? are you kidding?? There is only one thread, as momoko said. What are you trying to prove by posting this code?

I am sorry but I don’t see the point in abstracting SpiderMonkey. Doing that merely creates another layer of indirection between it and the networking. The interface for the user is the same, in terms of features and usability.



By the way, the code you pointed to does not indicate thread-per-client model; a thread-per-client implies that a thread is created for each client that connects to the server, the code you shown creates a single thread on call to start() which happens only once to start the server.

Yes, i was too fast. My bad… Anyway reading, writing and accepting in the same thread … for a lot of clients … You know what: never mind. Forget it … Maybe i’m trying to improve something which doesn’t have to… Obviously SpiderMonkey is good enough for the usual purposes.

Kr0e said:
Yes, i was too fast. My bad... Anyway reading, writing and accepting in the same thread ... for a lot of clients .. You know what: never mind. Forget it ... Maybe i'm trying to improve something which doesn't have to... Obviously SpiderMonkey is good enough for the usual purposes.

You're actually right about the single thread issue. It can be a problem when you have a 16 core server for example, and only a few cores are used...

Honestly, SpiderMonkey has its own share of issues, but the other networking libraries out there aren't perfect either.

It would be great if a good Java networking person just came along, with lots of experience, and helped us improve SpiderMonkey or create a new engine :) Where are you, person?

If only I had the time…



Oh wait, I already said I would take a good hard look at SM… Vount me in then, although I can’t really give a definitive timeline. First up is the alpha release for OGF. Then to get the chat control ready for Nifty. Then I’ll look into this one. So some time ofter the summer holidays. (Hopefully sooner, but no use getting everyones hopes up…)

Just being curious here…



What is a better design for a TCP networking piece than one thread per client?



I wrote my piece following the logic from oracle: Writing the Server Side of a Socket (The Java™ Tutorials > Custom Networking > All About Sockets)


Supporting Multiple Clients
To keep the KnockKnockServer example simple, we designed it to listen for and handle a single connection request. However, multiple client requests can come into the same port and, consequently, into the same ServerSocket. Client connection requests are queued at the port, so the server must accept the connections sequentially. However, the server can service them simultaneously through the use of threads - one thread per each client connection.

The basic flow of logic in such a server is this:

while (true) {
accept a connection ;
create a thread to deal with the client ;
end while

The thread reads from and writes to the client connection as necessary.


If someone can explain the concept of a better solution I would like to implement it into my code.

Thanks!
scrubalub said:
What is a better design for a TCP networking piece than one thread per client?

Just using one thread for reading and writing multiple connections. Think about the fact that a thread uses memory and system overhead just for management. All big server solutions went from multiple threads to a few that handle lots for connections each. The new SM also does it this way.
normen said:
Just using one thread for reading and writing multiple connections. Think about the fact that a thread uses memory and system overhead just for management. All big server solutions went from multiple threads to a few that handle lots for connections each. The new SM also does it this way.


I can imagine setting this up, the only problem I have is since I'm using the basic java.io, the api calls tend to block when you are reading from an inputstream. For example ObjectInputStream readObject() blocks until it can read from the stream. Having multiple connections on 1 thread (at least in my case) would potentially cause starvation.

Is what I just described the reason for using NIO?