Various cleanings & minor fix (xapi.js).

This commit is contained in:
Julien Fontanet 2013-12-14 15:37:09 +01:00
parent 7eb0c36a8e
commit 49fcefbf2d
6 changed files with 78 additions and 75 deletions

View File

@ -1,27 +1,28 @@
# Low level tools.
$_ = require 'underscore'
######################################################################
#=====================================================================
class DynamicProperty
class $DynamicProperty
constructor: (@value, @hooks) ->
#---------------------------------------------------------------------
#=====================================================================
noop = ->
$noop = ->
copyDeep = (value) ->
$copyDeep = (value) ->
if value instanceof Array
return (copyDeep item for item in value)
return ($copyDeep item for item in value)
if value instanceof Object
result = {}
result[key] = copyDeep item for key, item of value
result[key] = $copyDeep item for key, item of value
return result
return value
getDeep = (obj, path) ->
$getDeep = (obj, path) ->
return obj if path.length is 0
current = obj
@ -34,7 +35,7 @@ getDeep = (obj, path) ->
current[path[i]]
setDeep = (obj, path, value) ->
$setDeep = (obj, path, value) ->
throw new Error 'invalid path' if path.length is 0
current = obj
@ -50,7 +51,7 @@ setDeep = (obj, path, value) ->
# @param rule Rule of the current item.
# @param item Current item.
# @param value Value of the generator item.
computeValue = (rule, item, value) ->
$computeValue = (rule, item, value) ->
# @param parent The parent object of this entry (necessary for
# assignment).
@ -61,8 +62,8 @@ computeValue = (rule, item, value) ->
helper = (parent, name, spec) ->
if not $_.isObject spec
parent[name] = spec
else if spec instanceof DynamicProperty
# If there was no previous value use DynamicProperty.value,
else if spec instanceof $DynamicProperty
# If there was no previous value use $DynamicProperty.value,
# otherwise, just keep the previous value.
if parent[name] is undefined
# Helper is re-called for the initial value.
@ -85,7 +86,7 @@ computeValue = (rule, item, value) ->
######################################################################
class MappedCollection
class $MappedCollection
constructor: (spec) ->
@ -94,8 +95,8 @@ class MappedCollection
if $_.isFunction spec
ctx =
dynamic: (initialValue, hooks) ->
new DynamicProperty initialValue, hooks
noop: noop
new $DynamicProperty initialValue, hooks
noop: $noop
spec = spec.call ctx
@ -114,7 +115,7 @@ class MappedCollection
spec.rules or= {}
# Rules are the core of MappedCollection, they allow to categorize
# Rules are the core of $MappedCollection, they allow to categorize
# objects and to treat them differently.
@_rules = {}
@ -198,7 +199,7 @@ class MappedCollection
# If the value is a dynamic property, grabs the initial value
# and registers its hooks.
if value instanceof DynamicProperty
if value instanceof $DynamicProperty
hooks = value.hooks
# Browse hooks for each rules.
@ -220,7 +221,7 @@ class MappedCollection
# current rule.
for key, item of items
# Value of the current field.
field = getDeep item.value, path
field = $getDeep item.value, path
ctx = {rule, field}
ctx.__proto__ = item # Links to the current item.
@ -228,7 +229,7 @@ class MappedCollection
hook.call ctx, value, key
# Updates the value if it changed.
setDeep item.value, path if ctx.field isnt field
$setDeep item.value, path if ctx.field isnt field
# Checks each hook is correctly defined.
{enter, update, exit} = hooks_
@ -273,7 +274,7 @@ class MappedCollection
value: undefined
# Computes the value.
computeValue rule, item
$computeValue rule, item
# No events for static items.
@ -306,11 +307,10 @@ class MappedCollection
# Adds, updates or removes items from the collections. Items not
# present are added, present are updated, and present in the
# generated collection but not in the generator are removed.
set: (items, options = {}) ->
{add, update, remove} = options
set: (items, {add, update, remove} = {}) ->
add = true if add is undefined
update = true if update is undefined
remove = true if remove is undefined
remove = false if remove is undefined
itemsToRemove = {}
if remove
@ -329,7 +329,7 @@ class MappedCollection
rule = @_rules[item._ruleName]
# Compute the new value.
computeValue rule, item, value
$computeValue rule, item, value
# Runs related hooks.
for hook in @_hooks[rule.name]?.update or []
@ -351,7 +351,7 @@ class MappedCollection
value: undefined
# Computes the value.
computeValue rule, item, value
$computeValue rule, item, value
# Runs related hooks.
for hook in @_hooks[rule.name]?.enter or []
@ -369,6 +369,6 @@ class MappedCollection
# Removes effectively the item.
delete @_byKey[key] @_byRule[ruleName][key]
######################################################################
#=====================================================================
module.exports = MappedCollection
module.exports = $MappedCollection

View File

@ -1,3 +1,6 @@
# Low level tools.
$_ = require 'underscore'
# Async code is easier with fibers (light threads)!
$fiber = require 'fibers'
@ -8,15 +11,26 @@ $fiberize = (fn) ->
(args...) ->
$fiber(-> fn args...).run()
# Makes the fiber waits for a number of miliseconds.
$sleep = (ms) ->
fiber = $fiber.current
setTimeout (-> fiber.run()), ms
$fiber.yield()
# Makes an asynchrouneous function synchrouneous (in a fiber).
$synchronize = (fn) ->
$synchronize = (fn, ctx) ->
fn = ctx[fn] if $_.isString fn
(args...) ->
fiber = $fiber.current
fn args..., (error, result) ->
args.push (error, result) ->
if error?
fiber.throwInto error
else
fiber.run result
fn.apply ctx, args
$fiber.yield()
# TODO: remove promises ASAP.
@ -32,6 +46,7 @@ $waitForPromise = (promise) ->
module.exports = {
$fiberize
$sleep
$synchronize
$waitForPromise
}

