예제 #1
0
        public IHttpActionResult GetCommits()
        {
            CommitsModel vm;
            UnitOfWork   unitOfWork = null;

            System.Diagnostics.Trace.TraceInformation("Get Commits");

            try
            {
                unitOfWork = new UnitOfWork();

                var         parameters = this.Request.GetQueryNameValuePairs();
                CommitQuery query      = new CommitQuery(unitOfWork.Context.Commits);
                var         keyword    = parameters.FirstOrDefault(p => p.Key == "keyword").Value;

                if (string.IsNullOrEmpty(keyword) == false)
                {
                    query.Keyword = parameters.FirstOrDefault(p => p.Key == "keyword").Value;
                }

                query.ExcludeApproved = String.Equals("true", parameters.FirstOrDefault(p => p.Key == "excludeApproved").Value, StringComparison.InvariantCulture);
                query.Max             = Parser.ParseNullable <int>(parameters.FirstOrDefault(p => p.Key == "max").Value);
                query.IncludeAuthor   = parameters.FirstOrDefault(p => p.Key == "include").Value;
                query.ExcludeAuthor   = parameters.FirstOrDefault(p => p.Key == "exclude").Value;
                query.Project         = Parser.ParseNullable <int>(parameters.FirstOrDefault(p => p.Key == "project").Value);

                var list = new List <Tuple <Commit, CommitStats> >();
                foreach (var commit in query.Execute())
                {
                    var comments = unitOfWork.Context.Comments.Where(c => c.Revision == commit.Revision).ToList();

                    var replies = comments.Where(c => c.User == commit.Author && c.IsLike == false);
                    var reviews = comments.Where(c => c.User != commit.Author && c.IsLike == false);
                    var likes   = comments.Where(c => c.IsLike == true);

                    var stats = new CommitStats(
                        reviews.Select(c => c.User).Distinct().Count(),
                        reviews.Count(),
                        replies.Count(),
                        likes.Count());

                    list.Add(new Tuple <Commit, CommitStats>(commit, stats));
                }
                vm = new CommitsModel(list);

                return(Ok(vm));
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError("GetRevision: " + ex);
                return(InternalServerError(ex));
            }
            finally
            {
                if (unitOfWork != null)
                {
                    unitOfWork.Dispose();
                }
            }
        }
예제 #2
0
        private BuildStatistics CreateCommitsStats(BuildCommits buildCommits, BuildInfo buildInfo)
        {
            var result = new BuildStatistics(buildInfo);

            var buildCommit = buildCommits.BuildCommit;

            var compareList = new List <Commit>();

            compareList.Add(buildCommit);
            compareList.AddRange(buildCommits.PreviousCommits);

            var tracker = new FilesStatisticsTracker();

            for (int i = 0; i < compareList.Count; i++)
            {
                var commitA = compareList.ElementAtOrDefault(i);
                var commitB = compareList.ElementAtOrDefault(i + 1);

                if (commitA == null || commitB == null)
                {
                    break;
                }

                var commitStats = new CommitStats();
                commitStats.LocalDateTime = commitA.Author.When.LocalDateTime;
                commitStats.Commit        = commitA.Sha;
                commitStats.Author        = commitA.Author.Name;

                var diff = this.repository.Diff.Compare <Patch>(commitB.Tree, commitA.Tree);

                foreach (var file in diff)
                {
                    tracker.AddAuthor(file.Path, file.OldPath, commitA.Author.Name);
                    tracker.IncreaseRevision(file.Path, file.OldPath);

                    var fileStats = new FileStats();
                    fileStats.Path    = file.Path;
                    fileStats.OldPath = file.OldPath;
                    fileStats.NumberOfModifiedLines = file.LinesAdded + file.LinesDeleted;
                    fileStats.BuildResult           = buildInfo.BuildResult;
                    fileStats.GitObjectId           = file.Oid.Sha;

                    commitStats.AddFileStats(fileStats);
                }

                result.AddStats(commitStats);
            }

            foreach (var loopStat in result.CommitStats)
            {
                foreach (var loopFile in loopStat.FileStats)
                {
                    loopFile.NumberOfDistinctCommitters = tracker.GetDisctinctAuthorsCount(loopFile.Path);
                    loopFile.NumberOfRevisions          = tracker.GetRevisionsCount(loopFile.Path);
                }
            }

            return(result);
        }
