Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2000:
[Freeciv-Dev] Re: server i/o patch
Home

[Freeciv-Dev] Re: server i/o patch

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: Vasco Alexandre Da Silva Costa <vasc@xxxxxxxxxxxxxx>
Cc: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: server i/o patch
From: Lauri Tarkkala <ltarkkal@xxxxxxxxxxxxxxx>
Date: Wed, 9 Aug 2000 10:19:55 +0300

On Wed, Aug 09, 2000 at 02:34:32AM +0100, Vasco Alexandre Da Silva Costa wrote:
> On Wed, 9 Aug 2000, Lauri Tarkkala wrote:
> Remember the server has more things to do than just receive and send
> packets.  It runs the AI & goto algorithms, and that takes quite some
> time.  Not all "lag" is caused by communications.

Obviously, but when certain players disconnected. The lag went away,
(I think)..

> > After this, I decided to take a look at the freeciv networking code.
> > IMHO there a couple of minor issues with the code in question,
> > briefly:
> > 
> > - It basically uses blocking I/O for writing to sockets on the
> >   server side. Even if the socket is in nonblocking mode, the
> >   common/packets.c:write_socket_data() function loops untill it
> >   has written all data. 
> 
> Actually it waits at most 2secs for being able to write and then gives up.
> If it was in blocking I/O mode you would be lagging quite a bit more than
> 2secs...(minutes actually)  It was made this way so that lagging players
> wouldn't suffer too much (i.e. everyone moves 4 units while you move one).
> This was supposed to "fix" that while not letting other players lag too
> much.  It originally was like you are saying but people complained.

This is incorrect. 

If you carefuly consider what happens, if a client has a low throughput
connection..

write_socket_data() runs in a for(start=0;start<buf->ndata;) loop,
and yes, it waits at most 2 seconds before _EACH_ write(). As
the socket is in a non-blocking mode, then the write() may
very well only send part of the data to be written, and return,
after which the loop waits another 2 seconds. 

So basically a scenario like this is possible:

0. socket_write_data().. buffer contains N kilobytes of data..
1. select()
2. select() waits 1 < x < 2 s and returns, FD_ISSET(pc->sock,&writefs)
3. write() manages to write a fraction of the buffer
4. select() waits 1 < x < 2 s and returns, FD_ISSET(pc->sock,&writefs)
5. write() returns EWOULDBLOCK
6. select() waits 1 < x < 2 s and returns, FD_ISSET(pc->sock,&writefs)
7. goto 1 untill buffer finished

.. and so on, ad nauseaum. 

For a laggy TCP connection, this could
conceivably take a very long time (after all, transfer rates
of 1kbps are still real over modems and very laggy networks) ...

Anyway, I feel using an asynchronous flushing of the write
queues is more cleaner, and less disruptive to the gameplay.

As for the idea regarding IRC like "ping-packets". These are
nice, but again the TCP flow control can really screw you
there too, and this mechanism cannot be counted to give
the server a feeling of how lagged  a player is.  I do not
exactly know how the IRC protocol works, but if the pings
are client-oriented, i fear they may not be of much use
in poor network conditions.

A better method (than simply having the client send "pings"
at certain intervals) would be for the server to send an ACK request, 
and then the client to send an ACK reply. This would allow
a neat synchronization feature at "ends-of-turn" between
all clients.

> >   blocking for more than "tcptimeout" seconds without 
> >   any data being written to it, and if this is so, it
> >   then closes that client connection.
> 
> Kind of an aggressive stance i was trying to avoid, but anyway...

The idea in the "tcptimeout" was to allow for the "aggressiveness"
to be set, or completely disabled. This allows a server to be
configured, so an AI takes over quickly, instead of waiting
for a TCP connection to timeout in some cases.

Another question is, if a player wishes for an AI to take over ;-)

Lauri

-- 
"The credit belongs to the man in the arena whose face is marred by dust and
sweat and blood, who strives valiantly, who errs, and who comes up short again
and again, who knows the great enthusiasms, the great devotions, and spends
himself in a worthy cause. The man who at best knows the triumph of high
achievement and who at worst, if he fails, fails while daring greatly, so that
his place will never be with those cold timid souls who never knew victory or
defeat." - Theodore Roosevelt



[Prev in Thread] Current Thread [Next in Thread]