UNPKG

gearmanode-up

Version:

Node.js library for the Gearman distributed job system with support for multiple servers

246 lines (216 loc) 8.44 kB
// Copyright 2013 The GearmaNode Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /* * @fileoverview This script represents a set of utilities, helpers and convenience functions for internal use. * @author vaclav.sykora@google.com (Vaclav Sykora) * @namespace gearmanode/common */ var util = require('util'); /** * Verifies given options against a pattern that defines checks applied on each option. * <br/> * Usage:<br/> * <code>verifyOptions(optionsToBeVerified, {foo: 'mandatory', bar: [true, false], baz: 'optional'});</code> * * @function verifyOptions * @memberof gearmanode/common * @param options object to be verified * @param pattern object where property is an expected option's property and value can be<ul> * <li>'optional' - corresponding option may or may not be presented * <li>'mandatory' - corresponding option has to be presented * <li>Array - corresponding option has to be presented and value has to be in the given list * </ul> * @returns {error|object} error if expectation not accompished, otherwise the options */ exports.verifyOptions = function (options, pattern) { if (options === undefined || options == null) { return new Error('options not presented'); } if (pattern === undefined || pattern == null) { return new Error('pattern not presented'); } // unknown key? for (var key in options) { if (options.hasOwnProperty(key)) { if (!pattern.hasOwnProperty(key)) { return new Error('unknow option: ' + key); } // option in a set of allowed values if (util.isArray(pattern[key]) && pattern[key].indexOf(options[key]) === -1) { return new Error("value '" + options[key] + "' not in defined range, key=" + key); } } } // missing mandatory option? for (var key in pattern) { if (pattern.hasOwnProperty(key)) { if (pattern[key] === 'mandatory' && (!options.hasOwnProperty(key) || options[key] === undefined || options[key] == null)) { return new Error('missing mandatory option: ' + key); } if (util.isArray(pattern[key]) && !options.hasOwnProperty(key)) { return new Error('missing mandatory Array option: ' + key); } } } return options; }; /** * The same as <code>verifyOptions</code> with opportunity to define default values * of paramaters that will be set if missing in options. * Special values are:<ul> * <li>'null' which is considered as a desired value and will be NOT modified * <li>'undefined' which is considered as a missing value and will be modified * </ul> * Usage:<br/> * <code>verifyAndSanitizeOptions(optionsToBeVerified, {foo: 'defaultValue', bar: 100});</code> * * @function verifyAndSanitizeOptions * @memberof gearmanode/common * @param options object to be verified * @param pattern object where property is an expected option's property and value can be<ul> * <li>'optional' - corresponding option may or may not be presented * <li>'mandatory' - corresponding option has to be presented * <li>Array - corresponding option has to be presented and value has to be in the given list * <li>other value - default value set into options of corresponding key missing * </ul> * @returns {error|object} error if expectation not accompished, otherwise the options */ exports.verifyAndSanitizeOptions = function (options, pattern) { var returned = this.verifyOptions(options, pattern); if (returned instanceof Error) { return returned; } // set default values if missing in options for (var key in pattern) { if (pattern.hasOwnProperty(key)) { if (pattern[key] !== undefined && pattern[key] !== 'optional' && pattern[key] !== 'mandatory' && options[key] === undefined) { options[key] = pattern[key]; } } } return options; }; /** * Checks if the given value is a string literal or String object. * * @function isString * @memberof gearmanode/common * @param o object to be checked * @returns {boolean} <i>true</i> if the parameter is a string, otherwise <i>false</i> */ exports.isString = function (o) { return o !== undefined && o != null && (typeof o == 'string' || (typeof o == 'object' && o.constructor === String)); }; /** * Checks if the given value is a number literal or Number object. * * @function isNumber * @memberof gearmanode/common * @param o object to be checked * @returns {boolean} <i>true</i> if the parameter is a number, otherwise <i>false</i> */ exports.isNumber = function (o) { return o !== undefined && o != null && (typeof o == 'number' || (typeof o == 'object' && o.constructor === Number)); }; /** * Creates a shallow copy of an object. * * @function clone * @memberof gearmanode/common * @param from object to be copied * @returns shallow copy of the input argument */ exports.clone = function (from) { if (from !== Object(from)) { return from; } // not an object if (Array.isArray(from)) { return from.slice(); } return exports.mixin(from, {}); }; /** * Mixes in properties from source to destination * and so allows objects to borrow (or inherit) functionality from them with a minimal amount of complexity. * * @function mixin * @memberof gearmanode/common * @param source object where properties will be copied from * @param destination object where properties will be copied to * @returns the destination object */ exports.mixin = function (source, destination) { // #unit: TODO test it for (var k in source) { if (source.hasOwnProperty(k)) { destination[k] = source[k]; } } return destination; }; /** * Converts given buffer to space separated string of hexadecimal values of byte array. * * @function bufferAsHex * @memberof gearmanode/common * @param {Buffer} buff to be converted * @param {Number} maxLen * @returns {string} textual representation of given buffer */ exports.bufferAsHex = function (buff, maxLen) { // #unit: TODO test it var rslt = ''; if (maxLen === undefined || maxLen == null) { maxLen = 40; } for (var i = 0; i < buff.length && i < maxLen; i ++) { var num = new Number(buff.readUInt8(i)); rslt += num.toString(16); if (i < (buff.length - 1)) { rslt += ' '} } return rslt; }; /** * Null function used for default values of callbacks, etc. * * @function nullFunction * @memberof gearmanode/common * @type {Function} * @returns {void} Nothing */ exports.nullFunction = function() {}; // #unit: not needed /** * Can be used as a default implementation of an abstract method. * There's no need to define such function in JS, but I do anyway because of importance of documentation. * * @function abstractMethod * @memberof gearmanode/common * @type {Function} * @return {void} Nothing * @throws {Error} when invoked to indicate the method should be overridden */ exports.abstractMethod = function() { // #unit: not needed throw new Error('unimplemented abstract method'); }; /** * Get UUID based on RFC 4122, section 4.4 (Algorithms for Creating a UUID from Truly Random or Pseudo-Random Number). * * @function createUUID * @memberof gearmanode/common * @returns {string} textual UUID */ exports.createUUID = function () { // http://www.ietf.org/rfc/rfc4122.txt var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = "-"; return uuid = s.join(""); };