Exemple #1
0
        public SimulationManager(string marker, int run, WorkshiftsCM workshiftsCM, TicketGenerationPlan plan, int daysToSimulate)
        {
            this.marker         = marker;
            this.run            = run;
            this.workshiftsCM   = workshiftsCM;
            this.plan           = plan;
            this.daysToSimulate = daysToSimulate;

            // Init Basic Tickers
            var shiftManager = new ShiftManagerTicker(this, workshiftsCM, inputQueue, doneQueue, Accounting);

            shiftManager.LogEvent += ShiftManager_LogEvent;
            Add(shiftManager);
            Add(new NewTicketTicker(plan, inputQueue));

            // Needed for Grafana
            unixTimestamp = (Int32)((DateTimeOffset)DateTime.Today.ToUniversalTime()).ToUnixTimeSeconds();
        }
Exemple #2
0
 public NewTicketTicker(TicketGenerationPlan plan, MultiLevelTicketQueue inputQueue)
 {
     tickets         = plan.Tickets.OrderBy(t => t.createAtTicks).ToList();
     this.inputQueue = inputQueue;
 }
Exemple #3
0
        public int Run()
        {
            init();

            if (UseDatabase)
            {
                ConnectDb();
            }
            else if (TruncateFirst || DropAndCreateFirst || ClearTablesForMarker)
            {
                Print("You cannot do any data operations without --usedb");
                return(1);
            }


            EmployeeTypesCM employeeTypesCM = new EmployeeTypesCM();

            employeeTypesCM.Load(EmployeeTypesFilename);

            WorkshiftsCM workshifts = new WorkshiftsCM(employeeTypesCM);

            workshifts.Load(WorkshiftsFilename);

            TicketGenerationPlan ticketGenerationPlan = new TicketGenerationPlan();

            ticketGenerationPlan.Load(TicketGenerationPlan);

            Print("All files loaded");

            Print(string.Format("Total tickets: {0}", ticketGenerationPlan.TotalTickets));

            if (Days == null)
            {
                Days = ticketGenerationPlan.NumberOfDays;
                Print("Found {0} days in ticket plan", Days);
            }

            int run = 0;

            if (UseDatabase)
            {
                if (DropAndCreateFirst)
                {
                    DropTables(true);
                    CreateTables();
                }
                if (TruncateFirst)
                {
                    TruncateTables();
                }

                if (ClearTablesForMarker)
                {
                    Print("Deleted old datapoints (if exists) ({0})", DeleteDatapointsForMarker(Name));
                    Print("Deleted old summary (if exists) ({0})", DeleteSummariesForMarker(Name));
                }

                var getRunNumberCmd = new MySqlCommand(string.Format("select ifnull(max(run),0) as max from datapoints where marker=@Marker", Statics.TableSummaries), conn);
                getRunNumberCmd.Parameters.Add("@Marker", MySqlDbType.VarChar).Value = Name;
                using (var getRunNumberCmdReader = getRunNumberCmd.ExecuteReader())
                {
                    getRunNumberCmdReader.Read();
                    run = getRunNumberCmdReader.GetInt32("max") + 1;
                }
                Print("Run number {0}", run);
            }

            SimulationManager sm = new SimulationManager(Name, run, workshifts, ticketGenerationPlan, Days.Value);

            if (UseDatabase)
            {
                sm.NewDatapoint += Sm_NewDatapoint;
            }

            if (Debug)
            {
                sm.LogEvent += Print;
            }

            sm.Run();


            if (UseDatabase)
            {
                Print("Inserting {0} datapoints into db if connected", datapoints.Count);
                int inserts = 0;
                if (datapoints.Count > 0)
                {
                    inserts += InternalMySqlHelper.GetBulkInsert(conn, "datapoints", datapoints.ToArray()).ExecuteNonQuery();
                }
                Print("Inserts: {0}", inserts);
            }


            List <TicketEntity> tickets = ticketGenerationPlan.Tickets;

            SimulationSummary ss = new SimulationSummary(
                Name,
                run,
                tickets.Where(t => t.Solved).Count(),
                tickets.Where(t => t.Deployed).Count(),
                tickets.Where(t => t.Started).Count(),
                tickets.Count(),
                tickets.Where(t => !t.Solved && t.Difficulty == Models.SupportLevel.Level1st).Count(),
                tickets.Where(t => !t.Solved && t.Difficulty == Models.SupportLevel.Level2nd).Count(),
                tickets.Where(t => t.Solved).Any() ? tickets.Where(t => t.Solved).Average(i => i.Duration) : 0,
                sm.Accounting.TotalExpenses,
                sm.Accounting.TotalWorkingHours,
                sm.Accounting.TotalWorkingHours != 0? sm.Accounting.TotalExpenses / sm.Accounting.TotalWorkingHours : 0,
                tickets.Where(t => !t.Solved).Count()
                );

            if (UseDatabase)
            {
                var summaryInsert = InternalMySqlHelper.GetInsert(conn, TablePrefix + Statics.TableSummaries, ss);
                Print("Insert summary ({0})", summaryInsert.ExecuteNonQuery());
            }

            Print("Solved tickets: {0}/{1}", ss.SolvedTickets, ss.TotalTickets);
            Print("Deployed tickets: {0} ", ss.DeployedTickets);
            Print("Started tickets: {0} ", ss.StartedTickets);
            Print("Open 1st level tickets: {0} ", ss.Open1stLevelTickets);
            Print("Open 2nd level tickets: {0} ", ss.Open2ndLevelTickets);
            Print("Average Duration: {0} ", ss.AverageTicketSolveDuration);
            Print("Total Costs: {0:C} ", ss.TotalCosts);
            Print("Total Costs: {0:#,##0} h ", ss.TotalCosts);
            Print("Average hourly wage: {0:C}", ss.AverageHourlyWage);

            return(0);
        }
