1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_
6 #define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_
7 
8 #include <string>
9 
10 #include "base/containers/flat_set.h"
11 #include "base/macros.h"
12 #include "base/util/type_safety/token_type.h"
13 #include "components/performance_manager/public/execution_context_priority/execution_context_priority.h"
14 #include "components/performance_manager/public/graph/node.h"
15 #include "third_party/blink/public/common/tokens/tokens.h"
16 
17 class GURL;
18 
19 namespace performance_manager {
20 
21 class WorkerNodeObserver;
22 class FrameNode;
23 class ProcessNode;
24 
25 using execution_context_priority::PriorityAndReason;
26 
27 // Represents a running instance of a WorkerGlobalScope.
28 // See https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope.
29 //
30 // A worker is the equivalent of a thread on the web platform. To do
31 // asynchronous work, a frame can create a dedicated worker or a shared worker
32 // with Javascript. Those workers can now be used by sending an asynchronous
33 // message using the postMessage() method, and replies can be received by
34 // registering a message handler on the worker object.
35 //
36 // One notable special case is that dedicated workers can be nested. That means
37 // that a dedicated worker can create another dedicated worker which is then
38 // only accessible from the parent worker.
39 //
40 // Service workers are different. Instead of being created by the javascript
41 // when needed, a service worker is registered once and affects all frames and
42 // dedicated/shared workers whose URL matches the scope of the service worker.
43 // A service worker is mainly used to intercept network requests and optionally
44 // serve the responses from a cache, making the web site work offline.
45 //
46 // A client, from the point of view of the worker, is the frame or worker that
47 // caused the worker to start running, either because it explicitly created it,
48 // or a service worker is registered to handle their network requests.
49 class WorkerNode : public Node {
50  public:
51   // The different possible worker types.
52   enum class WorkerType {
53     kDedicated,
54     kShared,
55     kService,
56   };
57 
58   using Observer = WorkerNodeObserver;
59   class ObserverDefaultImpl;
60 
61   WorkerNode();
62   ~WorkerNode() override;
63 
64   // Returns the worker type. Note that this is different from the NodeTypeEnum.
65   virtual WorkerType GetWorkerType() const = 0;
66 
67   // Returns the unique ID of the browser context that this worker belongs to.
68   virtual const std::string& GetBrowserContextID() const = 0;
69 
70   // Returns the process node to which this worker belongs. This is a constant
71   // over the lifetime of the frame.
72   virtual const ProcessNode* GetProcessNode() const = 0;
73 
74   // Returns the unique token identifying this worker.
75   virtual const blink::WorkerToken& GetWorkerToken() const = 0;
76 
77   // Returns the URL of the worker script. This is the final response URL which
78   // takes into account redirections.
79   virtual const GURL& GetURL() const = 0;
80 
81   // Returns the frames that are clients of this worker.
82   virtual const base::flat_set<const FrameNode*> GetClientFrames() const = 0;
83 
84   // Returns the workers that are clients of this worker.
85   // There are 2 cases where this is possible:
86   // - A dedicated worker can create nested workers. The parent worker becomes
87   //   one of its client worker.
88   // - A dedicated worker or a shared worker will become a client of the service
89   //   worker that handles their network requests.
90   virtual const base::flat_set<const WorkerNode*> GetClientWorkers() const = 0;
91 
92   // Returns the child workers of this worker.
93   // There are 2 cases where a worker can be the child of another worker:
94   // - A dedicated worker can create nested workers. The nested worker becomes
95   //   a child worker of the parent.
96   // - A service worker will become a child worker of every worker for which
97   //   it handles network requests.
98   virtual const base::flat_set<const WorkerNode*> GetChildWorkers() const = 0;
99 
100   // Returns the current priority of the worker, and the reason for the worker
101   // having that particular priority.
102   virtual const PriorityAndReason& GetPriorityAndReason() const = 0;
103 
104  private:
105   DISALLOW_COPY_AND_ASSIGN(WorkerNode);
106 };
107 
108 // Pure virtual observer interface. Derive from this if you want to be forced to
109 // implement the entire interface.
110 class WorkerNodeObserver {
111  public:
112   WorkerNodeObserver();
113   virtual ~WorkerNodeObserver();
114 
115   // Node lifetime notifications.
116 
117   // Called when a |worker_node| is added to the graph.
118   virtual void OnWorkerNodeAdded(const WorkerNode* worker_node) = 0;
119 
120   // Called before a |worker_node| is removed from the graph.
121   virtual void OnBeforeWorkerNodeRemoved(const WorkerNode* worker_node) = 0;
122 
123   // Notifications of property changes.
124 
125   // Invoked when the final url of the worker script has been determined, which
126   // happens when the script has finished loading.
127   virtual void OnFinalResponseURLDetermined(const WorkerNode* worker_node) = 0;
128 
129   // Invoked when |client_frame_node| becomes a client of |worker_node|.
130   virtual void OnClientFrameAdded(const WorkerNode* worker_node,
131                                   const FrameNode* client_frame_node) = 0;
132 
133   // Invoked when |client_frame_node| is no longer a client of |worker_node|.
134   virtual void OnBeforeClientFrameRemoved(
135       const WorkerNode* worker_node,
136       const FrameNode* client_frame_node) = 0;
137 
138   // Invoked when |client_worker_node| becomes a client of |worker_node|.
139   virtual void OnClientWorkerAdded(const WorkerNode* worker_node,
140                                    const WorkerNode* client_worker_node) = 0;
141 
142   // Invoked when |client_worker_node| is no longer a client of |worker_node|.
143   virtual void OnBeforeClientWorkerRemoved(
144       const WorkerNode* worker_node,
145       const WorkerNode* client_worker_node) = 0;
146 
147   // Invoked when the worker priority and reason changes.
148   virtual void OnPriorityAndReasonChanged(
149       const WorkerNode* worker_node,
150       const PriorityAndReason& previous_value) = 0;
151 
152  private:
153   DISALLOW_COPY_AND_ASSIGN(WorkerNodeObserver);
154 };
155 
156 // Default implementation of observer that provides dummy versions of each
157 // function. Derive from this if you only need to implement a few of the
158 // functions.
159 class WorkerNode::ObserverDefaultImpl : public WorkerNodeObserver {
160  public:
161   ObserverDefaultImpl();
162   ~ObserverDefaultImpl() override;
163 
164   // WorkerNodeObserver implementation:
165 
166   // Called when a |worker_node| is added to the graph.
OnWorkerNodeAdded(const WorkerNode * worker_node)167   void OnWorkerNodeAdded(const WorkerNode* worker_node) override {}
OnBeforeWorkerNodeRemoved(const WorkerNode * worker_node)168   void OnBeforeWorkerNodeRemoved(const WorkerNode* worker_node) override {}
OnFinalResponseURLDetermined(const WorkerNode * worker_node)169   void OnFinalResponseURLDetermined(const WorkerNode* worker_node) override {}
OnClientFrameAdded(const WorkerNode * worker_node,const FrameNode * client_frame_node)170   void OnClientFrameAdded(const WorkerNode* worker_node,
171                           const FrameNode* client_frame_node) override {}
OnBeforeClientFrameRemoved(const WorkerNode * worker_node,const FrameNode * client_frame_node)172   void OnBeforeClientFrameRemoved(const WorkerNode* worker_node,
173                                   const FrameNode* client_frame_node) override {
174   }
OnClientWorkerAdded(const WorkerNode * worker_node,const WorkerNode * client_worker_node)175   void OnClientWorkerAdded(const WorkerNode* worker_node,
176                            const WorkerNode* client_worker_node) override {}
OnBeforeClientWorkerRemoved(const WorkerNode * worker_node,const WorkerNode * client_worker_node)177   void OnBeforeClientWorkerRemoved(
178       const WorkerNode* worker_node,
179       const WorkerNode* client_worker_node) override {}
OnPriorityAndReasonChanged(const WorkerNode * worker_node,const PriorityAndReason & previous_value)180   void OnPriorityAndReasonChanged(
181       const WorkerNode* worker_node,
182       const PriorityAndReason& previous_value) override {}
183 
184  private:
185   DISALLOW_COPY_AND_ASSIGN(ObserverDefaultImpl);
186 };
187 
188 }  // namespace performance_manager
189 
190 #endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_GRAPH_WORKER_NODE_H_
191