private IAsyncResult RemoteAsyncCallAppendEntry(Node otherNode, AppendEntriesMessage message) { RemoteAsyncCallAppendEntryDelegate RemoteDel = new RemoteAsyncCallAppendEntryDelegate(otherNode.AppendEntry); AsyncCallback callback = new AsyncCallback(VerifyHeartBeatsMessages); IAsyncResult RemAr = RemoteDel.BeginInvoke(message, callback, null); return(RemAr); }
public ITuple Take(ISchema schema) { ITuple result; Console.WriteLine("start take"); result = this.node.TupleSpace.Take(schema); Console.WriteLine("end take"); List <Entry> l; lock (this.leaderLog) { l = new List <Entry>(); l.Add(new Entry("take", schema, this.term, this.leaderLog.CommitIndex)); this.leaderLog.CommitIndex++; this.leaderLog.AppendNewEntries(l); } if (DF.N == 1) { return(result); } bool allAck = false; int consensus = 0; Dictionary <int, bool> alreadyTried = new Dictionary <int, bool>(DF.N); for (int i = 0; i < DF.N; i++) { alreadyTried[i] = false; } while (!allAck) { List <IAsyncResult> results = new List <IAsyncResult>(); List <WaitHandle> waits = new List <WaitHandle>(); //foreach (Node node in this.node.otherNodes) View v = this.node.manager.RequestView(); List <Entry> a = new List <Entry>(); a.Add(new Entry("take", schema, this.term, this.leaderLog.CommitIndex)); //foreach (KeyValuePair<int, Node> entry in nodesLeftToTry) foreach (KeyValuePair <int, Pingable> entry in v.pingables) { if (!alreadyTried[entry.Key]) { AppendEntriesMessage message = new AppendEntriesMessage(this.term, 0, 0, this.leaderLog.CommitIndex, l, entry.Key, node.url); RemoteAsyncCallAppendEntryDelegate RemoteDel = new RemoteAsyncCallAppendEntryDelegate(node.otherNodes[entry.Key].AppendEntry); IAsyncResult RemAr = RemoteDel.BeginInvoke(message, null, null); results.Add(RemAr); waits.Add(RemAr.AsyncWaitHandle); } } allAck = WaitHandle.WaitAll(waits.ToArray(), DF.TIMEOUT);//Change to a more reliable value because of timeouts if (!allAck) { // foreach(WaitHandle h in waits) for (int i = 0; i < waits.Count; i++) { try { if (waits[i].WaitOne(0)) { RemoteAsyncCallAppendEntryDelegate d = (RemoteAsyncCallAppendEntryDelegate)((AsyncResult)results[i]).AsyncDelegate; ResponseMessage r = d.EndInvoke(results[i]); if (r.Success && !alreadyTried[r.SharedId]) { //leaderLog.FollowersCommitIndex[r.SharedId]++; alreadyTried[r.SharedId] = true; consensus++; } } } catch (Exception ex) { } if (consensus > DF.N / 2) { allAck = true; } } } } foreach (KeyValuePair <int, bool> entry in alreadyTried) { if (entry.Value) { //leaderLog.FollowersCommitIndex[entry.Key]++; } } return(result); }