PM: Update README.md with some "how to hold it".
Change-Id: I9f02fe6f5de33ef136d1bf9336a0e066128204fd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2047375
Commit-Queue: Sigurður Ásgeirsson <[email protected]>
Reviewed-by: François Doray <[email protected]>
Cr-Commit-Position: refs/heads/master@{#741532}
diff --git a/components/performance_manager/README.md b/components/performance_manager/README.md
index 45ec683..ffdf8bd6 100644
--- a/components/performance_manager/README.md
+++ b/components/performance_manager/README.md
@@ -1,18 +1,130 @@
# Performance Manager Overview
-The Performance Manager centralizes policy for data-driven resource management
-and planning. Central to this is the [graph](graph/graph_impl.h) which is
-comprised of nodes that reflect the coarse structure of a browser at the
-level of [pages](graph/page_node_impl.h), [frames](graph/frame_node_impl.h)
-[processes](graph/process_node_impl.h), [workers](graph/worker_node_impl.h) and so forth.
+[TOC]
-Each node is adorned with relationships and properties sufficient to allow performance management policy
-to reason about such things as resource usage and prioritization. Usually properties are added directly
-to nodes if they would be used by multiple clients. Otherwise, it's preferred to
-add them as private impl details via [NodeAttachedData](graph/node_attached_data_impl.h). See
-[ProcessPriorityAggregator](/chrome/browser/performance_manager/decorators/process_priority_aggregator.cc) as an example of
-such a use-case. It requires some per-process-node intermediate data which is stored as NodeAttachedData.
+# Overview
-Nodes are nothing but data storage and contain no logic. Properties that need
-computation to be maintained are maintained via [decorators](decorators/) or "aggregators"
-which are both observers and mutators of the graph.
+The Performance Manager supports data-driven, centralized resource management,
+prioritization and planning for the Chrome browser. Over time, data-driven,
+centralized resource management will supplant and/or supplement the heuristics
+that can be found all over Chrome at present.
+
+Here’s an overview picture of the intended architecture:
+
+
+
+- The *Embedder* is responsible for notifying the
+ [Performance Manager Registry](embedder/performance_manager_registry.h) when
+ content entities are created or their relationships change. The Performance Manager
+ Registry maintains the structure of the Graph, which is a coarsely abstracted view of the state
+ of the browser.
+- Decorators populate the graph nodes with interesting properties and data, such as e.g. the results
+ of CPU, memory and battery measurements and so on.
+- Aggregators aggregate data in the graph, possibly across nodes.
+ As an example, the memory usage of all frame nodes could be summed up to their associated page
+ node, to establish the total memory usage of the page.
+- Resource Management Policies are observers of the graph, and use the graph structure as well as
+ the properties of graph nodes to make policy decisions.
+- Resource Management Mechanisms are invoked by Resource Management Policy to implement policy
+ decisions.
+ Note that while the mechanisms are depicted in the main thread, they can be hosted anywhere
+ necessary or convenient, such as in a renderer process at the far end of a mojo::Remote<>.
+- Content Proxies are a convenience feature to allow easy and safe access from nodes in the graph
+ to the corresponding content entity for any task that needs to run on the main thread.
+
+The graph lives on the Performance Manager Sequence, as do all graph observers and mutators.
+The graph structure can be viewed in the graph tab of the `chrome://discards WebUI.`
+
+In addition to the above, the Performance Manager also provides support for
+users that need to occasionally query the graph to e.g. collect metrics.
+
+# Details
+
+## Graph
+
+The performance manager exposes a simplified, coarse model of the browser’s
+state as a [Graph](public/graph/graph.h) of [Nodes](public/graph/node.h),
+where the nodes represent such things as:
+1. [Page](public/graph/page_node.h): corresponds to a content::WebContents.
+1. [Frame](public/graph/frame_node.h): corresponds to a frame in a
+ content::WebContents frame tree.
+1. [Process](public/graph/process_node.h): corresponds to a content::RenderProcessHost or
+ other type of process, such as e.g. the Browser or GPU process.
+1. [Worker](public/graph/worker_node.h): corresponds to a web worker.
+
+Nodes in the graph are connected with edges, such that e.g. each frame or worker
+connects to its hosting process.
+Frames are connected in a tree, and all frames in a tree connect to their
+corresponding page.
+Other edge types may denote dependencies between nodes, such as e.g. a
+MessagePort connection or the like. Different node types in the graph are
+adorned with different sets of properties, each of which represents necessary
+information about the particular node type.
+The graph provides node lookup and retrieval, as well as an observer interface
+for notification of addition and removal of nodes, as well as node property
+changes.
+The graph also provides a way for users to adorn nodes with private data by means of
+[Node Attached Data](public/graph/node_attached_data.h).
+It’s preferable to store data that’s used for intermediate results or for
+private purposes in Node Attached Data rather than in Node properties.
+
+## Public & Private APIs.
+
+The graph exposes both a public and a private API. The private API is only
+available to code in the component’s directory, whereas the public API can be
+used by anyone in the browser process. The private API provides read-write
+access to nodes and allows for node-intimate storage of node attached
+properties. The public API provides read-only access to nodes, but otherwise the
+two APIs are fairly similar. Where possible, using the public API is preferable,
+as the public API is more stable, and doesn’t require the user to live in the
+component.
+
+Good examples where the public API is appropriate, is e.g. for periodically
+collecting metrics by iteration over the graph, or where iterating over the
+graph can yield a set of content entities for some operation. As an example,
+finding the set of frames in a page that belong to the same browsing instance
+would be easy to do by iterating over the graph.
+
+## Decorators
+
+Decorators set properties on the graph that are derived from data external to
+the graph itself, such as e.g. performance measurement data.
+
+A simple example Decorator might periodically measure the cumulative CPU usage
+for each process Node in the Graph and adorn each node with the measured
+cumulative CPU usage of the corresponding process.
+
+## Aggregators
+
+Aggregators, like Decorators, set properties on the graph nodes. The difference is that
+Aggregators work solely on data in the graph, to e.g. aggregate or distribute data from
+one node to another.
+
+A simple example Aggregator working with the simple example Decorator above might
+compute the difference in cumulative CPU usage from the most recent measurement,
+then distribute the difference across the Frame (and/or Worker) nodes associated
+with each Process.
+This would in turn allow summing up the cumulative CPU usage of each Frame and
+Worker node to their associated Page node. This would yield the CPU usage of
+the entire Page (content::WebContents).
+
+## Policies & Mechanisms
+
+The intent is for all Resource Management Policies to use the graph and the data
+therein to make policy decisions. The decisions are then implemented by invoking
+some kind of Resource Management Mechanism. Making this a clean distinction
+makes the implementation easier, more readable and more testable.
+
+A simple example of a policy and a mechanism might be a policy for flushing some
+kind of a cache after all frames in a process have been backgrounded or idle for
+a set amount of time. This policy would register for the appropriate
+notifications and likely maintain private state on a process node. When the
+criteria for flushing is met, the policy invokes the mechanism by rendezvousing
+to a process-associated mojo interface and invoking on it.
+
+If the mojo interface is accessible through a content entity (e.g.
+content::WebContents), the mechanism invocation is posted to the main thread
+where the relevant content proxy (e.g. performance_manager::WebContentsProxy)
+makes it easy and safe to retrieve the content entity on the main thread.
+Should the corresponding content entity have been deleted after the task was
+posted, the content proxy will simply return nullptr.