예제 #3
0
        }                                      // TODO not used ????

        public CommitDetailViewModel(Commit commit, CommitStats stats)
        {
            Revision        = commit.Revision;
            Author          = commit.Author;
            Message         = commit.Message;
            Timestamp       = commit.Timestamp;
            NumberReviewers = stats.NumberReviewers;
            NumberComments  = stats.NumberComments;
            NumberReplies   = stats.NumberReplies;
            ApprovedBy      = commit.ApprovedBy;
        }
예제 #4
0
        public static void Notify(CommitStats stats, DocumentDatabase database)
        {
            if (stats.NumberOf4KbsWrittenToDisk == 0 ||
                // we don't want to raise the error too often
                stats.WriteToJournalDuration.TotalMilliseconds < 500)
            {
                return;
            }

            var writtenDataInMb        = stats.NumberOf4KbsWrittenToDisk / (double)256;
            var seconds                = stats.WriteToJournalDuration.TotalSeconds;
            var rateOfWritesInMbPerSec = writtenDataInMb / seconds;

            if (rateOfWritesInMbPerSec < 1)
            {
                database.NotificationCenter.SlowWrites.Add(stats.JournalFilePath, writtenDataInMb, seconds);
            }
        }
        private void CompletePreviousTransaction(
            DocumentsOperationContext context,
            RavenTransaction previous,
            CommitStats commitStats,
            ref List <MergedTransactionCommand> previousPendingOps,
            bool throwOnError)
        {
            try
            {
                _recording.State?.Record(context, TxInstruction.EndAsyncCommit);
                previous.EndAsyncCommit();

                //not sure about this 'if'
                if (commitStats != null)
                {
                    SlowWriteNotification.Notify(commitStats, _parent);
                }

                if (_log.IsInfoEnabled)
                {
                    _log.Info($"EndAsyncCommit on {previous.InnerTransaction.LowLevelTransaction.Id}");
                }

                NotifyOnThreadPool(previousPendingOps);
            }
            catch (Exception e)
            {
                foreach (var op in previousPendingOps)
                {
                    op.Exception = e;
                }
                NotifyOnThreadPool(previousPendingOps);
                previousPendingOps = null; // RavenDB-7417
                if (throwOnError)
                {
                    throw;
                }
            }
        }
예제 #6
0
        private Metric CreateStat(BuildInfo current, CommitStats commitStats, FileStats fileStats)
        {
            var stat = new Metric();

            stat.BuildCommit   = current.CommitHash;
            stat.BuildResult   = (int)current.BuildResult;
            stat.Commit        = commitStats.Commit;
            stat.ExportDateUtc = DateTime.UtcNow;
            stat.NumberOfDistinctCommitters = fileStats.NumberOfDistinctCommitters;
            stat.NumberOfModifiedLines      = fileStats.NumberOfModifiedLines;
            stat.NumberOfRevisions          = fileStats.NumberOfRevisions;
            stat.OldPath = fileStats.OldPath;
            stat.Path    = fileStats.Path;
            stat.BuildCommitDateTimeLocal = commitStats.LocalDateTime;
            stat.BuildDateTimeLocal       = current.BuildDateTimeLocal;
            stat.Author           = commitStats.Author;
            stat.BuildProjectName = current.BuildProjectName;
            stat.ProjectName      = this.appConfiguration.ImportProjectName;
            stat.ObjectId         = fileStats.GitObjectId;

            return(stat);
        }
예제 #7
0
        public static void Notify(CommitStats stats, DocumentDatabase database)
        {
            if (stats.NumberOf4KbsWrittenToDisk == 0 ||
                // we don't want to raise the error too often
                stats.WriteToJournalDuration.TotalMilliseconds < 500)
            {
                return;
            }

            var writtenDataInMb        = stats.NumberOf4KbsWrittenToDisk / (double)256;
            var seconds                = stats.WriteToJournalDuration.TotalSeconds;
            var rateOfWritesInMbPerSec = writtenDataInMb / seconds;

            if (rateOfWritesInMbPerSec < 1)
            {
                database.NotificationCenter.Add(PerformanceHint.Create(database.Name,
                                                                       $"An extremely slow write to disk.",
                                                                       $"We wrote {writtenDataInMb:N} MB in {seconds:N} seconds ({rateOfWritesInMbPerSec:N} MB/s) to: '{stats.JournalFilePath}'",
                                                                       PerformanceHintType.SlowIO,
                                                                       NotificationSeverity.Info,
                                                                       $"TxMerger/{Path.GetDirectoryName(stats.JournalFilePath)}"
                                                                       ));
            }
        }
