Beispiel #1
0
//JAVA TO C# CONVERTER WARNING: 'final' parameters are ignored unless the option to convert to C# 7.2 'in' parameters is selected:
//ORIGINAL LINE: private java.util.concurrent.Callable<Void> slaveCommitter(final org.neo4j.kernel.ha.com.master.Slave slave, final long txId, final CompletionNotifier notifier)
        private Callable <Void> SlaveCommitter(Slave slave, long txId, CompletionNotifier notifier)
        {
            return(() =>
            {
                try
                {
                    // TODO Bypass the CommitPusher, now that we have a single thread pulling updates on each slave
                    // The CommitPusher is all about batching transaction pushing to slaves, to reduce the overhead
                    // of multiple threads pulling the same transactions on each slave. That should be fine now.
//                    slave.pullUpdates( txId );
                    _pusher.queuePush(slave, txId);

                    return null;
                }
                finally
                {
                    notifier.Completed();
                }
            });
        }
Beispiel #2
0
        ///
        /// <param name="txId"> transaction id to replicate </param>
        /// <param name="authorId"> author id for such transaction id </param>
        /// <returns> the number of missed replicas (e.g., desired replication factor - number of successful replications) </returns>
        public virtual int Committed(long txId, int authorId)
        {
            int replicationFactor = _desiredReplicationFactor;
            // If the author is not this instance, then we need to push to one less - the committer already has it
            bool isAuthoredBySlave = _config.ServerId.toIntegerIndex() != authorId;

            if (isAuthoredBySlave)
            {
                replicationFactor--;
            }

            if (replicationFactor == 0)
            {
                return(replicationFactor);
            }
            ICollection <ReplicationContext> committers = new HashSet <ReplicationContext>();

            try
            {
                // TODO: Move this logic into {@link CommitPusher}
                // Commit at the configured amount of slaves in parallel.
                int successfulReplications    = 0;
                IEnumerator <Slave> slaveList = Filter(_replicationStrategy.prioritize(_slaves.getSlaves()).GetEnumerator(), authorId);
                CompletionNotifier  notifier  = new CompletionNotifier();

                // Start as many initial committers as needed
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
                for (int i = 0; i < replicationFactor && slaveList.hasNext(); i++)
                {
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
                    Slave           slave          = slaveList.next();
                    Callable <Void> slaveCommitter = slaveCommitter(slave, txId, notifier);
                    committers.Add(new ReplicationContext(_slaveCommitters.submit(slaveCommitter), slave));
                }

                // Wait for them and perhaps spawn new ones for failing committers until we're done
                // or until we have no more slaves to try out.
                ICollection <ReplicationContext> toAdd    = new List <ReplicationContext>();
                ICollection <ReplicationContext> toRemove = new List <ReplicationContext>();
                while (committers.Count > 0 && successfulReplications < replicationFactor)
                {
                    toAdd.Clear();
                    toRemove.Clear();
                    foreach (ReplicationContext context in committers)
                    {
                        if (!context.Future.Done)
                        {
                            continue;
                        }

                        if (IsSuccessful(context))
                        {
                            // This committer was successful, increment counter
                            successfulReplications++;
                        }
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
                        else if (slaveList.hasNext())
                        {
                            // This committer failed, spawn another one
//JAVA TO C# CONVERTER TODO TASK: Java iterators are only converted within the context of 'while' and 'for' loops:
                            Slave           newSlave = slaveList.next();
                            Callable <Void> slaveCommitter;
                            try
                            {
                                slaveCommitter = slaveCommitter(newSlave, txId, notifier);
                            }
                            catch (Exception t)
                            {
                                _log.error("Unknown error commit master transaction at slave", t);
                                return(_desiredReplicationFactor);
                            }

                            toAdd.Add(new ReplicationContext(_slaveCommitters.submit(slaveCommitter), newSlave));
                        }
                        toRemove.Add(context);
                    }

                    // Incorporate the results into committers collection
                    if (toAdd.Count > 0)
                    {
                        committers.addAll(toAdd);
                    }
                    if (toRemove.Count > 0)
                    {
//JAVA TO C# CONVERTER TODO TASK: There is no .NET equivalent to the java.util.Collection 'removeAll' method:
                        committers.removeAll(toRemove);
                    }

                    if (committers.Count > 0)
                    // There are committers doing work right now, so go and wait for
                    // any of the committers to be done so that we can reevaluate
                    // the situation again.
                    {
                        notifier.WaitForAnyCompletion();
                    }
                }

                // We did the best we could, have we committed successfully on enough slaves?
                if (successfulReplications < replicationFactor)
                {
                    _pushedToTooFewSlaveLogger.info("Transaction " + txId + " couldn't commit on enough slaves, desired " + replicationFactor + ", but could only commit at " + successfulReplications);
                }

                return(replicationFactor - successfulReplications);
            }
            finally
            {
                // Cancel all ongoing committers in the executor
                foreach (ReplicationContext committer in committers)
                {
                    committer.Future.cancel(false);
                }
            }
        }