Exemple #4
0
        public int Run()
        {
            init();

            var distributioGenerator = new TicketsPerDayDistributionGenerator();

            distributioGenerator.Load(TicketsPerDayDistributionFileName);

            var g = new Normal(NumOfTickets, NumOfTickets / 100);

            var ticketsPerNDay = new TicketsPerNDays();

            for (int day = 0; day < DaysToGenerate; day++)
            {
                int ticketsForThatDay = (int)g.Sample();
                for (int h = 0; h < TicketsPerDayDistributionGenerator.HOURS_PER_DAY; h++)
                {
                    var hourDist       = Decimal.ToDouble(distributioGenerator.Get(h)) / 100;
                    var gHourDist      = new Normal(hourDist, hourDist >= 1 ? 0.1 : hourDist / 100);
                    var ticketsForHour = gHourDist.Sample() * ticketsForThatDay;
                    ticketsPerNDay.Set(day, h, (int)ticketsForHour);
                }
            }

            ticketsPerNDay.Save(FilenameTicketDistribution);

            Print("Generated Tickets per n day file");

            int ticketNumber = 0;
            int ticks        = 0;

            var gSupportLevel = new Normal(BoundaryConditions.LevelDistributionFactor, 1);

            TicketGenerationPlan tge = new TicketGenerationPlan();

            for (int day = 0; day < DaysToGenerate; day++)
            {
                for (int h = 0; h < TicketsPerDayDistributionGenerator.HOURS_PER_DAY; h++)
                {
                    var ticketsToSolve = ticketsPerNDay.Get(day, h);
                    for (int t = 0; t < ticketsToSolve; t++)
                    {
                        var time         = ticks + ((double)t / (double)ticketsToSolve) * (double)60;
                        var supportLevel = SupportLevel.Level1st;
                        if (gSupportLevel.Sample() >= 2)
                        {
                            supportLevel = SupportLevel.Level2nd;
                        }
                        var ticket = new TicketEntity(ticketNumber, supportLevel, GetLevelDifficulties(), (int)time);
                        tge.Tickets.Add(ticket);
                        ticketNumber++;
                    }
                    ticks += 60;
                }
            }

            var avg1StLevel          = tge.Tickets.Average(i => i.DifficultyToSolveDurationMin[SupportLevel.Level1st]);
            var avg2ndLevel          = tge.Tickets.Average(i => i.DifficultyToSolveDurationMin[SupportLevel.Level2nd]);
            var numOf1stLevel        = tge.Tickets.Count(i => i.Difficulty == SupportLevel.Level1st);
            var numOf2ndLevel        = tge.Tickets.Count(i => i.Difficulty == SupportLevel.Level2nd);
            var percentageOf1stLevel = (double)numOf1stLevel / (double)(numOf1stLevel + numOf2ndLevel) * 100;

            Console.WriteLine("Avg 1st: {0:0.00} ticks 2nd: {1:0.00} ticks Tickets: 1st: {2:0.00} ({3:0.00}%) 2nd: {4:0.00}",
                              avg1StLevel,
                              avg2ndLevel,
                              numOf1stLevel,
                              percentageOf1stLevel,
                              numOf2ndLevel);

            tge.Save(FilenameTicketGeneration);

            return(0);
        }