public override Tuple Take(Tuple tuple)
        {
            int            timeStep      = 250; // ms
            List <Message> messages      = null;
            Message        resultMessage = null;
            List <Tuple>   intersection  = new List <Tuple>();
            Tuple          selectedTuple = new Tuple(new List <object>());

            // PHASE 1
            var takeRequest = new TakeRequest(ClientRequestSeqNumber, EndpointURL, tuple);

            // wait for all responses
            MulticastMessageWaitAll(View.Nodes, takeRequest);
            WaitMessage(takeRequest, View.Nodes);
            ClientRequestSeqNumber++;

            lock (ReplyResultQueue)
            {
                ReplyResultQueue.TryGetValue(takeRequest, out var replyResult);
                messages = new List <Message>(replyResult?.GetAllResults());
            }

            // get the intersection
            Response response;

            intersection = ((Response)messages.First()).Tuples;
            foreach (Message msg in messages)
            {
                response     = (Response)msg;
                intersection = new List <Tuple>(intersection.Intersect(response.Tuples));
            }

            // choose random tuple from intersection
            selectedTuple = intersection.ElementAt((new Random()).Next(0, intersection.Count));

            // phase 2, issue a take remove and wait for all acks
            Message takeRemove = new TakeRemove(EndpointURL, selectedTuple, takeRequest.SeqNum);

            MulticastMessageWaitAll(View.Nodes, takeRemove);
            WaitMessage(takeRemove, View.Nodes);

            return(selectedTuple);
        }
        public override Tuple Read(Tuple tuple)
        {
            Message resultMessage = null;
            var     request       = new ReadRequest(ClientRequestSeqNumber, EndpointURL, tuple);

            MulticastMessageWaitAny(View.Nodes, request);

            // wait until it gets a any message
            WaitMessage(request, View.Nodes);

            lock (ReplyResultQueue)
            {
                ReplyResultQueue.TryGetValue(request, out var replyResult);
                resultMessage = replyResult?.GetAnyResult();
            }

            ClientRequestSeqNumber++;
            Response response = (Response)resultMessage;

            return(response.Tuples.First());
        }