コード例 #1
0
ファイル: Runner.cs プロジェクト: KonsN/SQL-Replay
        private async Task RunEventsAsync(Run run)
        {
            var config = new ConfigurationBuilder()
                         .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                         .Build();

            IRunnerSettings runnerSettings = config.GetSection(nameof(RunnerSettings)).Get <RunnerSettings>();

            Console.WriteLine("Warming up thread pool...");

            System.Threading.ThreadPool.SetMaxThreads(32767, 32767);
            System.Threading.ThreadPool.SetMinThreads(32767, 32767);

            Console.WriteLine("Nesting events...");

            //Remove any sessions with no events
            run.Sessions.RemoveAll(s => s.Events.Count == 0);
            foreach (Session session in run.Sessions)
            {
                var         nestedEvents      = new List <Event>();
                Transaction parentTransaction = null;
                foreach (Event evt in session.Events)
                {
                    if (parentTransaction != null && evt.TransactionId != "0")
                    {
                        parentTransaction.Events.Add(evt);
                    }
                    else
                    {
                        nestedEvents.Add(evt);
                    }
                    if (evt is Transaction transaction)
                    {
                        switch (transaction.TransactionState)
                        {
                        case "Begin":
                            parentTransaction = transaction;
                            break;

                        case "Commit":
                        case "Rollback":
                            parentTransaction = session.Events
                                                .Where(e => ((e as Transaction)?.Events.Contains(parentTransaction)).GetValueOrDefault())
                                                .SingleOrDefault() as Transaction;
                            break;
                        }
                    }
                }
                session.Events = nestedEvents;
            }

            Console.WriteLine("Preparing 15 second buckets of sessions...");

            var buckets = run.Sessions.GroupBy(s =>
            {
                Event firstEvt = s.Events.First();
                return(firstEvt.Timestamp.ToString("ddHHmm") + firstEvt.Timestamp.Second / runnerSettings.BucketInterval);
            })
                          .OrderBy(g => g.Key)
                          .Select(g => g.OrderBy(s => s.Events.First().Timestamp)
                                  .ToList()
                                  ).ToList();

            Console.WriteLine("Kicking off executions...");

            var tasks         = new List <Task>();
            var eventExecutor = new EventExecutor();
            var replayOrigin  = DateTimeOffset.UtcNow;

            foreach (var bucket in buckets)
            {
                var      bucketTimestamp = bucket.First().Events.First().Timestamp;
                TimeSpan timeToDelay     = bucketTimestamp.Subtract(run.EventCaptureOrigin).Subtract(DateTimeOffset.UtcNow.Subtract(replayOrigin));
                if (timeToDelay.TotalMilliseconds > 0)
                {
                    await Task.Delay(timeToDelay);
                }
                Console.WriteLine("Starting bucket: " + bucketTimestamp);
                tasks.Add(eventExecutor.ExecuteSessionEventsAsync(run.EventCaptureOrigin, replayOrigin, bucket, run.ConnectionString, runnerSettings));
                Console.WriteLine("Ending Delay: " + bucketTimestamp);
            }

            Console.WriteLine("Waiting for unfinished executions to complete...");
            await Task.WhenAll(tasks);

            Console.WriteLine("Executions complete.");
            this.Exceptions.AddRange(eventExecutor.Exceptions);
        }
コード例 #2
0
ファイル: Runner.cs プロジェクト: KonsN/SQL-Replay
        public Task RunAsync(Run run, DateTimeOffset restorePoint, int durationInMinutes, string[] storedProcedureNamesToExclude)
        {
            var matchCriteria = StoredProcedureSearch.CreateMatchCriteria(storedProcedureNamesToExclude);

            if (matchCriteria.Any())
            {
                if (durationInMinutes > 0)
                {
                    foreach (var session in run.Sessions)
                    {
                        session.Events.RemoveAll(e => !(!matchCriteria.Any(mc =>
                                                                           ((e as Rpc)?.Procedure?.Equals(mc, StringComparison.CurrentCultureIgnoreCase))
                                                                           .GetValueOrDefault()) &&
                                                        e.Timestamp > restorePoint &&
                                                        e.Timestamp < run.EventCaptureOrigin.AddMinutes(durationInMinutes)));
                    }
                }
                else
                {
                    foreach (var session in run.Sessions)
                    {
                        session.Events.RemoveAll(e => !(!matchCriteria.Any(mc =>
                                                                           ((e as Rpc)?.Procedure?.Equals(mc, StringComparison.CurrentCultureIgnoreCase))
                                                                           .GetValueOrDefault()) &&
                                                        e.Timestamp > restorePoint));
                    }
                }
            }
            else
            {
                if (durationInMinutes > 0)
                {
                    foreach (var session in run.Sessions)
                    {
                        session.Events.RemoveAll(e => !(e.Timestamp > restorePoint &&
                                                        e.Timestamp < run.EventCaptureOrigin.AddMinutes(durationInMinutes)));
                    }
                }
                else
                {
                    foreach (var session in run.Sessions)
                    {
                        session.Events.RemoveAll(e => !(e.Timestamp > restorePoint));
                    }
                }
            }
            foreach (var session in run.Sessions)
            {
                session.Events.RemoveAll(e =>
                {
                    if (e is Rpc rpc)
                    {
                        return(rpc.Statement.Contains("OPENROWSET", StringComparison.CurrentCultureIgnoreCase) ||
                               rpc.Statement.Contains("OPENDATASOURCE", StringComparison.CurrentCultureIgnoreCase));
                    }
                    return(false);
                });
            }
            run.EventCaptureOrigin = restorePoint;
            return(RunEventsAsync(run));
        }
