+ /**
+ * Event handler helpers
+ */
+ _get_next_state_add: function(prev_state)
+ {
+ switch (prev_state) {
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ new_state = STATE_SET_IN_PENDING;
+ break;
+
+ case STATE_SET_OUT_PENDING:
+ new_state = STATE_SET_IN;
+ break;
+
+ case STATE_SET_IN:
+ case STATE_SET_IN_PENDING:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ console.log("Inconsistent state: already in");
+ return;
+ }
+ return new_state;
+ },
+
+ _get_next_state_remove: function(prev_state)
+ {
+ switch (prev_state) {
+ case STATE_SET_IN:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ new_state = STATE_SET_OUT_PENDING;
+ break;
+
+ case STATE_SET_IN_PENDING:
+ new_state = STATE_SET_OUT;
+ break;
+
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_PENDING:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ console.log("Inconsistent state: already out");
+ return;
+ }
+ return new_state;
+ },
+
+ _grep_active_lease_callback: function(lease_query, resource_key) {
+ return function(lease_key_lease) {
+ var state, lease_key, lease;
+
+ lease_key = lease_key_lease[0];
+ lease = lease_key_lease[1];
+
+ if (lease['resource'] != resource_key)
+ return false;
+
+ state = manifold.query_store.get_record_state(lease_query.query_uuid, lease_key, STATE_SET);;
+ switch(state) {
+ case STATE_SET_IN:
+ case STATE_SET_IN_PENDING:
+ case STATE_SET_IN_SUCCESS:
+ case STATE_SET_OUT_FAILURE:
+ return true;
+ case STATE_SET_OUT:
+ case STATE_SET_OUT_PENDING:
+ case STATE_SET_OUT_SUCCESS:
+ case STATE_SET_IN_FAILURE:
+ return false;
+ }
+ }
+ },
+
+ _enforce_constraints: function(query_ext, record, record_key, event_type)
+ {
+ var query, data;
+
+ query = query_ext.query;
+
+ switch(query.object) {
+
+ case 'resource':
+ // CONSTRAINT_RESERVABLE_LEASE
+ //
+ // +) If a reservable node is added to the slice, then it should have a corresponding lease
+ // XXX Not always a resource
+ var is_reservable = (record.exclusive == true);
+ if (is_reservable) {
+ var warnings = manifold.query_store.get_record_state(query.query_uuid, record_key, STATE_WARNINGS);
+
+ if (event_type == STATE_SET_ADD) {
+ // We should have a lease_query associated
+ var lease_query = query_ext.parent_query_ext.query.subqueries['lease']; // in options
+ var lease_query_ext = manifold.query_store.find_analyzed_query_ext(lease_query.query_uuid);
+ // Do we have lease records (in) with this resource
+ var lease_records = $.grep(lease_query_ext.records.entries(), this._grep_active_lease_callback(lease_query, record_key));
+ if (lease_records.length == 0) {
+ // Sets a warning
+ // XXX Need for a better function to manage warnings
+ var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+ warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+
+ manifold.query_store.set_record_state(query.query_uuid, record_key, STATE_WARNINGS, warnings);
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : record_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(query.query_uuid, FIELD_STATE_CHANGED, data);
+
+ } else {
+ // Lease are defined, delete the warning in case it was set previously
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+ } else {
+ // Remove warnings attached to this resource
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+ }
+
+ /* This was redundant */
+ // manifold.query_store.recount(query.query_uuid);
+
+ break;
+
+ case 'lease':
+ var resource_key = record_key.resource;
+ var resource_query = query_ext.parent_query_ext.query.subqueries['resource'];
+ var warnings = manifold.query_store.get_record_state(resource_query.query_uuid, resource_key, STATE_WARNINGS);
+
+ if (event_type == STATE_SET_ADD || event_type == STATE_SET_IN_PENDING) {
+ // A lease is added, it removes the constraint
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ } else {
+ // A lease is removed, it might trigger the warning
+ var lease_records = $.grep(query_ext.records.entries(), this._grep_active_lease_callback(query, resource_key));
+ if (lease_records.length == 0) { // XXX redundant cases
+ // Sets a warning
+ // XXX Need for a better function to manage warnings
+ var warn = CONSTRAINT_RESERVABLE_LEASE_MSG;
+ warnings[CONSTRAINT_RESERVABLE_LEASE] = warn;
+
+ // Signal the change to plugins (even if the constraint does not apply, so that the plugin can display a checkmark)
+ data = {
+ state: STATE_WARNINGS,
+ key : resource_key,
+ op : null,
+ value : warnings
+ }
+ manifold.raise_record_event(resource_query.query_uuid, FIELD_STATE_CHANGED, data);
+ } else {
+ // Lease are defined, delete the warning in case it was set previously
+ delete warnings[CONSTRAINT_RESERVABLE_LEASE];
+ }
+ }
+ /* Adding a lease can remove a warning and reduce the unconfigured resources */
+ manifold.query_store.recount(resource_query.query_uuid);
+ break;
+ }