Dear Andreas and Matt: > My ideas about implementing collaboration (also see comments down in the > quote block): > > Don't think about undo / redo, the implementation is still not stable on > single mode, you have no chance to get it working in multiusermode in > this state.
I think it *is* important to think about undo / redo -- not yet about implementing it now, but about what the general mechanism will look like eventually. This is an important point to think about because what one wants to be possible guides a lot of the design principles. Not in terms of the specifics such as which framework or message format to use, or whether there are UUIDs or not, etc., but in terms of the internals of Xournal++ data structures and their capabilities. If I had had clearer ideas in mind about undo/redo (already in single user mode) when I started writing xournal, the overall code would have ended up a lot cleaner. But yes, I do agree with you that one should not worry about implementing networked undo/redo yet, especially if the single-user undo/redo is not finalized yet. One should first come up with some idea of the general structure (symmetric or client/server? etc.), a message format, and code for sending those messages. If the xournal++ internal architecture allows it, the main part of the message data would essentially be just a serialization of the data structure representing an elementary action on the journal ("draw a stroke", "resize an item", "change color of an item", etc.). My point about undo/redo is that such data structures are also exactly what goes into the undo/redo stack -- so it's better to have some agreement about the broad principles for representation of action data between the person implementing networking and the person implementing undo/redo, even if the details of that data representation are not directly relevant to the networking code. (In other terms: the type of data that the instances should be exchanging during a collaborative session is exactly the same thing as undo/redo data. Of course there might also be other types of messages to be exchanged e.g. for handshake or for error recovery.) > Don't think about user rights, you can do this later. Better think about > error handling, because there is really much to do... I agree there'll be a lot of interesting questions regarding error handling. There are of course implementation details about specific scenarios, but the big questions are in two areas in my opinion. One is the issue of network timeouts / losing connections. The other one is conflicting actions on the journal. About network disconnects: - what does a client do if the server doesn't respond anymore? (presumably: notify the user with an error message and revert to single-user mode?) - can the user reconnect to a multi-user session after having lost the connection? (possibly, this might mean losing the local changes and starting from a fresh copy obtained from the remote source). - even if it is convenient to have a "master" or "server" instance, one should ideally be able to continue collaborating if the "master" gets disconnected. (Thinking of: collaborative work of 3-5 people, the "master" gets knocked off the network, the rest of the team should be able to continue.). It doesn't need to be seamless in the first implementation, it could require the remaining users having to restart a networked session. The answers to these questions depend of course on the chosen architecture -- is there a "master" / "server" or is it completely symmetric? (the classroom use case suggests that a master instance is desirable; the collaboration use case would be better off looking fairly symmetric, but can still internally rely on a server instance). About editing conflicts: things will depend very much on what is being implemented. But the worst conflicts do involve a page getting erased while someone is drawing on it. Those can be partially avoided by having a single "master" instance at any given time, which is the only one allowed to perform page operations and has control over what happens, as Matt suggests; but it still means the client instance needs to be able to handle a message from the server telling it the current page is being deleted. (Of course that'd be best handled after the stroke drawing is completed, rather than trying to do it immediately while in the process of drawing.) > First we need target which should be implemented: > Support for 2 - 30 users, much more makes no sense, this will not work > anyway, but it should be theoretical possible that a class works with > her teacher. > Network connection: If your in a local network there are no problem, but > if you're connect through the internet, or a class through wireless... > You have a really big time gap until there is an answer from the server etc. Agreed. > It's not necessary to generate random UUIDs, if a client writes a stroke > the stroke is sent to the server, the server assigns the stroke an ID, > send this id as responde to sender and sends the stroke to all other > clients. I agree entirely. If there is a server instance, which seems easiest, then ID creation/assignment should be the job of the server. Either that, or the ID of an item is a pair (client ID, item ID) where the client IDs are assigned at handshake and all distinct. > Really important is to think about a message protocol, even if you use a > framework or something, you need always to send messages, a simple but > realistic example: > > 1. Handshake: exchange version number etc. to check if they are > compatible, return: OK / FAIL and optional a message to display to the user. > > 2. Commands: A command should be built up with an ID (which command), A > length (how many data are sent with this command) and the data > > 3. Each command has also an answer which looks the same, also ID, > length, data. Yes -- this is very generic and I was taking it for granted, but you are right to point out that it's part of the networking code (pretty much any networking code). Many commands will correspond 1-to-1 to journal operations (again, the same types of operations that go into the undo/redo stack: things like "draw a stroke", "paste a set of strokes", "add a page", ...). So a lot of command IDs will correspond to operation types -- or, of course, there could be a single command ID which means "journal operation", and actual type of operation is in the data. > The most important thing is that it's easy extensible, because in the > future there are may (hopefully;-)) a lot new functions in Xournal++. Yes! > First I would only implement one command: send stroke: so the only thing > you can do is drawing on the first page and send this thought the > network. If this is working you can extend this. Seems reasonable as a first implementation target. But I'd still try to plan the implementation of this very specific command in a way that will allow the rest of the features to be implemented later without restarting from scratch. > But there are a lot of problems you will have, e.g. multi threading and > synchronisation, so don't try to much at time. Is xournal++ multi-threaded? That's going to make things really painful. Certainly all processing should be done in a single thread to avoid conflicts between different threads wanting to manipulate the data. Network messages can usually be sent in a non-blocking way (though I forgot though about the details of non-blocking sockets and whether they are guaranteed to be lossless; if not it might make sense to have a "send queue" and a thread for sending outbound data to emulate non-blocking sockets; but nothing else in it, to avoid conflicts). Incoming messages on sockets usually are caught as events within the GTK+ main loop (of course it all boils down to a select() call deep down, but if I recall correctly GTK+ isolates applications from those details and one just has to set callbacks for incoming data on monitored sockets). Denis ------------------------------------------------------------------------------ Benefiting from Server Virtualization: Beyond Initial Workload Consolidation -- Increasing the use of server virtualization is a top priority.Virtualization can reduce costs, simplify management, and improve application availability and disaster protection. Learn more about boosting the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev _______________________________________________ Xournal-devel mailing list Xournal-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/xournal-devel