コード例 #3
0
        public async Task Run(Run run)
        {
            //Prepare threads in thread pool
            System.Threading.ThreadPool.SetMaxThreads(32767, 32767);
            System.Threading.ThreadPool.SetMinThreads(32767, 32767);

            Console.WriteLine("Preparing 15 second buckets...");

            //DuplicateEvents(run, 4); //synthetically increase load

            //var matchCriteria = new List<string>()
            //{
            //    "something I want to exclude"
            //};

            var allEvents = run.Sessions.SelectMany(s => s.Events)
                            //.Where(e => !matchCriteria.Any(mc => ((e as Rpc)?.ObjectName.Contains(mc, StringComparison.CurrentCultureIgnoreCase)).GetValueOrDefault())) //leave these out
                            .ToList();

            var allDependentEvents   = allEvents.Where(e => e.TransactionId != "0" && ((e is Rpc) || (e as Transaction)?.TransactionState != "Begin")).ToList();
            var allIndependentEvents = allEvents.Where(e => e.TransactionId == "0" || (e as Transaction)?.TransactionState == "Begin");

            var groups  = allIndependentEvents.GroupBy(r => r.Timestamp.ToString("ddhhmm") + r.Timestamp.Second / 15).OrderBy(g => g.Key);
            var buckets = new Dictionary <string, List <Event> >();

            foreach (var group in groups)
            {
                var trxStarts = group.Where(e => e.TransactionId != "0").Select(e => (e as Transaction)).ToList();
                var startHash = new HashSet <string>(trxStarts.Select(x => x.TransactionId));
                var startDict = new Dictionary <string, Transaction>();
                foreach (var trx in trxStarts)
                {
                    trx.Events = new List <Event>();
                    startDict.Add(trx.TransactionId, trx);
                }

                var bucket = new List <Event>(group);

                foreach (var evt in allDependentEvents)
                {
                    if (startHash.Contains(evt.TransactionId))
                    {
                        startDict[evt.TransactionId].Events.Add(evt);
                    }
                }

                foreach (var trx in trxStarts)
                {
                    trx.Events = trx.Events.OrderBy(e => e.EventSequence).ToList();
                    //Avoid stragglers at end of trace that don't include a commit or rollback
                    if (!trx.Events.Any(e => (e as Transaction)?.TransactionState == "Commit" ||
                                        (e as Transaction)?.TransactionState == "Rollback"))
                    {
                        Event model;
                        if (trx.Events.Count > 0)
                        {
                            model = trx.Events.Last();
                        }
                        else
                        {
                            model = trx;
                        }
                        trx.Events.Add(new Transaction
                        {
                            TransactionId    = model.TransactionId,
                            TransactionState = "Commit",
                            EventSequence    = (int.Parse(model.EventSequence) + 1).ToString(),
                            Timestamp        = model.Timestamp.AddMilliseconds(100)
                        });
                    }
                }

                buckets.Add(group.Key, bucket);
            }

            var bucketEvents = buckets.SelectMany(b => b.Value.Select(e => e));
            var orphanEvents = allEvents.Except(bucketEvents);

            foreach (var evt in orphanEvents)
            {
                string key = evt.Timestamp.ToString("ddhhmm") + evt.Timestamp.Second / 15;
                if (buckets.TryGetValue(key, out var events))
                {
                    events.Add(evt);
                }
                else
                {
                    buckets.Add(key, new List <Event> {
                        evt
                    });
                }
            }
            var orderedBuckets = buckets.OrderBy(b => b.Key).Select(b => b.Value.OrderBy(e => e.Timestamp).ToList()).ToList();

            Console.WriteLine("Kicking off executions...");

            List <Task>    tasks         = new List <Task>();
            var            eventExecutor = new EventExecutor();
            DateTimeOffset replayOrigin  = DateTimeOffset.UtcNow;

            foreach (var bucket in orderedBuckets)
            {
                Console.WriteLine("Starting bucket: " + bucket[0].Timestamp);
                tasks.Add(eventExecutor.ExecuteEvents(run.EventCaptureOrigin, replayOrigin, bucket, run.ConnectionString));
                await Task.Delay(15000);

                Console.WriteLine("Ending Delay: " + bucket[0].Timestamp);
            }

            Console.WriteLine("Waiting for unfinished executions to complete...");
            await Task.WhenAll(tasks);

            Console.WriteLine("Executions complete.");
            this.Exceptions.AddRange(eventExecutor.Exceptions);
        }