belliottsmith commented on code in PR #10:
URL: https://github.com/apache/cassandra-accord/pull/10#discussion_r988569766


##########
accord-core/src/main/java/accord/messages/Apply.java:
##########
@@ -54,15 +63,59 @@ public Apply(Node.Id to, Topologies topologies, TxnId 
txnId, Txn txn, Key homeKe
         this.result = result;
     }
 
+    @VisibleForImplementation
+    public Apply(Keys scope, long waitForEpoch, TxnId txnId, Txn txn, Key 
homeKey, Timestamp executeAt, Deps deps, Writes writes, Result result)
+    {
+        super(scope, waitForEpoch);
+        this.txnId = txnId;
+        this.txn = txn;
+        this.homeKey = homeKey;
+        this.executeAt = executeAt;
+        this.deps = deps;
+        this.writes = writes;
+        this.result = result;
+    }
+
+    static Future<Void> waitAndReduce(Future<Void> left, Future<Void> right)

Review Comment:
   > You mean a detailed and informed discussion of the pros and cons of 
different solutions? I feel like the project could use more of this ;)
   
   No, absolutely :)
   
   > In the case where we interact with a single command store, futures 
actually use slightly less memory than callbacks.
   
   That definitely means we've done callbacks wrong :) ... bear in mind, the 
`Future` has to allocate a list entry for the callback, potentially allocates a 
`WaitQueue` for consumers like those above, and it has to perform a CAS to add 
the callbacks, signal the callbacks, and to set the result (also at least four 
for each waiting `Thread`). At _most_ a callback should have to do the last of 
these (and usually not even that).
   
   > Here’s the callback class if you’d like to take a look
   
   This looks like it is trying to implement a map/Reduce chain over a list of 
callbacks, i.e. the `waitAndReduce` method - rather than a single callback? But 
we have to solve this anyway still above, as we shouldn't be blocking, I think. 
So we will need some kind of mechanism for this either way, don't we? I think 
it can be a lot simpler though.
   
   > Often being instantiated and completed in a much narrower scope, like an 
executor, or in some critical path
   
   So, literally anywhere you can have a `Future` you can have a callback with 
exactly the same control flow. There's no need for extra plumbing. Wherever you 
would invoke `AbstractFuture.setSuccess` or `AbstractFuture.setFailure` you can 
invoke a callback.
   
   It is true that an `Executor` lets you hand this off, but we can do that for 
callbacks too. We have the power! `ExecutorPlus` can easily be given a callback 
`execute` method variation, in fact this seems like a really good idea. But 
also, a lambda can be submitted that simply has a try/catch branch doing the 
obvious things.
   
   > I'm not saying performance and safety are mutually exclusive, though 
there's often a trade off between the two.
   
   If I thought `Future` afforded more safety, I'd definitely agree it is a 
cost worth paying, so in that respect I can absolutely see your point of view. 
I just still don't see the extra safety here. 
   
   Perhaps we do as a project need to offer as much scaffolding and support for 
callbacks as we already do for `Future`. Perhaps we can also consider variants 
of `Future` that are more restricted but efficient (and have easier call 
stacks!), so we can begin walking the two extremes closer towards each other as 
well.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to