Skip to content

Instantly share code, notes, and snippets.

@rtsisyk
Last active December 12, 2015 02:58
Show Gist options
  • Save rtsisyk/4702667 to your computer and use it in GitHub Desktop.
Save rtsisyk/4702667 to your computer and use it in GitHub Desktop.
Tarantool/BOX + JavaScript HOWTO

Tarantool/Box + JavaScript HOWTO

Feature Stability: early alpha

Tarantool/Box is an in-memory database designed to store the most volatile and highly accessible web content. Tarantool/Box has been extensively used in production since 2009. It's open source, BSD licensed.

http://tarantool.org/

Installation

Get && install libv8 library with development files:

~ $ svn checkout http://v8.googlecode.com/svn/trunk/ v8
~ $ cd v8
~/v8 $ make dependencies
~/v8 $ make native werror=no library=shared -j8
~/v8 $ install -o root include/* /usr/local/include
~/v8 $ install -o root out/native/lib.target/libv8.so /usr/local/lib

Check http://code.google.com/p/v8/wiki/BuildingWithGYP for more details.

Version 3.20.14 is tested (head ChangeLog -n 1). Version older than 3.19 is now compatible due to V8 API changes.

Clone tarantool-js repository:

~ $ git clone https://github.com/rtsisyk/tarantool tarantool-js 
~/tarantool_js $ cd tarantool-js
~/tarantool_js $ git checkout js

Compile Tarantool/Box with JavaScript support

~/tarantool_js $ cmake . -DENABLE_JS=ON
~/tarantool_js $ make

Note: make -jN is known to be broken

Clone content of this gist to the test/var directory

~/tarantool_js $ cd test
~/tarantool_js $ git clone https://gist.github.com/4702667.git var

Run Tarantool/Box from the test/var/ directory

~/tarantool_js $ cd test/var
~/tarantool_js/test/var $ ../../src/box/tarantool_box --init-storage
~/tarantool_js/test/var $ ../../src/box/tarantool_box

Usage

You can use JavaScript mostly like Lua:

~$ tarantool
localhost> js 2 + 2
---
4
...
localhost> js Date()
---
Sun Feb 03 2013 20:43:06 GMT+0700 (NOVST)
...
localhost> js throw Error('message')
---
JS error: Error: dsfsa
...

To load module use require function:

localhost> js console = require('console');
---
[object Object]
...
localhost> js console.log('Hey You!')
---
undefined <!-- Message printed to the Tarantool's log
...

Our require mostly works like Node.JS's analog. By default Tarantool/Box lookups a module in the its modules cache, then checks the list of built-in modules and finally tries to scan your script_dir.

A small subset of Node.JS modules is already supported:

localhost> js util = require('node_util');
---
[object Object]
...
localhost> js util.format("%s %d", "String", 12)
---
String 12
...

Tarantool/Box tries to find and load init module on the start. All global variables from the module is accesable from the admin console.

Global Objects

Tarantool/Box exports only one global function to JavaScript - require. All other built-in modules can be loaded via this method require.

Built-in modules

  • platform - platform-specific things needed for implementation
  • require - require functions itself
  • fiber module for working with Tarantool/Box fibers
  • box - interface to the Tarantool/Box transaction processor (is not ready yet)

Module 'require'

Example:

~/tarantool_js/test/var $ cat console.js
exports.log = function(msg) {
    /* some code */
}

~/tarantool_js/test/var $ tarantool
localhost> js console = require('console');
---
[object Object]
...
localhost> console.log('Hey You!')
...

~/tarantool_js/test/var $ tail -n 100 tarantool.log
2013-02-03 21:03:22.754 [13130] 101/js-init-library I> Loading new JS module 'console' from './console.js'

Module 'fiber'

Example:

fiber = require('fiber')

function body1(msg, count)
{
    console.log("In Fiber: " + this.id);

    var k = 0;
    for (var i = 0; i < count; i++) {
        console.log("Hello from fiber: " + msg);
        fiber.sleep(1.0)
    }

    return 48;
}

f1 = new fiber(body1, "Hello", 10)
f2 = new fiber(body1, "Hey", 5)
console.log("f1.id = " + f1.id)

TypedArray (built-in module)

See https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays

