09 Sep, 2010, Scandum wrote in the 21st comment:
Votes: 0
Rudha said:
TT++ does not renegotiate TERMTYPE if it thinks it has already negotiated this; this is my problem for many options and just about any client other than MushClient. I would simply save socket states and reload them on copyover, but that seems sketchy; A: NakedMud doesn't reliably synch the socket UIDs up to connections on a copyover which means the data would be given to a bad socket, and B: Many protocols this can be a bad idea for, such as MSDP as you mentioned; though that's easy enough to put in conditionals.

I'll fix the TTYPE negotiation resetting for TT++.

From what I understand the typical MUD creates a socket for a given port, and on a copyover execl() is called, which destroys the old process, but somehow it doesn't destroy the socket - even though one would expect it would. As such the socket id and a list of connections can be saved, restored after the copyover, and things continue as if nothing happened.
09 Sep, 2010, David Haley wrote in the 22nd comment:
Votes: 0
Scandum said:
on a copyover execl() is called, which destroys the old process, but somehow it doesn't destroy the socket - even though one would expect it would.

No, one wouldn't – the whole point of exec is to inherit open descriptors, among other things.

See, e.g.,
man fork said:
* The child inherits copies of the parent's set of open file descriptors. Each file descriptor in the child refers to the same open file description (see open(2)) as the corresponding file
descriptor in the parent. This means that the two descriptors share open file status flags, current file offset, and signal-driven I/O attributes (see the description of F_SETOWN and F_SETSIG
in fcntl(2)).
09 Sep, 2010, Rudha wrote in the 23rd comment:
Votes: 0
It seems very odd to me then, if what you quoted is the case, that socket uids get reassigned when NakedMud does a copyover. I cant say Im very familiar with the copyover code for NM in the backend, so I cant really speculate why its doing that. I suspect that the uid pool is being tracked independantly of the actual sockets. Ill take a looksie when I get home.

Maya/Rudha
09 Sep, 2010, David Haley wrote in the 24th comment:
Votes: 0
It depends on what a socket "uid" is according to NakedMud. If it's some kind of internal tracking system, then it's normal that it would change. But the underlying, OS-level descriptor should not change, assuming it implements its copyover with the standard process-replacement method (like an exec call). (I'll note that I don't know how it could keep the sockets open if it didn't use this method. When a process dies without a fork/exec, all open descriptors are closed.)
10 Sep, 2010, Rudha wrote in the 25th comment:
Votes: 0
It is internal to nakedmud, that much I know - or in this case I should probably say SocketMUD, as Hollis has stated in his documentation that he was thankful for SocketMUD as he was not knowledgeable in sockets.

The problem becomes saving the socket information on a copyover; the problem with using an auxiliary data instance, is that my understanding of AuxData on sockets means that the information for that class gets saved to a socket UID. Im not sure if that's how its supposed to work - I would presume the socket itself is an object to which the uid is simply a property, so why it seems to behave in that manner when I have made preliminary attempts at saving the data for a socket, is a mystery to me.

Maya/Rudha
10 Sep, 2010, David Haley wrote in the 26th comment:
Votes: 0
The only thing here that gets transferred across sessions after a fork/exec is the descriptor itself. Any auxiliary data you're storing on it will be lost; the OS has no concept of auxiliary data for sockets. If you're using the UID to key the socket information, and the UID changes across copyover, then yes, you will be in trouble. The underlying file descriptor number should stay the same, however, so you could use that as a key.
10 Sep, 2010, Stendec wrote in the 27th comment:
Votes: 0
Copying socket state across copyover is sort of easy(ish) in NakedMud. First off, sockets without characters are dropped on copyover. That means you only have to worry about sockets with characters. And characters are uniquely identifiable, so you have a way to line the data up with sockets after copyover is complete. Next, storage sets can be written to or read from files pretty easily. And finally, copyover is only ever called from one place, pretty much, so you can add a custom function call before the actual copyover happens to save out the socket auxdata. Example code:

From wherever your socket auxdata is (say, telopt.py for example, and assuming your auxdata is accessible as sock.telopt for this snippet):
################################################################################
## Copyover
################################################################################

copyover_file = "../lib/misc/copyover"

def copyover():
''' Saves the telopt auxiliary data of all active connections with set players
to be restored after the copyover is complete.'''
set = storage.StorageSet()
list = storage.StorageList()

# Iterate through the sockets and save the ones with connected users. Ignore
# the others since they're simply disconnected.
for sk in mudsock.socket_list():
if sk.ch:
s = storage.StorageSet()
s.storeString("k", sk.ch.name)
s.storeSet("v", sk.telopt.store())
list.add(s)

# Store and close the set
set.storeList("list", list)
set.write(copyover_file)
set.close()

def copyover_complete(info):
''' Loads socket auxiliary data for the active connections from a file. '''
set = storage.StorageSet(copyover_file)

# Read the data into a dict.
data = { }
for s in set.readList("list").sets():
data[s.readString("k")] = s.readSet("v")

# Iterate through sockets, and if a player is connected, restore the aux data
# To their socket.
for sk in mudsock.socket_list():
if sk.ch is not None and data.has_key(sk.ch.name):
sk.telopt.load(data[sk.ch.name])

# Close the set
set.close()

# Register a hook so copyover_complete runs.
hooks.add("copyover_complete", copyover_complete)


Then, in cmd_admin.py, find cmd_copyover, and change it to something like:
def cmd_copyover(ch, cmd, arg):
'''Restarts the mud, and keep all sockets connected. But first
call the copyover function from advanced_telopt to keep track
of all our special data there.'''
from telopt import copyover
copyover()
mudsys.do_copyover()
11 Sep, 2010, Rudha wrote in the 28th comment:
Votes: 0
I hadn't thought that the players' characters would provide a consistent reference point and its a valid approach; I do have somewhat of a problem with that as is, in that I don't like the behaviour of dumping sockets in the account screen and I will probably be changing that; but then you would just have to expand that approach to iterate through accounts as well.

Maya/Rudha
20.0/28