Apache Mesos
sorter.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __MASTER_ALLOCATOR_SORTER_SORTER_HPP__
18 #define __MASTER_ALLOCATOR_SORTER_SORTER_HPP__
19 
20 #include <functional>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include <mesos/resources.hpp>
26 #include <mesos/type_utils.hpp>
27 
28 #include <process/pid.hpp>
29 
30 namespace mesos {
31 namespace internal {
32 namespace master {
33 namespace allocator {
34 
35 // Sorters implement the logic for determining the
36 // order in which users or frameworks should receive
37 // resource allocations.
38 //
39 // TODO(bmahler): Templatize this on Client, so that callers can
40 // don't need to do string conversion, e.g. FrameworkID, string role,
41 // etc.
42 class Sorter
43 {
44 public:
45  Sorter() = default;
46 
47  // Provides the allocator's execution context (via a UPID)
48  // and a name prefix in order to support metrics within the
49  // sorter implementation.
50  explicit Sorter(
51  const process::UPID& allocator,
52  const std::string& metricsPrefix) {}
53 
54  virtual ~Sorter() = default;
55 
56  // Initialize the sorter.
57  virtual void initialize(
58  const Option<std::set<std::string>>& fairnessExcludeResourceNames) = 0;
59 
60  // Adds a client to allocate resources to.
61  // A client may be a user or a framework.
62  // This function will not activate the client.
63  virtual void add(const std::string& client) = 0;
64 
65  // Removes a client.
66  virtual void remove(const std::string& client) = 0;
67 
68  // Readds a client to the sort after deactivate.
69  // It is a no-op if the client is already in the sort.
70  virtual void activate(const std::string& client) = 0;
71 
72  // Removes a client from the sort, so it won't get allocated to.
73  // It is a no-op if the client is already not in the sort.
74  virtual void deactivate(const std::string& client) = 0;
75 
76  // Updates the weight of a client path. This changes the sorter's
77  // behavior for all clients in the subtree identified by this path
78  // (both clients currently in the sorter and any clients that may be
79  // added later). If a client's weight is not explicitly set, the
80  // default weight of 1.0 is used. This interface does not support
81  // unsetting previously set weights; instead, the weight should be
82  // reset to the default value.
83  virtual void updateWeight(const std::string& path, double weight) = 0;
84 
85  // Specify that resources have been allocated to the given client.
86  virtual void allocated(
87  const std::string& client,
88  const SlaveID& slaveId,
89  const Resources& resources) = 0;
90 
91  // Updates a portion of the allocation for the client, in order to augment the
92  // resources with additional metadata (e.g., volumes), or remove certain
93  // resources. If the roles or scalar quantities are changed, the order of the
94  // clients should be updated accordingly.
95  virtual void update(
96  const std::string& client,
97  const SlaveID& slaveId,
98  const Resources& oldAllocation,
99  const Resources& newAllocation) = 0;
100 
101  // Specify that resources have been unallocated from the given client.
102  virtual void unallocated(
103  const std::string& client,
104  const SlaveID& slaveId,
105  const Resources& resources) = 0;
106 
107  // Returns the resources that have been allocated to this client.
109  const std::string& client) const = 0;
110 
111  // Returns the total scalar resource quantities that are allocated to
112  // this client. This omits metadata about dynamic reservations and
113  // persistent volumes; see `Resources::createStrippedScalarQuantity`.
114  virtual const Resources& allocationScalarQuantities(
115  const std::string& client) const = 0;
116 
117  // Returns the clients that have allocations on this slave.
119  const SlaveID& slaveId) const = 0;
120 
121  // Returns the given slave's resources that have been allocated to
122  // this client.
123  virtual Resources allocation(
124  const std::string& client,
125  const SlaveID& slaveId) const = 0;
126 
127  // Returns the total scalar resource quantities in this sorter. This
128  // omits metadata about dynamic reservations and persistent volumes; see
129  // `Resources::createStrippedScalarQuantity`.
130  virtual const Resources& totalScalarQuantities() const = 0;
131 
132  // Add resources to the total pool of resources this
133  // Sorter should consider.
134  virtual void add(const SlaveID& slaveId, const Resources& resources) = 0;
135 
136  // Remove resources from the total pool.
137  virtual void remove(const SlaveID& slaveId, const Resources& resources) = 0;
138 
139  // Returns all of the clients in the order that they should
140  // be allocated to, according to this Sorter's policy.
141  virtual std::vector<std::string> sort() = 0;
142 
143  // Returns true if this Sorter contains the specified client,
144  // which may be active or inactive.
145  virtual bool contains(const std::string& client) const = 0;
146 
147  // Returns the number of clients this Sorter contains,
148  // either active or inactive.
149  virtual size_t count() const = 0;
150 };
151 
152 // Efficient type for scalar resource quantities that avoids
153 // the overhead of using `Resources`.
154 //
155 // TODO(bmahler): This was originally added to replace a
156 // `hashmap<string, Scalar>` and hence the interface was
157 // tailored to the particular usage of the map. In order
158 // to move this up as a replacement of all quantities
159 // (e.g. `Resources::createStrippedScalarQuantity()`),
160 // this will need more functionality to do so (e.g.
161 // arithmetic operators, containment check, etc).
163 {
164 public:
166  {
167  // Pre-reserve space for first-class scalars.
168  quantities.reserve(4u); // [cpus, disk, gpus, mem]
169  }
170 
171  // Returns true if there is a non-zero amount of
172  // the specified resource.
173  bool contains(const std::string& name) const
174  {
175  // Don't bother binary searching since we don't expect
176  // a large number of quantities.
177  foreach (auto& quantity, quantities) {
178  if (quantity.first == name) {
179  return quantity.second.value() > 0.0;
180  }
181  }
182 
183  return false;
184  }
185 
186  const Value::Scalar& at(const std::string& name) const
187  {
188  // Don't bother binary searching since we don't expect
189  // a large number of quantities.
190  foreach (auto& quantity, quantities) {
191  if (quantity.first == name) {
192  return quantity.second;
193  }
194  }
195 
196  // TODO(bmahler): Print out the vector, need to add
197  // a `stringify(const pair<T1, T2>& p)` overload.
198  LOG(FATAL) << "Failed to find '" << name << "'";
199  }
200 
201  Value::Scalar& operator[](const std::string& name)
202  {
203  // Find the location to insert while maintaining
204  // alphabetical ordering. Don't bother binary searching
205  // since we don't expect a large number of quantities.
206  auto it = quantities.begin();
207  for (; it != quantities.end(); ++it) {
208  if (it->first == name) {
209  return it->second;
210  }
211 
212  if (it->first > name) {
213  break;
214  }
215  }
216 
217  it = quantities.insert(it, std::make_pair(name, Value::Scalar()));
218 
219  return it->second;
220  }
221 
222  typedef std::vector<std::pair<std::string, Value::Scalar>>::const_iterator
224 
225  const_iterator begin() const { return quantities.begin(); }
226  const_iterator end() const { return quantities.end(); }
227 
228 private:
229  // List of scalar resources sorted by resource name.
230  // Arithmetic operations benefit from this sorting.
231  std::vector<std::pair<std::string, Value::Scalar>> quantities;
232 };
233 
234 
235 } // namespace allocator {
236 } // namespace master {
237 } // namespace internal {
238 } // namespace mesos {
239 
240 #endif // __MASTER_ALLOCATOR_SORTER_SORTER_HPP__
const_iterator begin() const
Definition: sorter.hpp:225
Definition: path.hpp:26
bool contains(const std::string &name) const
Definition: sorter.hpp:173
virtual void unallocated(const std::string &client, const SlaveID &slaveId, const Resources &resources)=0
Definition: option.hpp:28
Sorter(const process::UPID &allocator, const std::string &metricsPrefix)
Definition: sorter.hpp:50
Definition: master.hpp:27
const Value::Scalar & at(const std::string &name) const
Definition: sorter.hpp:186
Definition: resources.hpp:81
virtual void initialize(const Option< std::set< std::string >> &fairnessExcludeResourceNames)=0
virtual const hashmap< SlaveID, Resources > & allocation(const std::string &client) const =0
virtual void update(const std::string &client, const SlaveID &slaveId, const Resources &oldAllocation, const Resources &newAllocation)=0
virtual void updateWeight(const std::string &path, double weight)=0
Definition: hashmap.hpp:38
virtual const Resources & totalScalarQuantities() const =0
virtual const Resources & allocationScalarQuantities(const std::string &client) const =0
An "untyped" PID, used to encapsulate the process ID for lower-layer abstractions (eg...
Definition: pid.hpp:39
Definition: spec.hpp:26
Value::Scalar & operator[](const std::string &name)
Definition: sorter.hpp:201
virtual bool contains(const std::string &client) const =0
std::vector< std::pair< std::string, Value::Scalar > >::const_iterator const_iterator
Definition: sorter.hpp:223
Definition: attributes.hpp:24
virtual void add(const std::string &client)=0
virtual std::vector< std::string > sort()=0
const_iterator end() const
Definition: sorter.hpp:226
virtual void activate(const std::string &client)=0
constexpr const char * name
Definition: shell.hpp:43
virtual void deactivate(const std::string &client)=0
virtual void allocated(const std::string &client, const SlaveID &slaveId, const Resources &resources)=0