Example:


buffer = new Int8Array(1024)
buffer[0] = 2;

Questions

/*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
var platform = require('platform');
exports.debug = function(msg) {
platform.say(platform.say.DEBUG, msg)
}
exports.info = function(msg) {
platform.say(platform.say.INFO, msg)
}
exports.warn = function(msg) {
platform.say(platform.say.WARN, msg)
}
exports.crit = function(msg) {
platform.say(platform.say.CRIT, msg)
}
exports.error = function(msg) {
platform.say(platform.say.ERROR, msg)
}
exports.fatal = function(msg) {
platform.say(platform.say.FATAL, msg)
}
exports.log = exports.info;
/*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* 1. Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Require
*/
console = require('console');
console.log('Hello from JS');
/*
* Test a module with native object
*/
stub = require('stub')
s = new stub()
console.log("stub.add => " + s.add(10))
console.log("stub.add => " + s.add(15))
/* Export the function to IPROTO */
exports.test = function(a, b) {
return a + b;
}
/*
* Try to load node.js module
*/
util = require('node_util')
console.log("node.js module test: " + util + " " + util.format("%s %d", "util.format", 1));
/*
* Fibers
*/
fiber = require('fiber')
function body1(msg, count)
{
console.log("In Fiber: " + this.id);
var k = 0;
for (var i = 0; i < count; i++) {
console.log("Hello from fiber: " + msg);
fiber.sleep(1.0)
}
return 48;
}
f1 = new fiber(body1, "Hello", 10)
f2 = new fiber(body1, "Hey", 5)
console.log("f1.id = " + f1.id)
/*
* Array
* @see https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays
*/
buffer = new Int8Array(1024)
buffer[0] = 0;
buffer[1023] = 1023;
buffer[1024] = 1024;
console.log("buffer[0] = " + buffer[0])
console.log("buffer[1023] = " + buffer[1023])
console.log("buffer[1024] = " + buffer[1024])
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
process = {}; /* is not implemented yet */
var formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (typeof f !== 'string') {
var objects = [];
for (var i = 0; i < arguments.length; i++) {
objects.push(inspect(arguments[i]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j': return JSON.stringify(args[i++]);
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (x === null || typeof x !== 'object') {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
// Mark that a method should not be used.
// Returns a modified function which warns once by default.
// If --no-deprecation is set, then it is a no-op.
exports.deprecate = function(fn, msg) {
if (process.noDeprecation === true) {
return fn;
}
var warned = false;
function deprecated() {
if (!warned) {
if (process.traceDeprecation) {
console.trace(msg);
} else {
console.error(msg);
}
warned = true;
}
return fn.apply(this, arguments);
}
return deprecated;
};
exports.print = function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stdout.write(String(arguments[i]));
}
};
exports.puts = function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stdout.write(arguments[i] + '\n');
}
};
exports.debug = function(x) {
process.stderr.write('DEBUG: ' + x + '\n');
};
var error = exports.error = function(x) {
for (var i = 0, len = arguments.length; i < len; ++i) {
process.stderr.write(arguments[i] + '\n');
}
};
/**
* Echos the value of a value. Trys to print the value out
* in the best way possible given the different types.
*
* @param {Object} obj The object to print out.
* @param {Object} opts Optional options object that alters the output.
*/
/* legacy: obj, showHidden, depth, colors*/
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (typeof opts === 'boolean') {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (typeof ctx.showHidden === 'undefined') ctx.showHidden = false;
if (typeof ctx.depth === 'undefined') ctx.depth = 2;
if (typeof ctx.colors === 'undefined') ctx.colors = false;
if (typeof ctx.customInspect === 'undefined') ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold' : [1, 22],
'italic' : [3, 23],
'underline' : [4, 24],
'inverse' : [7, 27],
'white' : [37, 39],
'grey' : [90, 39],
'black' : [30, 39],
'blue' : [34, 39],
'cyan' : [36, 39],
'green' : [32, 39],
'magenta' : [35, 39],
'red' : [31, 39],
'yellow' : [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][1] + 'm';
} else {
return str;
}
}
function stylizeNoColor(str, styleType) {
return str;
}
function arrayToHash(array) {
var hash = {};
array.forEach(function(val, idx) {
hash[val] = true;
});
return hash;
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect && value && typeof value.inspect === 'function' &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
return String(value.inspect(recurseTimes));
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (typeof value === 'function') {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (typeof value === 'function') {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
if (keys.length === 0 && (!array || value.length == 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function(key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function formatPrimitive(ctx, value) {
switch (typeof value) {
case 'undefined':
return ctx.stylize('undefined', 'undefined');
case 'string':
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
case 'number':
return ctx.stylize('' + value, 'number');
case 'boolean':
return ctx.stylize('' + value, 'boolean');
}
// For some reason typeof null is "object", so special case here.
if (value === null) {
return ctx.stylize('null', 'null');
}
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function(key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (recurseTimes === null) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function(line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (typeof name === 'undefined') {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'");
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
// NOTE: These type checking functions intentionally don't use `instanceof`
// because it is fragile and can be easily faked with `Object.create()`.
function isArray(ar) {
return Array.isArray(ar) ||
(typeof ar === 'object' && objectToString(ar) === '[object Array]');
}
exports.isArray = isArray;
function isRegExp(re) {
return typeof re === 'object' && objectToString(re) === '[object RegExp]';
}
exports.isRegExp = isRegExp;
function isDate(d) {
return typeof d === 'object' && objectToString(d) === '[object Date]';
}
exports.isDate = isDate;
function isError(e) {
return typeof e === 'object' && objectToString(e) === '[object Error]';
}
exports.isError = isError;
function objectToString(o) {
return Object.prototype.toString.call(o);
}
exports.p = exports.deprecate(function() {
for (var i = 0, len = arguments.length; i < len; ++i) {
error(exports.inspect(arguments[i]));
}
}, 'util.p: Use console.error() instead.');
function pad(n) {
return n < 10 ? '0' + n.toString(10) : n.toString(10);
}
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
'Oct', 'Nov', 'Dec'];
// 26 Feb 16:19:34
function timestamp() {
var d = new Date();
var time = [pad(d.getHours()),
pad(d.getMinutes()),
pad(d.getSeconds())].join(':');
return [d.getDate(), months[d.getMonth()], time].join(' ');
}
exports.log = function(msg) {
exports.puts(timestamp() + ' - ' + msg.toString());
};
exports.exec = exports.deprecate(function() {
return require('child_process').exec.apply(this, arguments);
}, 'util.exec is now called `child_process.exec`.');
function pump(readStream, writeStream, callback) {
var callbackCalled = false;
function call(a, b, c) {
if (callback && !callbackCalled) {
callback(a, b, c);
callbackCalled = true;
}
}
readStream.addListener('data', function(chunk) {
if (writeStream.write(chunk) === false) readStream.pause();
});
writeStream.addListener('drain', function() {
readStream.resume();
});
readStream.addListener('end', function() {
writeStream.end();
});
readStream.addListener('close', function() {
call();
});
readStream.addListener('error', function(err) {
writeStream.end();
call(err);
});
writeStream.addListener('error', function(err) {
readStream.destroy();
call(err);
});
}
exports.pump = exports.deprecate(pump,
'util.pump() is deprecated. Use readableStream.pipe() instead.');
/**
* Inherit the prototype methods from one constructor into another.
*
* The Function.prototype.inherits from lang.js rewritten as a standalone
* function (not on Function.prototype). NOTE: If this file is to be loaded
* during bootstrapping this function needs to be rewritten using some native
* functions as prototype setup using normal JavaScript does not work as
* expected during bootstrapping (see mirror.js in r114903).
*
* @param {function} ctor Constructor function which needs to inherit the
* prototype.
* @param {function} superCtor Constructor function to inherit prototype from.
*/
exports.inherits = function(ctor, superCtor) {
ctor.super_ = superCtor;
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true
}
});
};
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || typeof add !== 'object') return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
2013-08-09 19:07:41.038 [25941] 1/sched D> v8 TLS run-time hack works - all 3 keys have been detected
2013-08-09 19:07:41.038 [25941] 1/sched D> v8 pthread's TLS <-> fiber's FLS mapping:
2013-08-09 19:07:41.038 [25941] 1/sched D> 0 => 0
2013-08-09 19:07:41.038 [25941] 1/sched D> 1 => 1
2013-08-09 19:07:41.038 [25941] 1/sched D> 2 => 2
2013-08-09 19:07:41.048 [25941] 1/sched I> space 0 successfully configured
2013-08-09 19:07:41.048 [25941] 1/sched I> recovery start
2013-08-09 19:07:41.048 [25941] 1/sched I> recover from `./00000000000000000001.snap'
2013-08-09 19:07:41.048 [25941] 1/sched D> log_io_cursor_next: marker:0x00000000BA0BABED/4
2013-08-09 19:07:41.048 [25941] 1/sched D> eof while looking for magic
2013-08-09 19:07:41.048 [25941] 1/sched I> snapshot recovered, confirmed lsn: 1
2013-08-09 19:07:41.048 [25941] 1/sched I> building secondary indexes
2013-08-09 19:07:41.048 [25941] 1/sched I> bound to port 33013
2013-08-09 19:07:41.048 [25941] 1/sched I> I am primary
2013-08-09 19:07:41.048 [25941] 1/sched I> bound to port 33014
2013-08-09 19:07:41.048 [25941] 1/sched D> wal_writer_thread: locking &writer->mutex
2013-08-09 19:07:41.048 [25941] 1/sched I> bound to port 33015
2013-08-09 19:07:41.048 [25941] 101/js-init-library D> js enable
2013-08-09 19:07:41.048 [25941] 101/js-init-library D> js create locker
2013-08-09 19:07:41.050 [25941] 101/js-init-library I> Loading new JS module 'init' from './init.js'
2013-08-09 19:07:41.050 [25941] 101/js-init-library I> Loading new JS module 'console' from './console.js'
2013-08-09 19:07:41.051 [25941] 101/js-init-library I> Hello from JS
2013-08-09 19:07:41.051 [25941] 101/js-init-library stub.cc:90 W> new: 0xbb8960
2013-08-09 19:07:41.051 [25941] 101/js-init-library I> stub.add => 10
2013-08-09 19:07:41.051 [25941] 101/js-init-library I> stub.add => 25
2013-08-09 19:07:41.051 [25941] 101/js-init-library I> Loading new JS module 'node_util' from './node_util.js'
2013-08-09 19:07:41.054 [25941] 101/js-init-library I> node.js module test: [object Object] util.format 1
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js fiber pause hook
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js create unlocker
2013-08-09 19:07:41.054 [25941] 102/js D> js enable
2013-08-09 19:07:41.054 [25941] 102/js D> js create locker
2013-08-09 19:07:41.054 [25941] 102/js D> js fiber pause hook
2013-08-09 19:07:41.054 [25941] 102/js D> js create unlocker
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js fiber resume hook
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js delete unlocker
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js fiber pause hook
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js create unlocker
2013-08-09 19:07:41.054 [25941] 103/js D> js enable
2013-08-09 19:07:41.054 [25941] 103/js D> js create locker
2013-08-09 19:07:41.054 [25941] 103/js D> js fiber pause hook
2013-08-09 19:07:41.054 [25941] 103/js D> js create unlocker
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js fiber resume hook
2013-08-09 19:07:41.054 [25941] 101/js-init-library D> js delete unlocker
2013-08-09 19:07:41.054 [25941] 101/js-init-library I> f1.id = 102
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> buffer[0] = 0
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> buffer[1023] = -1
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> buffer[1024] = undefined
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> List of exported methods:
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> test
2013-08-09 19:07:41.055 [25941] 101/js-init-library I> End of the list.
2013-08-09 19:07:41.055 [25941] 101/js-init-library D> js fiber pause hook
2013-08-09 19:07:41.055 [25941] 101/js-init-library D> js create unlocker
2013-08-09 19:07:41.055 [25941] 101/js-init-library D> js fiber stop hook
2013-08-09 19:07:41.055 [25941] 101/js-init-library D> js delete unlocker
2013-08-09 19:07:41.055 [25941] 101/js-init-library D> js delete locker
2013-08-09 19:07:41.055 [25941] 1/sched C> log level 5
2013-08-09 19:07:41.055 [25941] 1/sched C> entering event loop
2013-08-09 19:07:41.055 [25941] 102/js D> js fiber resume hook
2013-08-09 19:07:41.055 [25941] 102/js D> js delete unlocker
2013-08-09 19:07:41.055 [25941] 102/js I> In Fiber: 102
2013-08-09 19:07:41.055 [25941] 102/js I> Hello from fiber: Hello
2013-08-09 19:07:41.055 [25941] 102/js D> js fiber pause hook
2013-08-09 19:07:41.055 [25941] 102/js D> js create unlocker
2013-08-09 19:07:41.055 [25941] 103/js D> js fiber resume hook
2013-08-09 19:07:41.055 [25941] 103/js D> js delete unlocker
2013-08-09 19:07:41.055 [25941] 103/js I> In Fiber: 103
2013-08-09 19:07:41.055 [25941] 103/js I> Hello from fiber: Hey
2013-08-09 19:07:41.055 [25941] 103/js D> js fiber pause hook
2013-08-09 19:07:41.055 [25941] 103/js D> js create unlocker
2013-08-09 19:07:41.055 [25941] 1/sched D> js idle
2013-08-09 19:07:41.057 [25941] 1/sched D> js idle
2013-08-09 19:07:41.058 [25941] 1/sched D> js idle
2013-08-09 19:07:41.059 [25941] 1/sched D> js idle
2013-08-09 19:07:41.060 [25941] 1/sched D> js idle
2013-08-09 19:07:41.061 [25941] 1/sched D> js idle
2013-08-09 19:07:41.063 [25941] 1/sched D> js idle
2013-08-09 19:07:42.056 [25941] 102/js D> js fiber resume hook
2013-08-09 19:07:42.056 [25941] 102/js D> js delete unlocker
2013-08-09 19:07:42.056 [25941] 102/js I> Hello from fiber: Hello
2013-08-09 19:07:42.056 [25941] 102/js D> js fiber pause hook
2013-08-09 19:07:42.056 [25941] 102/js D> js create unlocker
2013-08-09 19:07:42.056 [25941] 103/js D> js fiber resume hook
2013-08-09 19:07:42.056 [25941] 103/js D> js delete unlocker
2013-08-09 19:07:42.056 [25941] 103/js I> Hello from fiber: Hey
2013-08-09 19:07:42.056 [25941] 103/js D> js fiber pause hook
2013-08-09 19:07:42.056 [25941] 103/js D> js create unlocker
2013-08-09 19:07:42.056 [25941] 1/sched D> js idle
2013-08-09 19:07:42.884 [25941] 1/sched C> exiting loop
2013-08-09 19:07:42.884 [25941] 1/sched D> wal_writer_stop: locking &writer->mutex
2013-08-09 19:07:42.884 [25941] 1/sched D> wal_writer_stop: unlocking &writer->mutex
2013-08-09 19:07:42.884 [25941] 1/sched D> wal_writer_thread: unlocking &writer->mutex
2013-08-09 19:07:42.884 [25941] 1/sched D> wal_writer_thread: locking &writer->mutex
2013-08-09 19:07:42.884 [25941] 1/sched D> wal_writer_thread: unlocking &writer->mutex
#
# Limit of memory used to store tuples to 100MB
# (0.1 GB)
# This effectively limits the memory, used by
# Tarantool. However, index and connection memory
# is stored outside the slab allocator, hence
# the effective memory usage can be higher (sometimes
# twice as high).
#
slab_alloc_arena = 0.1
#
# Store the pid in this file. Relative to
# startup dir.
#
pid_file = "box.pid"
#
# Pipe the logs into the following process.
#
logger="cat - >> tarantool.log"
log_level = 5
script_dir = "."
#
# Read only and read-write port.
primary_port = 33013
# Read-only port.
secondary_port = 33014
#
# The port for administrative commands.
#
admin_port = 33015
#
# Each write ahead log contains this many rows.
# When the limit is reached, Tarantool closes
# the WAL and starts a new one.
rows_per_wal = 50
# Define a simple space with 1 HASH-based
# primary key.
space[0].enabled = 1
space[0].index[0].type = "HASH"
space[0].index[0].unique = 1
space[0].index[0].key_field[0].fieldno = 0
space[0].index[0].key_field[0].type = "NUM"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment