New version with slightly more correct cached edit handling. And I've added a third client that is being a spam bot.
The state trace now looks like this: Three clients, sync'd server editHistory[0]: Client 'Client1' at server revision 1 with document Client 'Client2' at server revision 1 with document Client 'Client3' at server revision 1 with document Client3 is generating noise server editHistory[0]: server editHistory[1]: ++" Chatter"; Client 'Client1' at server revision 1 with document Client 'Client2' at server revision 1 with document Client 'Client3' at server revision 2 with document ++" Chatter"; Client2 has generated an edit, and it's in flight server editHistory[0]: server editHistory[1]: ++" Chatter"; Client 'Client1' at server revision 1 with document ++"Hello"; with edit in flight ++"Hello"; Client 'Client2' at server revision 1 with document Client 'Client3' at server revision 2 with document ++" Chatter"; Client2 has generated matching edit, also in flight server editHistory[0]: server editHistory[1]: ++" Chatter"; Client 'Client1' at server revision 1 with document ++"Hello"; with edit in flight ++"Hello"; Client 'Client2' at server revision 1 with document ++"Hello"; with edit in flight ++"Hello"; Client 'Client3' at server revision 2 with document ++" Chatter"; Client1 has handbasket edit cached server editHistory[0]: server editHistory[1]: ++" Chatter"; Client 'Client1' at server revision 1 with document ++"Hello"; with edit in flight ++"Hello"; with cached edit __5; ++" Going to hell"; Client 'Client2' at server revision 1 with document ++"Hello"; with edit in flight ++"Hello"; Client 'Client3' at server revision 2 with document ++" Chatter"; Server has client2's edit in, and clients synced there server editHistory[0]: server editHistory[1]: ++" Chatter"; server editHistory[2]: ++"Hello"; __8; Client 'Client1' at server revision 3 with document ++"Hello Chatter"; with cached edit __5; ++" Going to hell"; __8; Client 'Client2' at server revision 3 with document ++"Hello Chatter"; Client 'Client3' at server revision 3 with document ++"Hello Chatter"; Client3 is generating noise server editHistory[0]: server editHistory[1]: ++" Chatter"; server editHistory[2]: ++"Hello"; __8; server editHistory[3]: __13; ++" Chatter"; Client 'Client1' at server revision 3 with document ++"Hello Chatter"; with cached edit __5; ++" Going to hell"; __8; Client 'Client2' at server revision 3 with document ++"Hello Chatter"; Client 'Client3' at server revision 4 with document ++"Hello Chatter Chatter"; Server accepts client1's edit server editHistory[0]: server editHistory[1]: ++" Chatter"; server editHistory[2]: ++"Hello"; __8; server editHistory[3]: __13; ++" Chatter"; server editHistory[4]: ++"Hello"; __21; Client 'Client1' at server revision 3 with document ++"Hello Chatter"; with cached edit __5; ++" Going to hell"; __8; Client 'Client2' at server revision 3 with document ++"Hello Chatter"; Client 'Client3' at server revision 4 with document ++"Hello Chatter Chatter"; Client3 is generating noise server editHistory[0]: server editHistory[1]: ++" Chatter"; server editHistory[2]: ++"Hello"; __8; server editHistory[3]: __13; ++" Chatter"; server editHistory[4]: ++"Hello"; __21; server editHistory[5]: __26; ++" Chatter"; Client 'Client1' at server revision 3 with document ++"Hello Chatter"; with cached edit __5; ++" Going to hell"; __8; Client 'Client2' at server revision 3 with document ++"Hello Chatter"; Client 'Client3' at server revision 6 with document ++"HelloHello Chatter Chatter Chatter"; Client1's cached edit posted to server, and accepted server editHistory[0]: server editHistory[1]: ++" Chatter"; server editHistory[2]: ++"Hello"; __8; server editHistory[3]: __13; ++" Chatter"; server editHistory[4]: ++"Hello"; __21; server editHistory[5]: __26; ++" Chatter"; server editHistory[6]: __10; ++" Going to hell"; __24; Client 'Client1' at server revision 7 with document ++"HelloHello Going to hell Chatter Chatter Chatter"; Client 'Client2' at server revision 7 with document ++"HelloHello Going to hell Chatter Chatter Chatter"; Client 'Client3' at server revision 7 with document ++"HelloHello Going to hell Chatter Chatter Chatter"; >From my perspective, the above shows that this simple c/s protocol based on pushing edits to the server, and pulling a queue of edits back in separate c->s calls, works. I'm not happy with how i'm modeling cached edits in the client at this point, which means I need to re-do Client#acceptUpdates(), probably using a strategy pattern... brett On Thu, Jan 21, 2010 at 10:28 AM, Brett Morgan <[email protected]>wrote: > Ugh. > > Reading back through my code after breakfast, and I realise that i'm > handling the cached edit while an edit is in flight incorrectly. And my > initial stabs at fixing it up are breaking. I think i need a bigger piece of > paper to figure this out... > > brett > > 2010/1/21 Brett Morgan <[email protected]> > > Heya Torben, >> >> I have attached a java class that I believe implements Daniel's scenario. >> First off, note that I'm not implementing the wave federation algorithm, as >> federation isn't my goal. My goal is to build web apps that use wave's OT. >> That said, here is the output of the aforementioned java class showing that >> the server and the two clients converge. >> >> State of system after step 1 >> server editHistory[0]: >> Client 'Client1' at server revision 1 with document >> Client 'Client2' at server revision 1 with document >> State of system after step 2 >> server editHistory[0]: >> Client 'Client1' at server revision 1 with document ++"Hello"; with edit >> in flight ++"Hello"; >> Client 'Client2' at server revision 1 with document >> State of system after step 3 >> server editHistory[0]: >> Client 'Client1' at server revision 1 with document ++"Hello"; with edit >> in flight ++"Hello"; >> Client 'Client2' at server revision 1 with document ++"Hello"; with edit >> in flight ++"Hello"; >> State of system after step 4 >> server editHistory[0]: >> Client 'Client1' at server revision 1 with document ++"Hello"; with edit >> in flight ++"Hello"; with cached edit __5; ++"Going to hell"; >> Client 'Client2' at server revision 1 with document ++"Hello"; with edit >> in flight ++"Hello"; >> State of system after step 5 >> server editHistory[0]: >> server editHistory[1]: ++"Hello"; >> server editHistory[2]: ++"Hello"; __5; >> Client 'Client1' at server revision 2 with document ++"Hello"; with >> cached edit __5; ++"Going to hell"; >> Client 'Client2' at server revision 2 with document ++"Hello"; >> State of system after step 7 >> server editHistory[0]: >> server editHistory[1]: ++"Hello"; >> server editHistory[2]: ++"Hello"; __5; >> server editHistory[3]: __10; ++"Going to hell"; >> Client 'Client1' at server revision 4 with document ++"HelloHelloGoing to >> hell"; >> Client 'Client2' at server revision 4 with document ++"HelloHelloGoing to >> hell"; >> >> >> On Thu, Jan 21, 2010 at 7:15 AM, Torben Weis <[email protected]>wrote: >> >>> Hi Brett, >>> >>> thanks for the hint to your project. I did not know it before. >>> >> >> It had it's coming out party at LCA. And I think I'm going to rip it down >> and start again, this time using long poll based notification. I couldn't do >> long polls while I was targeting AppEngine as my deployment environment. >> >> >>> However, I would like to see a proof (i.e. a short explanation is >>> sufficient) how you intend to solve the problem I have mentioned. >>> Running code is no proof :-) >>> >> >> If running code doesn't merit existence proof status, then i'm fucked. =) >> >> >>> For some reasons I strongly doubt that your code (or any possible code) >>> can handle this without changes to the C/S protocol. >>> >> >> The client/server protocol in the FedOne code base, unless i miss my >> guess, isn't doing OT. >> >> >>> Your application seems to be different anyway. If I am not mistaken (I >>> just read the wave you mentioned) you are running >>> a web client which connects to your web server which connects to FedOne. >>> Right? >>> >> >> Heh, no. I'm not using FedOne, just the OT component of FedOne. I'm >> building out the capacity to be able to have gwt web clients running OT sync >> with a webserver. It works, but I lack the theoretical grounding to prove >> it. >> >> >>> The problem I mentioned is between your web server and FedOne. In my case >>> it is between QWaveClient and FedOne. >>> Your web app can of course recover as long as FedOne and your web server >>> are stable. But what happens if your >>> WebServer crashes in an unfortunate moment? Your code will suffer from >>> the very problem I described. >>> >> >> If the web server goes down with unsync'd state, everything goes shiny. At >> this point I force the clients to drop all state and reload. >> >> >>> However, would like to be proven wrong here since this would give me a >>> solution to my initial problem :-) >>> >> >> Sorta, kinda, maybe. >> >> >>> Greetings >>> Torben >>> >>> 2010/1/20 Brett Morgan <[email protected]> >>> >>>> Actually, no, OT deals with this case. My almost working code that I >>>> presented at LCA2010 deals with this edge case. Unfortunately it has bugs, >>>> and dies in the arse randomly. Sigh. >>>> >>>> Wave that I presented from: >>>> >>>> https://wave.google.com/wave/#restored:wave:googlewave.com!w%252BTBvx4ehoA<https://wave.google.com/wave/#restored:wave:googlewave.com%21w%252BTBvx4ehoA> >>>> The code: >>>> >>>> http://code.google.com/p/wave-ot-editor/source/browse/#svn/wave-ot-editor >>>> >>>> I can put together a JUnit test case showing that this case actually >>>> stabilises using the Wave OT code, if that would help... >>>> >>>> >>>> On Wed, Jan 20, 2010 at 11:40 AM, Torben Weis <[email protected]>wrote: >>>> >>>>> Hi Brett, >>>>> >>>>> thanks for the suggestion. >>>>> However, it seems to me that this approach is not completely correct. >>>>> >>>>> Imagine two clients which are sending a delta against the same server >>>>> version. >>>>> The delta says to insert "Hello" at some position in a blip. >>>>> The correct outcome is "HelloHello" being inserted. >>>>> Now one client fails to submit its delta, the other one succeeds. >>>>> The client that failed cannot detect that it failed, because the other >>>>> delta looks exactly the same. Thus, in the end "Hello" will be inserted >>>>> only once. >>>>> >>>>> I agree that this is an academic corner case, but I see no solution for >>>>> this >>>>> when relying on delta comparisons. >>>>> >>>>> Greetings >>>>> Torben >>>>> >>>>> >>>>> 2010/1/19 Brett Morgan <[email protected]> >>>>> >>>>>> If you are transforming your docops, you can compare the docops coming >>>>>> back down for equality. You are doing client side transformations, right? >>>>>> >>>>>> org.waveprotocol.wave.model.operation.OpComparators is the FedOne code >>>>>> for comparing equality of ops. Which, after a whole bunch of edge case >>>>>> checking turns into the following comparison: >>>>>> >>>>>> DocOpUtil.toConciseString(a).equals(DocOpUtil.toConciseString(b)) >>>>>> >>>>>> In short, comparing docops for equality is easy, as long as you keep >>>>>> transforming your docops... >>>>>> >>>>>> On Wed, Jan 20, 2010 at 9:42 AM, Torben Weis >>>>>> <[email protected]>wrote: >>>>>> >>>>>>> Hi James, >>>>>>> >>>>>>> How about when the client connects to the server again it does a >>>>>>>> history >>>>>>>> check against the known good deltas it has sent out. If the last >>>>>>>> delta >>>>>>>> it sent out isn't in the history, then it hasn't been received. >>>>>>>> >>>>>>> >>>>>>> The problem is that this is impossible. How should QWaveClient >>>>>>> recognize a delta as >>>>>>> being its own? The server has perhaps transformed the delta, i.e. >>>>>>> simple delta comparison >>>>>>> is not possible and looking at version numbers does not help either. >>>>>>> >>>>>>> Greetings >>>>>>> Torben >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> >>>>>>>> James Purser >>>>>>>> http://wavingtheshiny.collaborynth.com.au >>>>>>>> Wave Addresses: >>>>>>>> [email protected] (wave.google.com) >>>>>>>> [email protected] (wavesandbox.com) >>>>>>>> [email protected] (collaborynth.com.au FedOne Server) >>>>>>>> Skype: purserj1977 >>>>>>>> GTalk: [email protected] >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> You received this message because you are subscribed to the Google >>>>>>>> Groups "Wave Protocol" group. >>>>>>>> To post to this group, send email to [email protected] >>>>>>>> . >>>>>>>> To unsubscribe from this group, send email to >>>>>>>> [email protected]<wave-protocol%[email protected]> >>>>>>>> . >>>>>>>> For more options, visit this group at >>>>>>>> http://groups.google.com/group/wave-protocol?hl=en. >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> --------------------------- >>>>>>> Prof. Torben Weis >>>>>>> Universitaet Duisburg-Essen >>>>>>> [email protected] >>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "Wave Protocol" group. >>>>>>> To post to this group, send email to [email protected]. >>>>>>> To unsubscribe from this group, send email to >>>>>>> [email protected]<wave-protocol%[email protected]> >>>>>>> . >>>>>>> For more options, visit this group at >>>>>>> http://groups.google.com/group/wave-protocol?hl=en. >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Brett Morgan http://domesticmouse.livejournal.com/ >>>>>> >>>>>> -- >>>>>> You received this message because you are subscribed to the Google >>>>>> Groups "Wave Protocol" group. >>>>>> To post to this group, send email to [email protected]. >>>>>> To unsubscribe from this group, send email to >>>>>> [email protected]<wave-protocol%[email protected]> >>>>>> . >>>>>> For more options, visit this group at >>>>>> http://groups.google.com/group/wave-protocol?hl=en. >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> --------------------------- >>>>> Prof. Torben Weis >>>>> Universitaet Duisburg-Essen >>>>> [email protected] >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Wave Protocol" group. >>>>> To post to this group, send email to [email protected]. >>>>> To unsubscribe from this group, send email to >>>>> [email protected]<wave-protocol%[email protected]> >>>>> . >>>>> For more options, visit this group at >>>>> http://groups.google.com/group/wave-protocol?hl=en. >>>>> >>>>> >>>> >>>> >>>> -- >>>> Brett Morgan http://domesticmouse.livejournal.com/ >>>> >>>> -- >>>> You received this message because you are subscribed to the Google >>>> Groups "Wave Protocol" group. >>>> To post to this group, send email to [email protected]. >>>> To unsubscribe from this group, send email to >>>> [email protected]<wave-protocol%[email protected]> >>>> . >>>> For more options, visit this group at >>>> http://groups.google.com/group/wave-protocol?hl=en. >>>> >>>> >>> >>> >>> -- >>> --------------------------- >>> Prof. Torben Weis >>> Universitaet Duisburg-Essen >>> [email protected] >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Wave Protocol" group. >>> To post to this group, send email to [email protected]. >>> To unsubscribe from this group, send email to >>> [email protected]<wave-protocol%[email protected]> >>> . >>> For more options, visit this group at >>> http://groups.google.com/group/wave-protocol?hl=en. >>> >>> >> >> >> -- >> Brett Morgan http://domesticmouse.livejournal.com/ >> > > > > -- > Brett Morgan http://domesticmouse.livejournal.com/ > -- Brett Morgan http://domesticmouse.livejournal.com/--
You received this message because you are subscribed to the Google Groups "Wave Protocol" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to [email protected].
For more options, visit this group at http://groups.google.com/group/wave-protocol?hl=en.
Breakage.java
Description: Binary data
