"OTv3" is just our label for a hypothetical less restricted (read: harder to implement) protocol that doesn't restrict clients to at most one outstanding delta. WIAB is generally ahead of Google Wave in anything actually implemented, including protocol.
The transport-level packet of information in the wave protocols is a delta. A delta is a sequence of ops applying to the same document. Thus more than one operation may be in flight in the same delta. At most one delta is in flight at a time. A NACK is a rejection response to a delta submission, and WIAB does this: any SubmitDeltaResponse with a status != OK. On Mon, Jan 9, 2012 at 3:16 PM, Michael MacFadden < [email protected]> wrote: > David, > > Again thanks. One more question from this set of answers. In your > descriptions you mention the OT v3 protocol, along with the possibility of > having more than one operations in flight as well as NACKS. None of these > concepts seem to exist in WiaB. Is this something that was implemented > later or in another project? > > ~Michael > > On Jan 8, 2012, at 6:12 PM, David Hearnden wrote: > > > Hi Michael, > > > > Torben gave a nice general description of the relationship between retain > > and composition. I'll try to concretize that to your specific questions > > below. > > > > On Wed, Dec 28, 2011 at 3:24 AM, Michael MacFadden < > > [email protected]> wrote: > > > >> > >> 1) In order to compose operations I assume they don't have to have the > >> same document width (how could they for successive inserts for example), > >> but I assume they would need to span the same line? Is that right? In > >> other words you wouldn't compose operations from one paragraph with > >> operations from another? Is the desire to compose one of the driving > >> reasons for the retain operation? > >> > > > > Yes, no, no, no, kind-of. > > > > An operation has two document widths/lengths: the length of the document > > before the op, and the length of the document after the op. The only > > constraint for composition is that, for op2 o op1 to make sense, the > > after-length of op1 must be equal to before-length of op2. These might > or > > might not be equal > > > > There is no relationship between lines and composition. Two ops that > > modify different lines can be (and are) composed into one op. Line > > elements are an application-level abstraction used by the editor to give > > good concurrent behaviour of rich text. The underlying OT code is lower > > level, and has no association with line elements. > > > > Finally, retain is necessary without regard to composition. A trailing > > retain, however, is probably mainly for conceptual satisfaction rather > than > > being fundamentally necessary. It might make the composition code a bit > > simpler, but I'm not sure. Abstractly though, an operation implements a > > function from documents of length N to documents of length M. Those > > lengths are part of that operation's functional type signature. An > > operation that inserts an 'x' at position 30 in a document of total size > 50 > > is considered a completely distinct operation to one that inserts 'x' at > > position 30 in a document of total size 60. This is just like > mathematical > > functions, where the doubling function (\x -> 2*x) from the Integers to > the > > Integers is considered to be a different function to the doubling > function > > from the Integers to the Even Integers, since their codomains are > different > > (even though their domains and ranges are equal). Having the trailing > > retain means that the concrete representation of an operation conforms to > > that abstraction. > > > > 2) When we send out "first" operation over to the server and we are in a > >> holding pattern buffering client operations, are these operations always > >> composed together and then sent over as a single operation when we get > the > >> ACK from the server. It seems like we can only send one operation to > the > >> server at a time, however the on line material implies that when we get > and > >> ACK we send over ALL buffered operations. This seems to be > contradictory. > >> If we have buffered 4 operations, it seems like we can send all of them > as > >> four individual operations. > >> > > > > There is at least one constraint that can cause the client not to compose > > its buffer of outgoing operations. While a list of operations is in > > transit to the server, subsequent client operations are not composed with > > that list. This is so that if an ACK is received, that preserved list of > > operations reflects the exact form that the server received, not some > other > > form that was subsequently modified by composition with more ops. > > > > Another cause for why the client might not compose its outgoing operation > > buffer is that in Wave's OT, transformation and composition do not > > necessarily commute: > > Ts (Ts (s, c1), c2) = Ts (s, c1 ; c2) > > is not always true. This cause might not affect the current CC protocol > > though - it may only be an issue for the OT v3 protocol where a client > > might have several ops in flight that get separately acknowledged. In > that > > case, once a client has sent an op to the server, it can no longer > compose > > that op with any others, unless it gets NACKed. > > > > So, in general, the client will have a list of operations that are yet to > > be ACKed by the server, and some subset of those operations will be in > > flight. Operations in that in-flight subset can not be composed with > > anything. Operations that have not yet been sent, however, are free to > be > > composed together, but the client is not obliged to do so. In > particular, > > while DocOps can always be composed, WaveOps can not always be composed, > so > > it is important that client-side composition is treated as an optional > > behaviour rather than required. > > > > 3) Is there a run down of how the CurrencyControl class does point #2 > >> anywhere. I see the unacknowledged, the inferredServerPath, and the > >> clientOperationsQueue objects and get a lose impression of how these are > >> managed but any help with regard to incoming server operations while we > >> have an operation in flight would be appreciated. Specifically what > >> transformations are performed on which object structures when we get a > new > >> operation form there server, and where / when is composition happening. > >> > > > > I can't recall where this happens in the code. IIRC, composing buffered > > operations is not implemented in the core CC class, but is rather done > by a > > specific subclass of an OperationQueue (BufferedOperationQueue?). I > think > > its behaviour was just to attempt composition of any incoming ops with > the > > last op in the buffer, so long as that op is not in flight waiting for an > > ACK or NACK. > > > > > >> 4) How exactly are the hashed versions designed? There seems to be a > >> monotonic scalar version number and a hash? I want to make sure I > >> understand how both are generated and how both are used. > >> > > > > I'll defer this to Alex. > > > > If any of this is well documented, please let me know where I could find > >> it. If it is not, I would volunteer to document this as I work through > it. > >> Thanks in advance. > >> > > > > I think some of the detailed design intents for the op stuff is littered > > throughout various mailing threads, but not in any written document that > I > > can recall. Thankyou for offering to collate these answers into a > cohesive > > document. It's always easier to answer specific questions like these in > > email than it is to curate a single document over time that should > explain > > it all! > > > > -Dave > >
