Bug 1214437

Summary: Slow System Overview page when systems have lots of unscheduled errata
Product: [Community] Spacewalk Reporter: Stephen Herr <sherr>
Component: WebUIAssignee: Stephen Herr <sherr>
Status: CLOSED CURRENTRELEASE QA Contact: Red Hat Satellite QA List <satqe-list>
Severity: medium Docs Contact:
Priority: medium    
Version: 2.3CC: jdobes, jentrena, satqe-list, tlestach, tpapaioa, xdmoon
Target Milestone: ---Keywords: Patch
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: spacewalk-java-2.4.7-1 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 1207816 Environment:
Last Closed: 2015-10-08 13:26:35 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1207816    
Bug Blocks: 1267654    

Description Stephen Herr 2015-04-22 17:39:00 UTC
+++ This bug was initially created as a clone of Bug #1207816 +++

Description of problem:

The System Overview page in the Satellite web UI can take a long time (~2 minutes) to load, when the systems have a large number of unscheduled errata. For example, on a Satellite with 84 systems, where 37 of them have over 1,000 available but unscheduled errata, the page takes 154 seconds to load (with session timeouts increased to avoid Internal Server Errors). 103 of those 154 seconds are spent creating instances of the com.redhat.rhn.domain.errata.impl.PublishedErrata class that are never actually used. The problem is in the query used:

****
./java/code/src/com/redhat/rhn/manager/system/SystemManager.java:

    public static boolean hasUnscheduledErrata(User user, Long sid) {
        SelectMode m = ModeFactory.getMode("Errata_queries",
                "unscheduled_relevant_to_system");
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("user_id", user.getId());
        params.put("sid", sid);
        DataResult dr = m.execute(params);
        return !dr.isEmpty();   <--- returns True or False, depending on whether there are any unscheduled errata for the system
    }

./java/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml:

<mode name="unscheduled_relevant_to_system" class="com.redhat.rhn.domain.errata.impl.PublishedErrata">
  <query params="user_id, sid">
SELECT DISTINCT E.id, E.update_date
  FROM rhnErrata E,
       rhnServerNeededPackageCache SNPC
 WHERE EXISTS (SELECT server_id FROM rhnUserServerPerms USP WHERE USP.user_id = :user_id AND USP.server_id = :sid)
   AND SNPC.server_id = :sid
   AND SNPC.errata_id = E.id
   AND NOT EXISTS (SELECT SA.server_id
                     FROM rhnActionErrataUpdate AEU,
                          rhnServerAction SA,
                          rhnActionStatus AST
                    WHERE SA.server_id = :sid
                      AND SA.status = AST.id
                      AND AST.name IN('Queued', 'Picked Up')
                      AND AEU.action_id = SA.action_id
                      AND AEU.errata_id = E.id )
ORDER BY E.update_date, E.id
  </query>
  <elaborator name="published_overview" params="">
    SELECT  E.id, E.advisory, E.advisory_name, E.advisory_type, E.update_date, E.synopsis
    FROM  rhnErrata E
    WHERE  E.id IN (%s)
    ORDER BY  E.update_date DESC
  </elaborator>
</mode>
****

unscheduled_relevant_to_system creates a class instance for each errata record returned by the query, but SystemManager.hasUnscheduledErrata() simply checks whether the result is empty, and does not use these instances. 

Version-Release number of selected component (if applicable):

spacewalk-java-2.3.8-100.el6sat.noarch

How reproducible:

100%

Steps to Reproduce:
1.) Register a RHEL 6.0 system ~50 times, subscribing it to the rhel-x86_64-server-6 base channel.
2.) Navigate to the System Overview page.
3.) Notice the slow page load.

Actual results:

Slow System Overview page load when systems have many available errata.

Expected results:

Not-so-slow page load.

Additional info:


unscheduled_relevant_to_system is used in other code that needs the errata objects, so creating a second query that returns only the total errata count may be required to fix this. In my testing, the following patch resolved the issue:

# diff -pruN java/code/src/com/redhat/rhn/manager/system/SystemManager.java.bak java/code/src/com/redhat/rhn/manager/system/SystemManager.java
--- java/code/src/com/redhat/rhn/manager/system/SystemManager.java.bak	2015-03-31 14:51:17.984634294 -0400
+++ java/code/src/com/redhat/rhn/manager/system/SystemManager.java	2015-03-31 14:51:58.354443219 -0400
@@ -943,12 +943,13 @@ public class SystemManager extends BaseM
      */
     public static boolean hasUnscheduledErrata(User user, Long sid) {
         SelectMode m = ModeFactory.getMode("Errata_queries",
-                "unscheduled_relevant_to_system");
+                "count_unscheduled_relevant_to_system");
         Map<String, Object> params = new HashMap<String, Object>();
         params.put("user_id", user.getId());
         params.put("sid", sid);
-        DataResult dr = m.execute(params);
-        return !dr.isEmpty();
+        DataResult<Map<String, Object>> dr = makeDataResult(params, null, null, m);
+        return ((Long) dr.get(0).get("count")).intValue() > 0;
+
     }
 
     /**

# diff -pruN java/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml.bak java/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml
--- java/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml.bak	2015-03-31 14:53:28.367017151 -0400
+++ java/code/src/com/redhat/rhn/common/db/datasource/xml/Errata_queries.xml	2015-03-31 14:53:43.854943835 -0400
@@ -301,6 +301,26 @@ ORDER BY E.update_date, E.id
   </elaborator>
 </mode>
 
+<mode name="count_unscheduled_relevant_to_system">
+  <query params="user_id, sid">
+ SELECT COUNT(DISTINCT E.id) AS COUNT
+   FROM rhnErrata E,
+        rhnServerNeededPackageCache SNPC
+  WHERE EXISTS (SELECT server_id FROM rhnUserServerPerms USP WHERE USP.user_id = :user_id AND USP.server_id = :sid)
+    AND SNPC.server_id = :sid
+    AND SNPC.errata_id = E.id
+    AND NOT EXISTS (SELECT SA.server_id
+                      FROM rhnActionErrataUpdate AEU,
+                           rhnServerAction SA,
+                           rhnActionStatus AST
+                     WHERE SA.server_id = :sid
+                       AND SA.status = AST.id
+                       AND AST.name IN('Queued', 'Picked Up')
+                       AND AEU.action_id = SA.action_id
+                       AND AEU.errata_id = E.id )
+  </query>
+</mode>
+
 <mode name="issued_between">
   <query params="start_date_str, end_date_str">
 SELECT DISTINCT

--- Additional comment from Jan Dobes on 2015-04-02 07:33:24 EDT ---

see also bz1205328 where is now used select from rhnServerNeededErrataCache instead of rhnServerNeededPackageCache

--- Additional comment from Stephen Herr on 2015-04-22 13:36:18 EDT ---

Thanks as always for the excellent investigation and patch Tasos.

I approve the patch (after making the rhnServerNeededPackageCache -> rhnServerNeededErrataCache change that Jan pointed out) and verify that it improves the loading speed of that page (50 rhel 6.0 server subscribed to rhel channel, 27s page load before the patch, ~4s after) (local SSD hard drives are fast).

Comment 1 Stephen Herr 2015-04-22 17:48:21 UTC
Committing to Spacewalk master:
3c0b39d7f78ba35499934b96917d119725754533

Comment 2 Tomas Lestach 2015-09-09 11:56:31 UTC
Making the BZ public ...

Comment 3 Jan Dobes 2015-10-08 13:26:35 UTC
Spacewalk 2.4 has been released.