convert offer operations to something a bit more functional
@@ -7,12 +7,34 @@ import (
"github.com/gogo/protobuf/proto"
)
-func (operation *Offer_Operation) Apply(resources Resources) (Resources, error) {
+type offerResourceOp func(Offer_Operation, Resources) (Resources, error)
+
+var (
+ opNoop = func(_ Offer_Operation, _ Resources) (_ Resources, _ error) { return }
+ offerResourceOpMap = map[Offer_Operation_Type]offerResourceOp{
+ LAUNCH: opNoop,
+ RESERVE: validateOpTotals(opReserve),
+ UNRESERVE: validateOpTotals(opUnreserve),
+ CREATE: validateOpTotals(opCreate),
+ DESTROY: validateOpTotals(opDestroy),
+ }
+)
+
+func validateOpTotals(f offerResourceOp) offerResourceOp {
+ return func(operation Offer_Operation, resources Resources) (Resources, error) {
+ result, err := f(operation, resources)
+ if err == nil {
+ // sanity CHECK, same as apache/mesos does
+ if !resources.sameTotals(result) {
+ panic("result != resources")
+ }
+ }
+ return result, err
+ }
+}
+
+func opReserve(operation Offer_Operation, resources Resources) (Resources, error) {
result := resources.Clone()
- switch operation.GetType() {
- case LAUNCH:
- // launch op doens't alter offer resources
- case RESERVE:
opRes := Resources(operation.GetReserve().GetResources())
err := opRes.Validate()
if err != nil {
@@ -32,7 +54,11 @@ func (operation *Offer_Operation) Apply(resources Resources) (Resources, error)
result.SubtractAll(unreserved)
result.Add(r)
}
- case UNRESERVE:
+ return result, nil
+}
+
+func opUnreserve(operation Offer_Operation, resources Resources) (Resources, error) {
+ result := resources.Clone()
opRes := Resources(operation.GetUnreserve().GetResources())
err := opRes.Validate()
if err != nil {
@@ -49,7 +75,11 @@ func (operation *Offer_Operation) Apply(resources Resources) (Resources, error)
result.Subtract(r)
result.AddAll(unreserved)
}
- case CREATE:
+ return result, nil
+}
+
+func opCreate(operation Offer_Operation, resources Resources) (Resources, error) {
+ result := resources.Clone()
volumes := Resources(operation.GetCreate().GetVolumes())
err := volumes.Validate()
if err != nil {
@@ -77,7 +107,11 @@ func (operation *Offer_Operation) Apply(resources Resources) (Resources, error)
result.Subtract(*stripped)
result.Add(v)
}
- case DESTROY:
+ return result, nil
+}
+
+func opDestroy(operation Offer_Operation, resources Resources) (Resources, error) {
+ result := resources.Clone()
volumes := Resources(operation.GetDestroy().GetVolumes())
err := volumes.Validate()
if err != nil {
@@ -98,14 +132,13 @@ func (operation *Offer_Operation) Apply(resources Resources) (Resources, error)
result.Subtract(v)
result.Add(*stripped)
}
- default:
- return nil, errors.New("unknown offer operation: " + operation.GetType().String())
+ return result, nil
}
- // sanity CHECK, same as apache/mesos does
- if !resources.sameTotals(result) {
- panic("result != resources")
+func (operation Offer_Operation) Apply(resources Resources) (Resources, error) {
+ f, ok := offerResourceOpMap[operation.GetType()]
+ if !ok {
+ return nil, errors.New("unknown offer operation: " + operation.GetType().String())
}
-
- return result, nil
+ return f(operation, resources)
}