예제 #8
0
 public void RetrieveCommitStats(out CommitStats stats)
 {
     _requestedCommitStats = stats = new CommitStats();
 }
        private void MergeTransactionsWithAsyncCommit(
            ref DocumentsOperationContext previous,
            ref IDisposable returnPreviousContext,
            List <MergedTransactionCommand> previousPendingOps)
        {
            DocumentsOperationContext current = null;
            IDisposable currentReturnContext  = null;

            try
            {
                while (true)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info($"BeginAsyncCommit on {previous.Transaction.InnerTransaction.LowLevelTransaction.Id} with {_operations.Count} additional operations pending");
                    }

                    currentReturnContext = _parent.DocumentsStorage.ContextPool.AllocateOperationContext(out current);
                    CommitStats commitStats = null;
                    try
                    {
                        previous.Transaction.InnerTransaction.LowLevelTransaction.RetrieveCommitStats(out commitStats);
                        _recording.State?.Record(current, TxInstruction.BeginAsyncCommitAndStartNewTransaction);
                        current.Transaction = previous.Transaction.BeginAsyncCommitAndStartNewTransaction(current);
                    }
                    catch (Exception e)
                    {
                        foreach (var op in previousPendingOps)
                        {
                            op.Exception = e;
                        }
                        NotifyOnThreadPool(previousPendingOps);

                        if (e is OutOfMemoryException)
                        {
                            try
                            {
                                //already throwing, attempt to complete previous tx
                                CompletePreviousTransaction(previous, previous.Transaction, commitStats, ref previousPendingOps, throwOnError: false);
                            }
                            finally
                            {
                                current.Transaction?.Dispose();
                                currentReturnContext.Dispose();
                            }
                        }

                        return;
                    }

                    var currentPendingOps = GetBufferForPendingOps();
                    PendingOperations result;
                    bool calledCompletePreviousTx = false;
                    try
                    {
                        var transactionMeter = TransactionPerformanceMetrics.MeterPerformanceRate();
                        try
                        {
                            result = ExecutePendingOperationsInTransaction(
                                currentPendingOps, current,
                                previous.Transaction.InnerTransaction.LowLevelTransaction.AsyncCommit, ref transactionMeter);
                            UpdateGlobalReplicationInfoBeforeCommit(current);
                        }
                        finally
                        {
                            transactionMeter.Dispose();
                        }
                        calledCompletePreviousTx = true;
                        CompletePreviousTransaction(previous, previous.Transaction, commitStats, ref previousPendingOps, throwOnError: true);
                    }
                    catch (Exception e)
                    {
                        using (current.Transaction)
                            using (currentReturnContext)
                            {
                                if (calledCompletePreviousTx == false)
                                {
                                    CompletePreviousTransaction(
                                        previous,
                                        previous.Transaction,
                                        commitStats,
                                        ref previousPendingOps,
                                        // if this previous threw, it won't throw again
                                        throwOnError: false);
                                }
                                else
                                {
                                    throw;
                                }
                            }

                        if (e is HighDirtyMemoryException highDirtyMemoryException)
                        {
                            if (_log.IsInfoEnabled)
                            {
                                var errorMessage = $"{currentPendingOps.Count:#,#0} operations were cancelled because of high dirty memory, details: {highDirtyMemoryException.Message}";
                                _log.Info(errorMessage, highDirtyMemoryException);
                            }

                            NotifyHighDirtyMemoryFailure(currentPendingOps, highDirtyMemoryException);
                        }
                        else
                        {
                            if (_log.IsInfoEnabled)
                            {
                                _log.Info($"Failed to run merged transaction with {currentPendingOps.Count:#,#0} operations in async manner, will retry independently", e);
                            }

                            NotifyTransactionFailureAndRerunIndependently(currentPendingOps, e);
                        }

                        return;
                    }

                    _recording.State?.Record(previous, TxInstruction.DisposePrevTx, previous.Transaction.Disposed == false);

                    previous.Transaction.Dispose();
                    returnPreviousContext.Dispose();

                    previous = current;
                    returnPreviousContext = currentReturnContext;

                    switch (result)
                    {
                    case PendingOperations.CompletedAll:
                        try
                        {
                            previous.Transaction.InnerTransaction.LowLevelTransaction.RetrieveCommitStats(out var stats);
                            _recording.State?.Record(current, TxInstruction.Commit);
                            previous.Transaction.Commit();

                            SlowWriteNotification.Notify(stats, _parent);
                        }
                        catch (Exception e)
                        {
                            foreach (var op in currentPendingOps)
                            {
                                op.Exception = e;
                            }
                        }
                        NotifyOnThreadPool(currentPendingOps);
                        return;

                    case PendingOperations.HasMore:
                        previousPendingOps = currentPendingOps;
                        break;

                    default:
                        Debug.Assert(false);
                        return;
                    }
                }
            }
            catch
            {
                if (current.Transaction != null)
                {
                    _recording.State?.Record(current, TxInstruction.DisposeTx, current.Transaction.Disposed == false);
                    current.Transaction.Dispose();
                }
                currentReturnContext?.Dispose();
                throw;
            }
        }
        private void MergeTransactionsWithAsyncCommit(
            DocumentsOperationContext context,
            List <MergedTransactionCommand> previousPendingOps)
        {
            var previous = context.Transaction;

            try
            {
                while (true)
                {
                    if (_log.IsInfoEnabled)
                    {
                        _log.Info($"BeginAsyncCommit on {previous.InnerTransaction.LowLevelTransaction.Id} with {_operations.Count} additional operations pending");
                    }

                    CommitStats commitStats = null;
                    try
                    {
                        previous.InnerTransaction.LowLevelTransaction.RetrieveCommitStats(out commitStats);
                        context.Transaction = previous.BeginAsyncCommitAndStartNewTransaction();
                    }
                    catch (Exception e)
                    {
                        foreach (var op in previousPendingOps)
                        {
                            op.Exception = e;
                        }
                        NotifyOnThreadPool(previousPendingOps);

                        if (e is OutOfMemoryException)
                        {
                            try
                            {
                                //already throwing, attempt to complete previous tx
                                CompletePreviousTransaction(previous, commitStats, ref previousPendingOps, throwOnError: false);
                            }
                            finally
                            {
                                context.Transaction?.Dispose();
                            }
                        }

                        return;
                    }
                    try
                    {
                        var currentPendingOps = GetBufferForPendingOps();
                        PendingOperations result;
                        bool calledCompletePreviousTx = false;
                        try
                        {
                            var transactionMeter = TransactionPerformanceMetrics.MeterPerformanceRate();
                            try
                            {
                                result = ExecutePendingOperationsInTransaction(
                                    currentPendingOps, context,
                                    previous.InnerTransaction.LowLevelTransaction.AsyncCommit, ref transactionMeter);
                                UpdateGlobalReplicationInfoBeforeCommit(context);
                            }
                            finally
                            {
                                transactionMeter.Dispose();
                            }
                            calledCompletePreviousTx = true;
                            CompletePreviousTransaction(previous, commitStats, ref previousPendingOps, throwOnError: true);
                        }
                        catch (Exception e)
                        {
                            if (_log.IsInfoEnabled)
                            {
                                _log.Info(
                                    $"Failed to run merged transaction with {currentPendingOps.Count:#,#0} operations in async manner, will retry independently",
                                    e);
                            }
                            using (previous)
                                using (context.Transaction)
                                {
                                    if (calledCompletePreviousTx == false)
                                    {
                                        CompletePreviousTransaction(previous,
                                                                    commitStats,
                                                                    ref previousPendingOps,
                                                                    // if this previous threw, it won't throw again
                                                                    throwOnError: false);
                                    }
                                    else
                                    {
                                        throw;
                                    }
                                }
                            NotifyTransactionFailureAndRerunIndependently(currentPendingOps, e);
                            return;
                        }
                        previous.Dispose();

                        switch (result)
                        {
                        case PendingOperations.CompletedAll:
                            try
                            {
                                context.Transaction.InnerTransaction.LowLevelTransaction.RetrieveCommitStats(out var stats);
                                context.Transaction.Commit();
                                SlowWriteNotification.Notify(stats, _parent);
                                context.Transaction.Dispose();
                            }
                            catch (Exception e)
                            {
                                foreach (var op in currentPendingOps)
                                {
                                    op.Exception = e;
                                }
                            }
                            NotifyOnThreadPool(currentPendingOps);
                            return;

                        case PendingOperations.HasMore:
                            previousPendingOps  = currentPendingOps;
                            previous            = context.Transaction;
                            context.Transaction = null;
                            break;

                        default:
                            Debug.Assert(false);
                            return;
                        }
                    }
                    finally
                    {
                        context.Transaction?.Dispose();
                    }
                }
            }
            finally
            {
                previous.Dispose();
            }
        }