Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #6059: Graphes in home page take ages to display #755

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
*************************************************************************************
* Copyright 2012 Normation SAS
*************************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* In accordance with the terms of section 7 (7. Additional Terms.) of
* the GNU Affero GPL v3, the copyright holders add the following
* Additional permissions:
* Notwithstanding to the terms of section 5 (5. Conveying Modified Source
* Versions) and 6 (6. Conveying Non-Source Forms.) of the GNU Affero GPL v3
* licence, when you create a Related Module, this Related Module is
* not considered as a part of the work and may be distributed under the
* license agreement of your choice.
* A "Related Module" means a set of sources files including their
* documentation that, without modification of the Source Code, enables
* supplementary functions or services in addition to those offered by
* the Software.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/agpl.html>.
*
*************************************************************************************
*/

package com.normation.rudder.domain.logger

import org.slf4j.LoggerFactory
import net.liftweb.common.Logger

/**
* Applicative log of interest for Rudder ops.
*/
object TimingDebugLogger extends Logger {
override protected def _logger = LoggerFactory.getLogger("debug_timing")
}


Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import com.normation.rudder.repository.ldap.LDAPEntityMapper
import com.normation.utils.Control._
import com.normation.inventory.ldap.core.InventoryMapper
import com.normation.inventory.ldap.core.InventoryDitService
import com.normation.rudder.domain.logger.TimingDebugLogger

/**
* A case class used to represent the minimal
Expand Down Expand Up @@ -185,26 +186,42 @@ class NodeInfoServiceImpl(
* query for far too many entries (in machine) compared to do lots
* of requests.
*/
import scala.collection.mutable.{Map => MutMap}

