NodeJS Package-UUID IDX AMQPLIB
UUID
https://github.com/kelektiv/node-uuid
Support version 1, 3, 4, 5 UUIDs
Current latest version is
> npm info uuid version
3.2.1
Install that library in global
> sudo npm install -g uuid
Generate UUID
>uuid
a63b5d3b-b80a-480b-ab56-8ba7bb043d68
>uuid v1
1ea16090-3bfc-11e8-9d47-9194247d340e
In the TypeScript Code, first of all, configure TypeScript Support on Sublime Text3
https://cmatskas.com/getting-started-with-typescript-and-sublime-text/
Package Control —> Install Package —> TypeScript
import * as uuidv4 from 'uuid/v4';
//version 4 is random
const meetingUuid = paramsToSend.UUID = uuidv4();
IDX
https://github.com/facebookincubator/idx
Traverse properties on objects and arrays.
Current Version
> npm info idx version
2.2.0
From Readme
type User = {
user: ?{
name: string,
friends: ?Array<User>,
}
};
props.user && props.user.friends && props.user.friends[0] && props.user.friends[0].friends, my first friends’s friends
Import idx from ‘idx’;
idx(props, _ => _.user.friends[0].friends)
APIGatewayEvent event;
const loginSession = idx(event, _ => { return (_ as any).loginSession; } );
AMQP.NODE
amqplib https://github.com/squaremo/amqp.node
Current Version
> npm info amqplib version
0.5.2
We are using CallbackAPI in our Project
var q = 'tasks';
function bail(err) {
console.error(err);
process.exit(1);
}
// Publisher
function publisher(conn) {
conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.sendToQueue(q, new Buffer('something to do'));
}
}
// Consumer
function consumer(conn) {
var ok = conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.consume(q, function(msg) {
if (msg !== null) {
console.log(msg.content.toString());
ch.ack(msg);
}
});
}
}
require('amqplib/callback_api')
.connect('amqp://localhost', function(err, conn) {
if (err != null) bail(err);
consumer(conn);
publisher(conn);
});
Promise API
Ignore, not that clear to me.
Detail in Example
https://segmentfault.com/a/1190000008229467
https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
More Complex One
https://www.cloudamqp.com/blog/2015-05-19-part2-2-rabbitmq-for-beginners_example-and-sample-code-node-js.html
Reconnect when There is Error
function start() {
amqp.connect(process.env.CLOUDAMQP_URL + “?heartbeat=60”, function(err, conn) {
if (err) {
console.error(“{AMQP]”, err.message);
return setTimeout(start, 1000);
}
conn.on(“error”, function(err) {
if (err.message !== “Connection closing”) {
console.error(“[AMQP] conn error”, err.message);
}
});
conn.on(“close”, function() {
console.error(“[AMQP] reconnecting”);
return setTimeout(start, 1000);
});
console.log(“[AMQP] connected”);
amqpConn = conn;
whenConnected();
});
}
function whenConnected() {
startPublisher();
startWorker();
}
Publisher
var pubChannel = null;
var offlinePubQueue = [];
function startPublisher() {
amqpConn.createConfirmChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
pubChannel = ch;
while (true) {
var m = offlinePubQueue.shift();
if (!m) break;
publish(m[0], m[1], m[2]);
}
});
}
function publish(exchange, routingKey, content) {
try {
pubChannel.publish(exchange, routingKey, content, { persistent: true },
function(err, ok) {
if (err) {
console.error("[AMQP] publish", err);
offlinePubQueue.push([exchange, routingKey, content]);
pubChannel.connection.close();
}
});
} catch (e) {
console.error("[AMQP] publish", e.message);
offlinePubQueue.push([exchange, routingKey, content]);
}
}
Publish fails, it will put the message back to the internal queue.
Consumer
// A worker that acks messages only if processed successfully
function startWorker() {
amqpConn.createChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
ch.prefetch(10);
ch.assertQueue("jobs", { durable: true }, function(err, _ok) {
if (closeOnErr(err)) return;
ch.consume("jobs", processMsg, { noAck: false });
console.log("Worker is started");
});
});
}
function processMsg(msg) {
work(msg, function(ok) {
try {
if (ok)
ch.ack(msg);
else
ch.reject(msg, true);
} catch (e) {
closeOnErr(e);
}
});
}
function work(msg, cb) {
console.log("PDF processing of ", msg.content.toString());
cb(true);
}
Other Methods
function closeOnErr(err) {
if (!err) return false;
console.error("[AMQP] error", err);
amqpConn.close();
return true;
}
Main Methods
setInterval(function() {
publish("", "jobs", new Buffer("work work work"));
}, 1000);
start();
References:
https://github.com/kelektiv/node-uuid
https://github.com/facebookincubator/idx
https://www.npmjs.com/package/idx
https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html
https://www.cloudamqp.com/blog/2015-05-19-part2-2-rabbitmq-for-beginners_example-and-sample-code-node-js.html
https://github.com/squaremo/amqp.node
UUID
https://github.com/kelektiv/node-uuid
Support version 1, 3, 4, 5 UUIDs
Current latest version is
> npm info uuid version
3.2.1
Install that library in global
> sudo npm install -g uuid
Generate UUID
>uuid
a63b5d3b-b80a-480b-ab56-8ba7bb043d68
>uuid v1
1ea16090-3bfc-11e8-9d47-9194247d340e
In the TypeScript Code, first of all, configure TypeScript Support on Sublime Text3
https://cmatskas.com/getting-started-with-typescript-and-sublime-text/
Package Control —> Install Package —> TypeScript
import * as uuidv4 from 'uuid/v4';
//version 4 is random
const meetingUuid = paramsToSend.UUID = uuidv4();
IDX
https://github.com/facebookincubator/idx
Traverse properties on objects and arrays.
Current Version
> npm info idx version
2.2.0
From Readme
type User = {
user: ?{
name: string,
friends: ?Array<User>,
}
};
props.user && props.user.friends && props.user.friends[0] && props.user.friends[0].friends, my first friends’s friends
Import idx from ‘idx’;
idx(props, _ => _.user.friends[0].friends)
APIGatewayEvent event;
const loginSession = idx(event, _ => { return (_ as any).loginSession; } );
AMQP.NODE
amqplib https://github.com/squaremo/amqp.node
Current Version
> npm info amqplib version
0.5.2
We are using CallbackAPI in our Project
var q = 'tasks';
function bail(err) {
console.error(err);
process.exit(1);
}
// Publisher
function publisher(conn) {
conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.sendToQueue(q, new Buffer('something to do'));
}
}
// Consumer
function consumer(conn) {
var ok = conn.createChannel(on_open);
function on_open(err, ch) {
if (err != null) bail(err);
ch.assertQueue(q);
ch.consume(q, function(msg) {
if (msg !== null) {
console.log(msg.content.toString());
ch.ack(msg);
}
});
}
}
require('amqplib/callback_api')
.connect('amqp://localhost', function(err, conn) {
if (err != null) bail(err);
consumer(conn);
publisher(conn);
});
Promise API
Ignore, not that clear to me.
Detail in Example
https://segmentfault.com/a/1190000008229467
https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html
More Complex One
https://www.cloudamqp.com/blog/2015-05-19-part2-2-rabbitmq-for-beginners_example-and-sample-code-node-js.html
Reconnect when There is Error
function start() {
amqp.connect(process.env.CLOUDAMQP_URL + “?heartbeat=60”, function(err, conn) {
if (err) {
console.error(“{AMQP]”, err.message);
return setTimeout(start, 1000);
}
conn.on(“error”, function(err) {
if (err.message !== “Connection closing”) {
console.error(“[AMQP] conn error”, err.message);
}
});
conn.on(“close”, function() {
console.error(“[AMQP] reconnecting”);
return setTimeout(start, 1000);
});
console.log(“[AMQP] connected”);
amqpConn = conn;
whenConnected();
});
}
function whenConnected() {
startPublisher();
startWorker();
}
Publisher
var pubChannel = null;
var offlinePubQueue = [];
function startPublisher() {
amqpConn.createConfirmChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
pubChannel = ch;
while (true) {
var m = offlinePubQueue.shift();
if (!m) break;
publish(m[0], m[1], m[2]);
}
});
}
function publish(exchange, routingKey, content) {
try {
pubChannel.publish(exchange, routingKey, content, { persistent: true },
function(err, ok) {
if (err) {
console.error("[AMQP] publish", err);
offlinePubQueue.push([exchange, routingKey, content]);
pubChannel.connection.close();
}
});
} catch (e) {
console.error("[AMQP] publish", e.message);
offlinePubQueue.push([exchange, routingKey, content]);
}
}
Publish fails, it will put the message back to the internal queue.
Consumer
// A worker that acks messages only if processed successfully
function startWorker() {
amqpConn.createChannel(function(err, ch) {
if (closeOnErr(err)) return;
ch.on("error", function(err) {
console.error("[AMQP] channel error", err.message);
});
ch.on("close", function() {
console.log("[AMQP] channel closed");
});
ch.prefetch(10);
ch.assertQueue("jobs", { durable: true }, function(err, _ok) {
if (closeOnErr(err)) return;
ch.consume("jobs", processMsg, { noAck: false });
console.log("Worker is started");
});
});
}
function processMsg(msg) {
work(msg, function(ok) {
try {
if (ok)
ch.ack(msg);
else
ch.reject(msg, true);
} catch (e) {
closeOnErr(e);
}
});
}
function work(msg, cb) {
console.log("PDF processing of ", msg.content.toString());
cb(true);
}
Other Methods
function closeOnErr(err) {
if (!err) return false;
console.error("[AMQP] error", err);
amqpConn.close();
return true;
}
Main Methods
setInterval(function() {
publish("", "jobs", new Buffer("work work work"));
}, 1000);
start();
References:
https://github.com/kelektiv/node-uuid
https://github.com/facebookincubator/idx
https://www.npmjs.com/package/idx
https://www.cloudamqp.com/blog/2015-05-18-part1-rabbitmq-for-beginners-what-is-rabbitmq.html
https://www.cloudamqp.com/blog/2015-05-19-part2-2-rabbitmq-for-beginners_example-and-sample-code-node-js.html
https://github.com/squaremo/amqp.node