From d7b6d9f124af7e226dd80047f0404c30a266a434 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Thu, 16 Apr 2015 16:18:11 +0200 Subject: [PATCH] Objects are now linked together! ```javascript const {pool} = xapi console.log(pool.master.name_label) ``` --- packages/xen-api/src/index.js | 39 ++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/xen-api/src/index.js b/packages/xen-api/src/index.js index 79c92e1e7..11514f8a9 100644 --- a/packages/xen-api/src/index.js +++ b/packages/xen-api/src/index.js @@ -1,7 +1,6 @@ import Bluebird, {promisify} from 'bluebird' import Collection from 'xo-collection' import createDebug from 'debug' -import findKey from 'lodash.findkey' import forEach from 'lodash.foreach' import startsWith from 'lodash.startswith' import {BaseError} from 'make-error' @@ -91,8 +90,12 @@ function parseUrl (url) { } } +// ------------------------------------------------------------------- + const noop = () => {} +// ------------------------------------------------------------------- + const notConnectedPromise = Bluebird.reject(new Error('not connected')) // Does nothing but avoid a Bluebird message error. @@ -102,6 +105,8 @@ notConnectedPromise.catch(noop) const MAX_TRIES = 5 +// ------------------------------------------------------------------- + export class Xapi extends EventEmitter { constructor (opts) { super() @@ -114,6 +119,8 @@ export class Xapi extends EventEmitter { this._init() this._poolId = null + this._objectsByRefs = Object.create(null) + this._objectsByRefs['OpaqueRef:NULL'] = null this._objects = new Collection() this._objects.getId = (object) => object.$id @@ -304,12 +311,26 @@ export class Xapi extends EventEmitter { } _normalizeObject (type, ref, object) { + const {_objectsByRefs: objectsByRefs} = this + const REF_RE = /^OpaqueRef:/ + + forEach(object, function resolveIfLink(value, key, object) { + if (typeof value === 'string' && REF_RE.test(value)) { + Object.defineProperty(object, key, { + enumerable: true, + get: () => objectsByRefs[value] + }) + } else if (typeof value === 'object') { + forEach(value, resolveIfLink) + } + }) + object.$id = object.uuid || ref object.$ref = ref object.$type = type Object.defineProperty(object, '$pool', { - // enumerable: true, + enumerable: true, get: () => this._pool }) } @@ -320,24 +341,28 @@ export class Xapi extends EventEmitter { ).then(({token, events}) => { this._fromToken = token - const {_objects: objects} = this + const { + _objects: objects, + _objectsByRefs: objectsByRefs + } = this forEach(events, event => { const {operation: op} = event const {ref} = event if (op === 'del') { - // TODO: This should probably be speed up with an index. - const key = findKey(objects.all, {$ref: ref}) + const objects = objectsByRefs[ref] - if (key !== undefined) { - objects.remove(key) + if (objects) { + objects.remove(objects.$id) + delete objectsByRefs[ref] } } else { const {class: type, snapshot: object} = event this._normalizeObject(type, ref, object) objects.set(object) + objectsByRefs[ref] = object if (object.$type === 'pool') { this._pool = object