Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-57997

Performance plugin parses the same file multiple times

    Details

    • Similar Issues:

      Description

      In some cases, the Performance plugin parses the same CSV files of the same build multiple times, even if has been already parsed. This causes the UI halting and not able to show any data, until all of them get parsed multiple times, which takes extremely long time.

      The way I reproduce it is to run the same build again and again without delay (performance reporting of large csv files, but without testing), like below pipeline snippet:

      //A CSV file named report.csv is firstly created with large dataset

      perfReport report.csv

      When the multiple builds are being run, keep the job's UI page open in one browser.

      After several builds, the job's UI page is halting and there is no performance report showed, unless after an extremely long time.

      From the Jenkins log, I can see the same report gets parsed again and again.

      For example, after building #67, #68 & #69, below is the Jenkins log:

      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/69/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/68/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/68/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/68/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/68/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/69/performance-reports/JMeterCSV/full_report' with filterRegex 'null'.
      Performance: Parsing report file '/local/jenkins/jobs/loadtest/builds/67/performance-reports/JMeterCSV/full_report' with filterRegex 'null'. 

      Two work-arounds:

      1. Make sure the Jenkins job UI page is not opened in any browsers when multiple builds are being run without delay. It seems like the parsing is triggered from UI request, and if the job UI page is opened, and the build only contains one report each, it will request the performance report and trigger Jenkins to parse the logs every time a new build is run.
      2. Restart the Jenkins after multiple builds have been performed, then run only one more new build. After that, the plugin parses all builds which have not been parsed yet only once, but not multiple times.

       

       

        Attachments

          Activity

          Hide
          goldyliang Goldy Liang added a comment -

          In AbstractParser.parse, it tries to load the report from file/cache, and if not parsed yet, run the parser.

          I think this can be synchronized by file name, so that if thread A is already trying to parse, the other thread B won't try doing that again, but just wait for the thread A finishes.

          Show
          goldyliang Goldy Liang added a comment - In AbstractParser.parse, it tries to load the report from file/cache, and if not parsed yet, run the parser. I think this can be synchronized by file name, so that if thread A is already trying to parse, the other thread B won't try doing that again, but just wait for the thread A finishes.
          Hide
          goldyliang Goldy Liang added a comment -

          It turns out that there is a silly bug in the AbstractParser.loadSerializedReport:

          {{ protected static PerformanceReport loadSerializedReport(File reportFile) {}}

              ....

              PerformanceReport report = CACHE.getIfPresent(serialized);
              if (report == null && file.exists() && file.canRead()) {
                 ...

                 report = (PerformanceReport) in.readObject();
                 CACHE.put(serialized, report);
                 return report;
                  ...

          }
                  // It returns null, which shall be a mistake.
              return null;//Shall return report
          {{ }}}

          Because of this bug, the log is re-parsed if the in-memory cache has been created.

          I compiled a fix as above, and it works fine then.

           

          Show
          goldyliang Goldy Liang added a comment - It turns out that there is a silly bug in the AbstractParser.loadSerializedReport: {{ protected static PerformanceReport loadSerializedReport(File reportFile) {}}     ....     PerformanceReport report = CACHE.getIfPresent(serialized);     if (report == null && file.exists() && file.canRead()) {        ...        report = (PerformanceReport) in.readObject();        CACHE.put(serialized, report);        return report;         ... }         // It returns null, which shall be a mistake.     return null; //Shall return report {{ }}} Because of this bug, the log is re-parsed if the in-memory cache has been created. I compiled a fix as above, and it works fine then.  
          Hide
          goldyliang Goldy Liang added a comment -

          It turned out that the same fix as pull request have been sitting there: https://github.com/jenkinsci/performance-plugin/pull/188

           

          Show
          goldyliang Goldy Liang added a comment - It turned out that the same fix as pull request have been sitting there: https://github.com/jenkinsci/performance-plugin/pull/188  
          Hide
          artem_fedorov Artem Fedorov added a comment -

          Fixed in 3.17

          Show
          artem_fedorov Artem Fedorov added a comment - Fixed in 3.17

            People

            • Assignee:
              artem_fedorov Artem Fedorov
              Reporter:
              goldyliang Goldy Liang
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: