These are chat archives for RBMHTechnology/eventuate

13th
Oct 2016
Alexander Semenov
@Tvaroh
Oct 13 2016 09:06

@krasserm according to

pre(add(n, m), T ) ≡ ∃(z, m) ∈ T

, parent node should exist when adding a child node. To match this atSource precondition, should CRDT return an error (as an exception or encoded in the return datatype) if parent doesn't exist? Or just ignore the call?

Martin Krasser
@krasserm
Oct 13 2016 09:08
return error i.e. async operation on service interface should complete with a Failure
Alexander Semenov
@Tvaroh
Oct 13 2016 09:10
I see, then CRDT (not service) itself should throw an exception that will be wrapped to a future by op
Alexander Semenov
@Tvaroh
Oct 13 2016 10:00

Martin, could you confirm that by reasoning is correct in the following?

I'm working on resolving add/remove operations conflicts.

For example at location 1 we add a node and observe that its parent exists (atSource phase) and add it to the underlying set CRDT ("local" downstream phase). At the same time at location 2 we remove that parent, gather all its descendants timestamps (atSource phase) and remove them with parent ("local" downstream phase).

When the addition operation is replicated to the location 2, we see that parent doesn't exist anymore (deleted concurrently). We apply one of the connection policies - either skip adding the node or put it under the root.

When the deletion operation is replicated to the location 1, we see that the node being deleted has an additional child not observed previously (added concurrently). We apply one of the connection policies - either skip the concurrently added child or put it under the root.

Does it make sense?

Martin Krasser
@krasserm
Oct 13 2016 10:09

... that will be wrapped to a future by op

what do you mean with by op?

I'm working on resolving add/remove operations conflicts ...

Makes sense to me what you've written

Alexander Semenov
@Tvaroh
Oct 13 2016 10:45

thanks, by op I mean

  /**
   * Updates the CRDT identified by `id` with given `operation`.
   * Returns the updated value of the CRDT.
   */
  protected def op(id: String, operation: Any): Future[B]

in CRDTService trait

Martin Krasser
@krasserm
Oct 13 2016 10:47
ok, :+1: then
Alexander Semenov
@Tvaroh
Oct 13 2016 14:08
Martin, conflicts resolution in a tree might modify tree in a non-obvious way for a caller and there should be a way to make him know about it. E.g. if a node is moved to root when adding to concurrently deleted parent. Should such information be encoded in TreeCrdtService service methods return types in your opinion?
Martin Krasser
@krasserm
Oct 13 2016 15:06
There might be conflict resolutions ongoing locally (from concurrent updates at multiple remote locations) without even having a local user interaction. If we want to inform a user about local conflict resolutions we'd anyway need to do that with a listener/notification mechanism. However, I'd like to leave that an application-level concern to investigate how local state changed.
Martin Krasser
@krasserm
Oct 13 2016 15:29

return error i.e. async operation on service interface should complete with a Failure

on the other hand, a successful validation of a local operation atSource doesn't necessarily mean that application of that operation in local downstream is conflict-free. There might be a concurrent operation (from remote) applied to local state after validating a local operation (in atSource) but before applying that local operation locally after persistence (in local downstream). That's ok, a caller just needs to be aware of that. He can inspect the local state returned from the update operation to find out if this was the case or not.