ldap.map { con =>
val allNodes = con.searchOne(nodeDit.NODES.dn, ALL, nodeInfoAttributes:_*).flatMap { node =>
nodeDit.NODES.NODE.idFromDn(node.dn).map { (_, node) }

//some map of things - mutable, yes
val nodes = MutMap[String, LDAPEntry]() //node_uuid -> entry
val nodeInventories = MutMap[String, LDAPEntry]() // node_uuid -> entry
val machineInventories = MutMap[String, LDAPEntry]() // machine_dn -> entry

val n1 = System.currentTimeMillis
con.search(
nodeDit.BASE_DN
, Sub
, OR(IS(OC_MACHINE), IS(OC_NODE), IS(OC_RUDDER_NODE))
, nodeInfoAttributes:_*
).foreach { e =>
if(e.isA(OC_MACHINE)) {
machineInventories += (e.dn.toString -> e)
} else if(e.isA(OC_NODE)) {
nodeInventories += (e.value_!(A_NODE_UUID) -> e)
} else if(e.isA(OC_RUDDER_NODE)) {
nodes += (e.value_!(A_NODE_UUID) -> e)
} else {
// it's an error, don't use
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will you have also the policy server with this ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

}
}
val allNodeInventories = con.searchOne(inventoryDit.NODES.dn, ALL, nodeInfoAttributes:_*).flatMap { nodeInv =>
inventoryDit.NODES.NODE.idFromDN(nodeInv.dn).map{ (_, nodeInv) }
}.toMap

//we must look in ou=Inventories,cn=rudder-configuration
//because we don't know what the machine inventory status will be
//and we only need objectClass
val allMachineInventories = con.searchSub(inventoryDit.BASE_DN.getParent, IS(OC_MACHINE), Seq("objectClass"):_*).map( machine => (machine.dn, machine) ).toMap
val n2 = System.currentTimeMillis
TimingDebugLogger.debug(s"Getting node info entries: ${n2-n1}ms")

allNodes.flatMap { case (id, nodeEntry) =>
nodes.flatMap { case (id, nodeEntry) =>
for {
nodeInv <- allNodeInventories.get(id)
nodeInv <- nodeInventories.get(id)
machineInv = for {
containerDn <- nodeInv(A_CONTAINER_DN)
machineEntry <- allMachineInventories.get(containerDn)
machineEntry <- machineInventories.get(containerDn)
} yield {
machineEntry
}
Expand All @@ -216,46 +233,9 @@ class NodeInfoServiceImpl(
}
}

def find(nodeIds: Seq[NodeId]) : Box[Seq[NodeInfo]] = {
sequence(nodeIds) { nodeId =>
getNodeInfo(nodeId)
}
}

/**
* Get all node ids
*/
def getAllIds() : Box[Seq[NodeId]] = {
for {
con <- ldap
nodeIds <- sequence(con.searchOne(nodeDit.NODES.dn, IS(OC_RUDDER_NODE), "1.1")) { entry =>
nodeDit.NODES.NODE.idFromDn(entry.dn)
}
} yield {
nodeIds
}
}

/**
* Get all "simple" node ids (i.e, all user nodes,
* for example, NOT policy servers)
*/
def getAllUserNodeIds() : Box[Seq[NodeId]] = {
for {
con <- ldap
nodeIds <- sequence(con.searchOne(nodeDit.NODES.dn, AND(IS(OC_RUDDER_NODE), NOT(IS(OC_POLICY_SERVER_NODE))), "1.1")) { entry =>
nodeDit.NODES.NODE.idFromDn(entry.dn)
}
} yield {
nodeIds
}
}

/**
* Get all systen node ids, for example
* policy server node ids.
* @return
*/
/**
* Get all policy server node ids.
*/
def getAllSystemNodeIds() : Box[Seq[NodeId]] = {
for {
con <- ldap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ object RudderConfig extends Loggable {
val woAgentRunsRepository : WoReportsExecutionRepository = woAgentRunsSquerylRepository

val inMemoryChangeRequestRepository : InMemoryChangeRequestRepository = new InMemoryChangeRequestRepository
val ldapInventoryMapper = inventoryMapper

val roChangeRequestRepository : RoChangeRequestRepository = {
//a runtime checking of the workflow to use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import bootstrap.liftweb.RudderConfig
import com.normation.rudder.web.components.DateFormaterService
import com.normation.rudder.reports.execution.RoReportsExecutionRepository
import com.normation.rudder.reports.execution.AgentRun
import com.normation.rudder.domain.logger.TimingDebugLogger

/**
* Very much like the NodeGrid, but with the new WB and without ldap information
Expand Down Expand Up @@ -139,35 +140,42 @@ class SrvGrid(
, callback : Option[String => JsCmd]
) = {

val lines = (for {
lastReports <- roAgentRunsRepository.getNodesLastRun(nodes.map(_.id).toSet)
} yield {
nodes.map(node => NodeLine(node,lastReports.get(node.id), callback))
}) match {
case eb: EmptyBox =>
val msg = "Error when trying to get nodes info"
val e = eb ?~! msg
logger.error(e.messageChain)
e.rootExceptionCause.foreach(ex => logger.error(ex) )
Nil
case Full(lines) => lines.toList
}

JsTableData(lines)
val now = System.currentTimeMillis
val runs = roAgentRunsRepository.getNodesLastRun(nodes.map(_.id).toSet)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you remove this from the for only to get the timing ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


if(TimingDebugLogger.isDebugEnabled) {
TimingDebugLogger.debug(s"Get all last run date time: ${System.currentTimeMillis - now}ms")
}

val lines = (for {
lastReports <- runs
} yield {
nodes.map(node => NodeLine(node,lastReports.get(node.id), callback))
}) match {
case eb: EmptyBox =>
val msg = "Error when trying to get nodes info"
val e = eb ?~! msg
logger.error(e.messageChain)
e.rootExceptionCause.foreach(ex => logger.error(ex) )
Nil
case Full(lines) => lines.toList
}

JsTableData(lines)
}

def refreshData (
refreshNodes : () => Seq[NodeInfo]
, callback : Option[String => JsCmd]
, tableId: String
) = {
val ajaxCall = SHtml.ajaxCall(JsNull, (s) => {
val nodes = refreshNodes()
val data = getTableData(nodes,callback)
JsRaw(s"""refreshTable("${tableId}",${data.json.toJsCmd});""")
} )
val ajaxCall = SHtml.ajaxCall(JsNull, (s) => {
val nodes = refreshNodes()
val data = getTableData(nodes,callback)
JsRaw(s"""refreshTable("${tableId}",${data.json.toJsCmd});""")
} )

AnonFunc("",ajaxCall)
AnonFunc("",ajaxCall)
}

/**
Expand Down Expand Up @@ -231,4 +239,4 @@ case class NodeLine (
}

val json = baseFields +* JsObj(optCallback.toSeq:_*)
}
}
Loading