//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(timeout = TEST_RUN_TIME_MS * 20) public void closeTransaction() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void CloseTransaction()
        {
            BlockingQueue <bool>             committerToTerminator = new LinkedBlockingQueue <bool>(1);
            BlockingQueue <TerminatorAction> terminatorToCommitter = new LinkedBlockingQueue <TerminatorAction>(1);

            RunTwoThreads(tx =>
            {
                bool?terminatorShouldAct = committerToTerminator.poll();
                if (terminatorShouldAct != null && terminatorShouldAct)
                {
                    TerminatorAction action = TerminatorAction.random();
                    action.executeOn(tx);
                    assertTrue(terminatorToCommitter.add(action));
                }
            }, tx =>
            {
                tx.initialize();
                CommitterAction committerAction = CommitterAction.random();
                committerAction.executeOn(tx);
                if (committerToTerminator.offer(true))
                {
                    TerminatorAction terminatorAction;
                    try
                    {
                        terminatorAction = terminatorToCommitter.poll(1, TimeUnit.SECONDS);
                    }
                    catch (InterruptedException)
                    {
                        Thread.CurrentThread.Interrupt();
                        return;
                    }
                    if (terminatorAction != null)
                    {
                        Close(tx, committerAction, terminatorAction);
                    }
                }
            });
        }
        protected internal virtual bool ProcessNextBatch(int batchCount, bool exitIfNoJobsAvailable)
        {
            try
            {
                bool waitForMessage = false;
                bool loop           = false;
                do
                {
                    // exit loop if we'll close the connection
                    if (WillClose())
                    {
                        break;
                    }

                    // do we have pending jobs or shall we wait for new jobs to
                    // arrive, which is required only for releasing stickiness
                    // condition to this thread
                    if (waitForMessage || !_queue.Empty)
                    {
                        _queue.drainTo(_batch, batchCount);
                        // if we expect one message but did not get any (because it was already
                        // processed), silently exit
                        if (_batch.Count == 0 && !exitIfNoJobsAvailable)
                        {
                            // loop until we get a new job, if we cannot then validate
                            // transaction to check for termination condition. We'll
                            // break loop if we'll close the connection
                            while (!WillClose())
                            {
                                Job nextJob = _queue.poll(10, SECONDS);
                                if (nextJob != null)
                                {
                                    _batch.Add(nextJob);

                                    break;
                                }
                                else
                                {
                                    _machine.validateTransaction();
                                }
                            }
                        }
                        NotifyDrained(_batch);

                        // execute each job that's in the batch
                        while (_batch.Count > 0)
                        {
                            Job current = _batch.RemoveAt(0);

                            current.Perform(_machine);
                        }

                        // do we have any condition that require this connection to
                        // stick to the current thread (i.e. is there an open statement
                        // or an open transaction)?
                        loop           = _machine.shouldStickOnThread();
                        waitForMessage = loop;
                    }

                    // we processed all pending messages, let's flush underlying channel
                    if (_queue.size() == 0)
                    {
                        _output.flush();
                    }
                } while (loop);

                // assert only if we'll stay alive
                if (!WillClose())
                {
                    Debug.Assert(!_machine.hasOpenStatement());
                }
            }
            catch (BoltConnectionAuthFatality ex)
            {
                _shouldClose.set(true);
                if (ex.Loggable)
                {
                    _userLog.warn(ex.Message);
                }
            }
            catch (BoltProtocolBreachFatality ex)
            {
                _shouldClose.set(true);
                _log.error(string.Format("Protocol breach detected in bolt session '{0}'.", Id()), ex);
            }
            catch (InterruptedException)
            {
                _shouldClose.set(true);
                _log.info("Bolt session '%s' is interrupted probably due to server shutdown.", Id());
            }
            catch (Exception t)
            {
                _shouldClose.set(true);
                _userLog.error(string.Format("Unexpected error detected in bolt session '{0}'.", Id()), t);
            }
            finally
            {
                if (WillClose())
                {
                    Close();
                }
            }

            return(!_closed.get());
        }