incubator-wave-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Richard Davis <>
Subject Re: JSON editing and move conflicts
Date Tue, 21 Oct 2014 01:53:46 GMT
Hi Joseph,

Regarding object move, I'm in favor of keeping things simple, but I'm also 
in favor of thinking about this in terms of what people might actually do 
with this capability. Since mapping a directory structure of files is the 
one good example you have, then maybe multiple moves to the same key should 
merge their values as directory moves merge their files. That would mean a 
slightly modified version of your option 1. In the simple case, you have 
{x:1, y:2} -> {z:2}, but in the complex case you have {x:{a:1}, y:{b:2}} -> 
{z:{a:1, b:2}}. 

Maybe you could add a flag that allows the writer to specify whether they 
want a move to "replace" the existing value (your option 1) or "merge" with 
the existing value (this modified option 1). It's still clear what will 
happen if two writers use two different flags, as long as you can put the 
two ops in some order: if the "replace" comes second you can replace, and 
if the "merge" comes second you can merge.

The only downside I see of merging is that it can have a cascading effect. 
That could be tricky, and I haven't thought it through, but I had hope that 
this wouldn't be fundamentally different from the other changes you are 
making in JSON2.


On Sunday, October 19, 2014 8:46:11 AM UTC+8, Joseph Gentle wrote:
> It does complicate the type, and it breaks my nice abstraction. Also 
> remember that any funny logic will need to be on the server and the 
> client - and I'd really like the server to be application-agnostic if 
> possible. That said, the server will probably need 
> application-specific schema validation & access control code anyway, 
> so maybe its not a big deal. 
> Another option is to just do the dangerous thing for objects, but 
> actively encourage people to use lists instead. If you're inserting 
> into a list instead of inserting into an object, the semantics are 
> safe & easy. The final list will just contains both items. For 
> hierarchal to-do lists, you probably want a children:[] list on your 
> nodes anyway. Using object-move when the key is either a GUID or a 
> hash of the data would work fine as well because your keys won't 
> conflict. 
> This won't work if you're trying to map a directory structure of files 
> though. But thats the only bad use case I can think of. Maybe 
> something as simple as a flag on the move operation saying "in the 
> case of conflicts, rewrite the destination key to {key}_n". Or we 
> could just force the IDE to use a list of files, and leave deduping 
> hacks there. 
> -J 
> On Sat, Oct 18, 2014 at 4:44 PM, Ali Lown < <javascript:>>

> wrote: 
> > Hi Joseph, 
> > 
> > I think that the only sensible option is to delegate the resolution of 
> > this action in the case of conflict back into the application, so some 
> > sort of extension of (4) that allows some arbitrary lambda expression 
> > to be passed as the onconflict method. (Depending on the situation, 
> > they might want to 'merge' the two items (if possible), rather than 
> > moving one into a 'backup' location). 
> > 
> > This does complicate the OT type, and does make it more difficult to 
> > analyse how long certain actions will take to resolve though... 
> > 
> > How does this sound? 
> > 
> > Ali 
> > 
> > On 19 October 2014 00:33, Joseph Gentle < <javascript:>>

> wrote: 
> >> I'm (finally!) taking a serious look at making a better version of the 
> >> JSON OT type. I'm cross-posting this here because it directly effects 
> >> sharejs & derby users, and I think any serious rewrite of wave will 
> >> use something like this at the top level to store waves. 
> >> 
> >> I have two questions that I would love some input on from the wider 
> community. 
> >> 
> >> We want to add a 'move' action which will let you transplant arbitrary 
> >> parts of the JSON structure to other places in the tree. This is 
> >> really useful if, for example, you want a hierarchal to-do list, a 
> >> tree of source files for your IDE or a tree of blips. 
> >> 
> >> But I can't figure out what should happen if two users move different 
> >> objects to the same place in the tree at the same time. 
> >> 
> >> 1. The simplest option is to simply delete one of them. This is really 
> >> convenient from a programming pov, but I think that would be the worst 
> >> kind of surprise. {x:1, y:2} -> {z:2} 
> >> 2. We could try and make one of the moves fail - {x:1, y:2} -> {x:1, 
> >> z:2}. On the face of it this sounds great, but this is a cascading 
> >> failure. If (locally) I move x->z then insert some new data at x, what 
> >> happens to the new data? Does the new data get deleted? Does x get 
> >> deleted? I can't think of a good answer here which isn't just 
> >> dangerous in a more complicated way. Making both the moves fail has 
> >> the same problem. 
> >> 3. We could pick a winner and then move the loser to some special 
> >> lost&found bucket or something. So, {x:1, y:2} -> {__recovered_z:1, 
> >> z:2} But that could play havoc with data bindings, and we'd have to 
> >> introduce some reserved keys. The other way to do this is to introduce 
> >> a new top-level structure which contains the data, so it'd be 
> >> {data:{x:1, y:2}} -> {data:{z:2}, lost:[{z:1}]}. 
> >> 4. Or we could add the backup location into the move operation itself, 
> >> so whoever's building on top of this API can make the choice. (They 
> >> can make a better decision because they know what the data structure 
> >> looks like). So instead of (move x->z) we'd have (move x->z, 
> >> onconflict:(move x->__x)) or something. 
> >> 
> >> Are there any other choices I'm missing here? I'm edging toward option 
> >> 4, although it might increase the type's complexity by 50% unless I 
> >> can think of a clean way to do it. 
> >> 
> >> Thanks 
> >> -J 

  • Unnamed multipart/mixed (inline, None, 0 bytes)
View raw message