View File

@ -13,9 +13,6 @@ $_ = require 'underscore'
# HTTP(s) middleware framework.
$connect = require 'connect'
# Async code is easier with fibers (light threads)!
$fiber = require 'fibers'
# Configuration handling.
$nconf = require 'nconf'

View File

@ -199,7 +199,10 @@ module.exports = (refsToUUIDs) ->
iSCSI_name: (value) -> value.other_config?.iscsi_iqn
memory: {} # TODO
memory: { # TODO
usage: 0
size: 0
}
power_state: 'Running' # TODO

View File

@ -1,20 +1,13 @@
# Async code is easier with fibers (light threads) and futures!
Fiber = require 'fibers'
Future = require 'fibers/future'
$xmlrpc = require 'xmlrpc'
xmlrpc = require 'xmlrpc'
#---------------------------------------------------------------------
# Helpers for dealing with fibers.
{$sleep, $synchronize} = require './fibers-utils'
#=====================================================================
sleep = (ms) ->
fiber = Fiber.current;
setTimeout (-> fiber.run()), ms
Fiber.yield()
#=====================================================================
# Note: All methods are synchroneous (using fibers), `.future()` may
# be used to make them asynchroneous.
# Note: All methods are synchroneous (using fibers).
class XAPI
constructor: ({@host, @username, @password}) ->
@ -28,12 +21,16 @@ class XAPI
# Makes sure there is not session id left.
delete @sessionId
@xmlrpc = xmlrpc.createSecureClient {
@xmlrpc = $xmlrpc.createSecureClient {
hostname: @host
port: '443'
rejectUnauthorized: false
}
# Make `methodCall()` synchroneous.
@xmlrpc.methodCall = $synchronize 'methodCall', @xmlrpc
# Logs in.
@logIn()
call: (method, args...) ->
@ -42,11 +39,8 @@ class XAPI
args.unshift @sessionId if @sessionId
do helper = =>
future = new Future()
@xmlrpc.methodCall method, args, future.resolver()
try
result = future.wait()
result = @xmlrpc.methodCall method, args
# Returns the plain result if it does not have a valid XAPI format.
return result unless result.Status?
@ -80,7 +74,7 @@ class XAPI
# I would like to be able to use a shorter delay but for some
# reason, when we connect to XAPI at a give moment, the
# connection hangs.
Fiber.sleep(500)
$sleep 500
helper()
# XAPI is sometimes reinitialized and sessions are lost.

View File

@ -9,9 +9,6 @@ $_ = require 'underscore'
# Password hasing.
$hashy = require 'hashy'
# Async code is easier with fibers (light threads)!
$fiber = require 'fibers'
# Redis.
$createRedisClient = (require 'then-redis').createClient
@ -21,9 +18,6 @@ $createRedisClient = (require 'then-redis').createClient
# specification.
$MappedCollection = require './MappedCollection'
# Collection where models are stored in memory.
$MemoryCollection = require './collection/memory'
# Collection where models are stored in a Redis DB.
$RedisCollection = require './collection/redis'
@ -38,34 +32,34 @@ $XAPI = require './xapi'
#=====================================================================
$randomBytes = $synchronize $crypto.randomBytes
$randomBytes = $synchronize 'randomBytes', $crypto
#=====================================================================
# Models and collections.
class Server extends $Model
class $Server extends $Model
validate: -> # TODO
class Servers extends $RedisCollection
model: Server
class $Servers extends $RedisCollection
model: $Server
#---------------------------------------------------------------------
class Token extends $Model
class $Token extends $Model
@generate: (userId) ->
new Token {
new $Token {
id: ($randomBytes 32).toString 'base64'
user_id: userId
}
validate: -> # TODO
class Tokens extends $RedisCollection
model: Token
class $Tokens extends $RedisCollection
model: $Token
#---------------------------------------------------------------------
class User extends $Model
class $User extends $Model
default: {
permission: 'none'
}
@ -97,11 +91,11 @@ class User extends $Model
perms[@get 'permission'] => perms[permission]
class Users extends $RedisCollection
model: User
class $Users extends $RedisCollection
model: $User
create: (email, password, permission) ->
user = new User {
user = new $User {
email: email
}
user.setPassword password
@ -111,24 +105,24 @@ class Users extends $RedisCollection
#=====================================================================
class XO
class $XO
start: (config) ->
# Connects to Redis.
redis = $createRedisClient config.redis.uri
# Creates persistent collections.
@servers = new Servers {
@servers = new $Servers {
connection: redis
prefix: 'xo:server'
indexes: ['host']
}
@tokens = new Tokens {
@tokens = new $Tokens {
connection: redis
prefix: 'xo:token'
indexes: ['host']
}
@users = new Users {
@users = new $Users {
connection: redis
prefix: 'xo:user'
indexes: ['host']
@ -277,4 +271,4 @@ class XO
#=====================================================================
module.exports = XO
module.exports = $XO