Skip to content

Commit

Permalink
Introduced ResourceConversion to represent conversion to Resources.
Browse files Browse the repository at this point in the history
Currently, we couple offer operations with resource conversions. For
instance, we have interfaces like `Resources::apply` that takes an
offer operation. This becomes less ideal because an offer operation
might not represent a `conversion` anymore with new offer operation
like `CREATE_VOLUME` being introduced.

This patch decoupled resource conversions from offer operations.
`Resources::apply` will now take a `ResourceConversion` object. We
also provide some helpers to get a `ResourceConversion` from an offer
operation (if supported).

Review: https://reviews.apache.org/r/63511
  • Loading branch information
jieyu committed Nov 6, 2017
1 parent 2f1efb9 commit e55309a
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 548 deletions.
60 changes: 47 additions & 13 deletions include/mesos/resources.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <stout/hashmap.hpp>
#include <stout/json.hpp>
#include <stout/lambda.hpp>
#include <stout/nothing.hpp>
#include <stout/option.hpp>
#include <stout/try.hpp>

Expand All @@ -53,6 +54,10 @@

namespace mesos {

// Forward declaration.
class ResourceConversion;


// NOTE: Resource objects stored in the class are always valid, are in
// the "post-reservation-refinement" format, and kept combined if possible.
// It is the caller's responsibility to validate any Resource object or
Expand Down Expand Up @@ -464,26 +469,30 @@ class Resources
// example frameworks to leverage.
Option<Resources> find(const Resources& targets) const;

// Certain offer operations alter the offered resources. The
// following methods provide a convenient way to get the transformed
// resources by applying the given offer operation(s). Returns an
// Error if the offer operation(s) cannot be applied.
Try<Resources> apply(
const Offer::Operation& operation,
const Option<Resources>& convertedResources = None()) const;
// Applies a resource conversion by taking out the `consumed`
// resources and adding back the `converted` resources. Returns an
// Error if the conversion cannot be applied.
Try<Resources> apply(const ResourceConversion& conversion) const;

// Obtains the conversion from the given operation and applies the
// conversion. This method serves a syntax sugar for applying a
// resource conversion.
// TODO(jieyu): Consider remove this method once we updated all the
// call sites.
Try<Resources> apply(const Offer::Operation& operation) const;

template <typename Iterable>
Try<Resources> apply(const Iterable& operations) const
Try<Resources> apply(const Iterable& iterable) const
{
Resources result = *this;

foreach (const Offer::Operation& operation, operations) {
Try<Resources> transformed = result.apply(operation);
if (transformed.isError()) {
return Error(transformed.error());
foreach (const auto& t, iterable) {
Try<Resources> converted = result.apply(t);
if (converted.isError()) {
return Error(converted.error());
}

result = transformed.get();
result = converted.get();
}

return result;
Expand Down Expand Up @@ -663,6 +672,31 @@ hashmap<Key, Resources> operator+(
return result;
}


/**
* Represents a resource conversion, usually as a result of an offer
* operation. See more details in `Resources::apply` method.
*/
class ResourceConversion
{
public:
typedef lambda::function<Try<Nothing>(const Resources&)> PostValidation;

ResourceConversion(
const Resources& _consumed,
const Resources& _converted,
const Option<PostValidation>& _postValidation = None())
: consumed(_consumed),
converted(_converted),
postValidation(_postValidation) {}

Try<Resources> apply(const Resources& resources) const;

Resources consumed;
Resources converted;
Option<PostValidation> postValidation;
};

} // namespace mesos {

#endif // __RESOURCES_HPP__
60 changes: 47 additions & 13 deletions include/mesos/v1/resources.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <stout/hashmap.hpp>
#include <stout/json.hpp>
#include <stout/lambda.hpp>
#include <stout/nothing.hpp>
#include <stout/option.hpp>
#include <stout/try.hpp>

Expand All @@ -53,6 +54,10 @@
namespace mesos {
namespace v1 {

// Forward declaration.
class ResourceConversion;


// NOTE: Resource objects stored in the class are always valid, are in
// the "post-reservation-refinement" format, and kept combined if possible.
// It is the caller's responsibility to validate any Resource object or
Expand Down Expand Up @@ -464,26 +469,30 @@ class Resources
// example frameworks to leverage.
Option<Resources> find(const Resources& targets) const;

// Certain offer operations alter the offered resources. The
// following methods provide a convenient way to get the transformed
// resources by applying the given offer operation(s). Returns an
// Error if the offer operation(s) cannot be applied.
Try<Resources> apply(
const Offer::Operation& operation,
const Option<Resources>& convertedResources = None()) const;
// Applies a resource conversion by taking out the `consumed`
// resources and adding back the `converted` resources. Returns an
// Error if the conversion cannot be applied.
Try<Resources> apply(const ResourceConversion& conversion) const;

// Obtains the conversion from the given operation and applies the
// conversion. This method serves a syntax sugar for applying a
// resource conversion.
// TODO(jieyu): Consider remove this method once we updated all the
// call sites.
Try<Resources> apply(const Offer::Operation& operation) const;

template <typename Iterable>
Try<Resources> apply(const Iterable& operations) const
Try<Resources> apply(const Iterable& iterable) const
{
Resources result = *this;

foreach (const Offer::Operation& operation, operations) {
Try<Resources> transformed = result.apply(operation);
if (transformed.isError()) {
return Error(transformed.error());
foreach (const auto& t, iterable) {
Try<Resources> converted = result.apply(t);
if (converted.isError()) {
return Error(converted.error());
}

result = transformed.get();
result = converted.get();
}

return result;
Expand Down Expand Up @@ -663,6 +672,31 @@ hashmap<Key, Resources> operator+(
return result;
}


/**
* Represents a resource conversion, usually as a result of an offer
* operation. See more details in `Resources::apply` method.
*/
class ResourceConversion
{
public:
typedef lambda::function<Try<Nothing>(const Resources&)> PostValidation;

ResourceConversion(
const Resources& _consumed,
const Resources& _converted,
const Option<PostValidation>& _postValidation = None())
: consumed(_consumed),
converted(_converted),
postValidation(_postValidation) {}

Try<Resources> apply(const Resources& resources) const;

Resources consumed;
Resources converted;
Option<PostValidation> postValidation;
};

} // namespace v1 {
} // namespace mesos {

Expand Down

0 comments on commit e55309a

Please sign in to comment.