Seneca’s Open Source Orbit: Telescope
As Seneca’s Telescope continues its development, more and more challenges are faced. For this week I have chosen to work on the database part of the application, specifically on the Redis constructor for the Bull queue. Let’s get started!
Realizing the Goal
First of all, what is Bull and why do we need a queue? Well, Bull is a popular Open Source library providing a Redis-based queue for Node. In Telescope, it used to line up the feed of blogposts fetched from various blogging platforms. Originally, it was set up in the following way:
function createQueue(name) {
const log = logger.child({ module: `queue:${name}` });
const queue = new Bull(name, {
createClient: type => {
switch (type) {
case 'client':
return client;
case 'subscriber':
return subscriber;
default:
return new Redis(redisUrl);
}
},
})
// ...
}
Prototyping
As you can see, the Redis data store is created with using only url
. One of the downsides of such a solution is the lack of security. Of course, Redis comes up with a number of options for you on how to construct the database. After browsing the docs, I have found the following. The Redis object can be constructed as new Redis([port], [host], [options])
, with options
including password
.
Implementing
Therefore, in order to use this constructor, we needed to do a number of things:
- Parse
port
andhost
from theRedisUrl
- Add
password
property to the config file
The first step can be easily achieved by using the Node’s url.parse
method:
const { port, host } = url.parse(redisUrl, true);
For the second step we just set up the prototype for the config file:
REDIS_PASSWORD=YourUnguessablePassowrdHere
Afterwards, we need to create function which would do all of the work for us, including the error handling:
function createRedisClient() {
try {
const { port, host } = url.parse(redisUrl, true);
return new RedisConstructor(port, host, { password: process.env.REDIS_PASSWORD });
} catch (err) {
const message = `Unable to parse port and host from "${redisUrl}"`;
logger.error({ err }, message);
throw new Error(message);
}
}
Lastly, we just export our function through module.exports
.
Outcome
After a round of tests and improvements the code started to work as expected. The update has now been introduced to the project through a PR.We can now specify a secure connection to our Redis database!