<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>redis &amp;mdash; Simple Engineering</title>
    <link>https://getsimple.works/tag:redis</link>
    <description></description>
    <pubDate>Tue, 28 Apr 2026 14:53:47 +0000</pubDate>
    <item>
      <title>How to modularize redis clients </title>
      <link>https://getsimple.works/how-to-modularize-redis-clients?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Modularization of redis for testability&#xA;&#xA;To take advantage of multicore systems, nodejs -- being a single-threaded JavaScript runtime -- spins up multiple processes to guarantee parallel processing capabilities. That works well until inter-process communication becomes an issue.&#xA;&#xA;That is where key-stores such as redis come into the picture, to solve the inter-process communication problem while enhancing real-time experience. &#xA;&#xA;This article is about showcasing how to achieve leverage modular design to provide testable and scalable code. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;How to modularize redis clients for reusability  &#xA;How to modularize redis clients for testability &#xA;How to modularize redis clients for composability &#xA;The need to have a redis powered pub/sub &#xA;Techniques to modularize redis powered pub/sub&#xA;The need to coupling WebSocket with redis pub/subsystem&#xA;How to modularize WebSocket redis communications &#xA;How to modularize redis configuration &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;Introducing extra components makes it hard to test a system in isolation. This example highlights some of the moving parts we will be discussing in this article:   &#xA;&#xA;//creating the Server -- alternative #1 &#xA;var app = express();&#xA;var server = Server(app);&#xA;&#xA;//creating the Server -- alternative #2&#xA;var express = require(&#39;express&#39;),&#xA;    app = express(),&#xA;    server = require(&#39;http&#39;).createServer(app);&#xA;&#xA;//Initialization of WebSocket Server + Redis Pub/Sub    &#xA;var wss = require(&#34;socket.io&#34;)(server),&#xA;&#x9;redis = require(&#39;redis&#39;), &#xA;&#x9;rhost = process.env.REDISHOST,&#xA;&#x9;rport = process.env.REDISPORT,&#xA;&#x9;pub = redis.createClient(rport, rhost), &#xA;  sub = redis.createClient(rport, rhost);&#xA;  &#xA;//HTTP session middleware thing&#xA;function middleware(req, res, next){&#xA; ...&#xA; next();&#xA;}&#xA;&#xA;//exchanging session values &#xA;wss.use(function(socket, next){&#xA; &#x9;middleware(socket.request, socket.request.res, next);&#xA;});&#xA;&#xA;//express uses middleware for session management&#xA;app.use(middleware);&#xA;    &#xA;//somewhere&#xA;wss.sockets.on(&#34;connection&#34;, function(socket) {&#xA; &#xA; //socket.request.session &#xA; //Now it&#39;s available from Socket.IO sockets too! Win!&#xA; socket.on(&#39;message&#39;, (event) =  {&#xA;&#x9; var payload = JSON.parse(event.payload || event),&#xA;&#x9; &#x9;user = socket.handshake.user || false;&#xA;&#x9; &#xA;&#x9; //except when coming from pub  &#x9;&#x9;&#x9;&#xA;&#x9; pub.publish(payload.conversation, payload)); &#xA; });&#xA;&#xA; //redis listener&#xA; sub.on(&#39;message&#39;, function(channel, event) {&#xA;&#x9;var payload = JSON.parse(event.payload || event),&#xA;&#x9;&#x9;user = socket.handshake.user || false;&#xA;    wss.&#xA;      sockets.&#xA;      in(payload.conversation).&#xA;      emit(&#39;message&#39;, payload);&#xA; });&#xA;Example:&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;Having redis.createClient() everywhere, makes it hard to mock&#xA;creation/deletion of redis instances(pub/sub) is out of control&#xA;&#xA;  One way is to create One instance (preferably while loading top-level module), and inject that instance into dependent modules - Managing modularity and redis connections in nodejs. - The other way: node module loader caches loaded modules. Which provides a singleton by default.&#xA;&#xA;The need to have a redis powered pub/sub &#xA;&#xA;JavaScript, and nodejs in particular, is a single-threaded language -- but has other ways to provide parallel computing. &#xA;&#xA;It is possible to spin up any number of processes depending on application needs. The process to process communication becomes an issue, and when one process mutates the state of a shared object, for instance, any other process on the same server would have to be informed about the update. &#xA;&#xA;Unfortunately, that is not feasible. pub/sub mechanisms that redis brings to the table, make it possible to solve problems similar to this one.  &#xA;&#xA;    &#xA;&#xA;How to modularize redis clients for testability &#xA;&#xA;pub/sub implementations make the code intimidating, especially when the time comes to test. &#xA;&#xA;We assume that existing code has little to no test, and most importantly, not modularized. Or well tested, and well modularized, but the addition of real-time handling adds a need to leverage pub/sub to provide near real-time experience. &#xA;&#xA;The first and easy thing to do in such a scenario is to break code blocks into smaller chunks that we can test in isolation. &#xA;&#xA;In essence, the pub and sub are both redis clients, that have to be created independently so that they run in two separate contexts and processes. We may be tempted to use pub and sub-objects as the same client, that would be detrimental and create race conditions from the get-go.  &#xA;Delegating pub/sub-creation to a utility function makes it possible to mock the clients.&#xA;The utility function should accept injected redis. It is possible to go the extra mile and delegate redis instance initialization in its own factory. That way, it becomes even easier to mock the redis instance itself.  &#xA;&#xA;Past these steps, other refactoring techniques can take over. &#xA;&#xA;// hard to mock when located in [root]/index.js  &#xA;var redis = require(&#39;redis&#39;), &#xA;&#x9;rhost = process.env.REDISHOST,&#xA;&#x9;rport = process.env.REDISPORT,&#xA;&#x9;pub = redis.createClient(rport, rhost), &#xA;  sub = redis.createClient(rport, rhost);&#xA;&#xA;// Easy to mock with introduction of createClient factory&#xA;// in /lib/util/redis.js|redis-helper.js&#xA;module.exports = function(redis){&#xA;    return redis.createClient(port, host);&#xA;}&#xA;How to modularize redis clients for reusability &#xA;&#xA;The example provided in this article scratches the surface on what can be achieved when integrating redis into a project. &#xA;&#xA;What would be the chain of events if, for some reason, redis server goes down. Would that affect the overall health and usability of the whole application? &#xA;&#xA;If the answer is yes, or not sure, that gives a pretty good indication of the need to isolate usage of redis, and make sure its modularity is sound and failure-proof. &#xA;&#xA;Modularization of the redis can be seen from two angles: to publish a set of events to the shared store, subscribing to the shared store for updates on events of our interest. &#xA;&#xA;By making the redis integration modular, we also have to think about making sure redis server downtime/failure, does not translate into a cascading effect that may bring the application down. &#xA;&#xA;//in app|server|index.js   &#xA;var client = require(&#34;redis&#34;).createClient(); &#xA;var app = require(&#34;./lib&#34;)(client);//&lt;- Injection&#xA;&#xA;//injecting redis into a route&#xA;var createClient = require(&#39;./lib/util/redis&#39;);&#xA;module.exports = function(redis){&#xA;  return function(req, res, next){&#xA;    var redisClient = createClient(redis);&#xA;    return res.status(200).json({message: &#39;About Issues&#39;});&#xA;  };&#xA;};&#xA;&#xA;//usage&#xA;var getMessage = require(&#39;./&#39;)(redis);&#xA;&#xA;How to modularize redis clients for composability &#xA;&#xA;In the previous two sections, we have seen how pub/sub enhanced by a redis server brings near real-time experience to the program. &#xA;&#xA;The problem we faced in both sections, is that redis is tightly coupled to all modules, even those that do not need to use it. &#xA;&#xA;Composability becomes an issue when we need to avoid having a single point of failure in the program, as well as providing a test coverage deep enough to prevent common use cases of failures.  &#xA;&#xA;// in /lib/util/redis&#xA;const redis = require(&#39;redis&#39;);&#xA;module.exports = function(options){&#xA;  return options ?  {} : redis;&#xA;}&#xA;&#xA;The above small factory may look a little weird, but it makes it possible to offset initialization to a third-party service and becomes possible to mock when testing. &#xA;&#xA;Techniques to modularize redis powered pub/sub &#xA;&#xA;The need to modularize the pub/sub code has been discussed in previous segments. &#xA;&#xA;The issue we still have at this time is at pub/sub handler level. As we may have noticed already, testing pub/sub handlers is challenging especially when not having an up and running redis instance. &#xA;&#xA;Modularizing that two kinds of handlers provide an opportunity to test pub/sub handlers in isolation. It also makes it possible to share the handlers with other systems that may need exactly the same kind of behavior. &#xA;&#xA;The need to lose coupling WebSocket with redis pub/sub system &#xA;&#xA;One example of decoupling pub/sub from redis and make its handlers re-usable, can be seen when the WebSocket server has to leverage socket server events. &#xA;&#xA;For example, on a new message read on the socket, the socket server should notify other processes that there is in fact a new message on the socket. &#xA;&#xA;The pub is the right place to post this kind of notification. On a new message posted in the store, the WebSocket server may need to respond to a particular user. and so forth.  &#xA;&#xA;How to modularize WebSocket redis communications &#xA;&#xA;There is a use case where an infinite same message can be ping-pong-ed between pub and sub. &#xA;&#xA;To make sure such a thing doesn&#39;t happen, a communication protocol should be initialized. For example, when a message is published to the store by a WebSocket and the message is destined to all participating processes, a corresponding listener should read from the store and forward the message to all participating sockets, In such a way a socket that receives the message simply publishes it but does not answer to the sender right away. &#xA;&#xA;Subscribed sockets, can then read from the store, and forward the message to the right receiver. &#xA;&#xA;  There is an entire blog dedicated to modularizing nodejs WebSockets here&#xA;&#xA;How modularize redis configuration &#xA;&#xA;The need to configure a server comes not only for redis server but also for any other server or service. &#xA;&#xA;In this particular instance, we will see how we can include redis configuration into an independent module that can then be used with the rest of the configurations.  &#xA;&#xA;//from the example above &#xA;const redis = require(&#34;redis&#34;); &#xA;const port = process.ENV.REDISPORT || &#34;6379&#34;;&#xA;const host = process.ENV.REDISHOST || &#34;127.0.0.1&#34;;&#xA;module.exports = redis.createClient(port, host);&#xA;&#xA;//abstracting configurations in lib/configs&#xA;module.exports = Object.freeze({ &#xA;  redis: {&#xA;    port: process.ENV.REDISPORT || &#34;6379&#34;,&#xA;    port: process.ENV.REDISHOST || &#34;127.0.0.1&#34;&#xA;  }&#xA;});&#xA;&#xA;//using an abstracted configurations&#xA;const configs = require(&#39;./lib/configs&#39;);&#xA;module.exports = redis.createClient(&#xA;  configs.redis.port, &#xA;  configs.redis.host&#xA;);&#xA; &#xA;  This strategy to rethink, application structure has been found here&#xA;&#xA;Conclusion&#xA;&#xA;Modularization is a key strategy in crafting re-usable composable software. Modularization brings not only elegance but makes copy/paste detectors happy, and at the same time improves both performance and testability. &#xA;&#xA;In this article, we revisited how to aggregate WebSocket code into composable and testable modules. The need to group related tasks into modules involves the ability to add support of Pub/Sub on demand and using various solutions as project requirements evolve. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book.  &#xA;&#xA;References + Reading List&#xA;&#xA;Testing nodejs Applications book&#xA;redis pubsub library ~ A Github cloned library&#xA;Building a Chat Server with node and redis - tests ~ Matthew Daly Blog&#xA;High Volume, low latency difficulties nodejs/pubsub/redis ~ StackOverflow Question&#xA;examples using redis-store with socket.io ~ StackOverflow Question&#xA;Using redis as PubSub over socket.io ~ StackOverflow Question&#xA;socket.io-redis ~ Github Library&#xA;socket.io within concurrent processes ~ Tolle Iv Blog&#xA;Modularize Your Chat App(or How to Write a nodejs Express App in More Than One File) ~ Philosophy is Thinking Medium&#xA;bacon.js + nodejs + mongodb: Functional Reactive Programming on the Server ~ Carbon Five Blog&#xA;NODE.JS DATABASES: USING REDIS FOR FUN AND PROFIT&#xA;&#xA;tags: #snippets #redis #nodejs #modularization&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p><strong><em>Modularization of <code>redis</code> for testability</em></strong></p>

<p>To take advantage of multicore systems, <code>nodejs</code> — being a single-threaded <code>JavaScript</code> runtime — spins up multiple processes to guarantee parallel processing capabilities. That works well until inter-process communication becomes an issue.</p>

<p>That is where key-stores such as <code>redis</code> come into the picture, to solve the inter-process communication problem while enhancing real-time experience.</p>

<p>This article is about showcasing how to achieve leverage modular design to provide testable and scalable code.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>How to modularize <code>redis</code> clients for reusability<br/></li>
<li>How to modularize <code>redis</code> clients for testability</li>
<li>How to modularize <code>redis</code> clients for composability</li>
<li>The need to have a <code>redis</code> powered pub/sub</li>
<li>Techniques to modularize <code>redis</code> powered pub/sub</li>
<li>The need to coupling WebSocket with <code>redis</code> pub/subsystem</li>
<li>How to modularize WebSocket <code>redis</code> communications</li>
<li>How to modularize <code>redis</code> configuration</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<p>Introducing extra components makes it hard to test a system in isolation. This example highlights some of the moving parts we will be discussing in this article:</p>

<pre><code class="language-JavaScript">//creating the Server -- alternative #1 
var app = express();
var server = Server(app);

//creating the Server -- alternative #2
var express = require(&#39;express&#39;),
    app = express(),
    server = require(&#39;http&#39;).createServer(app);

//Initialization of WebSocket Server + Redis Pub/Sub    
var wss = require(&#34;socket.io&#34;)(server),
	redis = require(&#39;redis&#39;), 
	rhost = process.env.REDIS_HOST,
	rport = process.env.REDIS_PORT,
	pub = redis.createClient(rport, rhost), 
  sub = redis.createClient(rport, rhost);
  
//HTTP session middleware thing
function middleware(req, res, next){
 ...
 next();
}

//exchanging session values 
wss.use(function(socket, next){
 	middleware(socket.request, socket.request.res, next);
});

//express uses middleware for session management
app.use(middleware);
    
//somewhere
wss.sockets.on(&#34;connection&#34;, function(socket) {
 
 //socket.request.session 
 //Now it&#39;s available from Socket.IO sockets too! Win!
 socket.on(&#39;message&#39;, (event) =&gt; {
	 var payload = JSON.parse(event.payload || event),
	 	user = socket.handshake.user || false;
	 
	 //except when coming from pub  			
	 pub.publish(payload.conversation, payload)); 
 });

 //redis listener
 sub.on(&#39;message&#39;, function(channel, event) {
	var payload = JSON.parse(event.payload || event),
		user = socket.handshake.user || false;
    wss.
      sockets.
      in(payload.conversation).
      emit(&#39;message&#39;, payload);
 });
</code></pre>

<p><em><em>Example</em>:</em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>
<ul><li>Having <code>redis.createClient()</code> everywhere, makes it hard to mock</li>
<li>creation/deletion of <code>redis</code> instances(pub/sub) is out of control</li></ul>

<blockquote><p>One way is to create One instance (preferably while loading top-level module), and inject that instance into dependent modules – <a href="https://medium.com/@stockholmux/managing-modularity-and-redis-connections-in-node-js-eb9232f8c1ba">Managing modularity and <code>redis</code> connections in nodejs</a>. – The other way: node module loader caches loaded modules. Which provides a singleton by default.</p></blockquote>

<h2 id="the-need-to-have-a-redis-powered-pub-sub" id="the-need-to-have-a-redis-powered-pub-sub">The need to have a <code>redis</code> powered pub/sub</h2>

<p>JavaScript, and <code>nodejs</code> in particular, is a single-threaded language — but has other ways to provide parallel computing.</p>

<p>It is possible to spin up any number of processes depending on application needs. The process to process communication becomes an issue, and when one process mutates the state of a shared object, for instance, any other process on the same server would have to be informed about the update.</p>

<p>Unfortunately, that is not feasible. <code>pub/sub</code> mechanisms that <code>redis</code> brings to the table, make it possible to solve problems similar to this one.</p>

<h2 id="how-to-modularize-redis-clients-for-testability" id="how-to-modularize-redis-clients-for-testability">How to modularize <code>redis</code> clients for testability</h2>

<p><code>pub/sub</code> implementations make the code intimidating, especially when the time comes to test.</p>

<p>We assume that existing code has little to no test, and most importantly, not modularized. Or well tested, and well modularized, but the addition of real-time handling adds a need to leverage <code>pub/sub</code> to provide near real-time experience.</p>

<p>The first and easy thing to do in such a scenario is to break code blocks into smaller chunks that we can test in isolation.</p>
<ul><li>In essence, the <code>pub</code> and <code>sub</code> are both <code>redis</code> clients, that have to be created independently so that they run in two separate contexts and processes. We may be tempted to use pub and sub-objects as the same client, that would be detrimental and create race conditions from the get-go.<br/></li>
<li>Delegating pub/sub-creation to a utility function makes it possible to mock the clients.</li>
<li>The utility function should accept injected <code>redis</code>. It is possible to go the extra mile and delegate <code>redis</code> instance initialization in its own factory. That way, it becomes even easier to mock the <code>redis</code> instance itself.<br/></li></ul>

<p>Past these steps, other refactoring techniques can take over.</p>

<pre><code class="language-JavaScript">// hard to mock when located in [root]/index.js  
var redis = require(&#39;redis&#39;), 
	rhost = process.env.REDIS_HOST,
	rport = process.env.REDIS_PORT,
	pub = redis.createClient(rport, rhost), 
  sub = redis.createClient(rport, rhost);

// Easy to mock with introduction of createClient factory
// in /lib/util/redis.js|redis-helper.js
module.exports = function(redis){
    return redis.createClient(port, host);
}
</code></pre>

<h2 id="how-to-modularize-redis-clients-for-reusability" id="how-to-modularize-redis-clients-for-reusability">How to modularize <code>redis</code> clients for reusability</h2>

<p>The example provided in this article scratches the surface on what can be achieved when integrating <code>redis</code> into a project.</p>

<p>What would be the chain of events if, for some reason, <code>redis</code> server goes down. Would that affect the overall health and usability of the whole application?</p>

<p>If the answer is yes, or not sure, that gives a pretty good indication of the need to isolate usage of <code>redis</code>, and make sure its modularity is sound and failure-proof.</p>

<p>Modularization of the <code>redis</code> can be seen from two angles: to publish a set of events to the shared store, subscribing to the shared store for updates on events of our interest.</p>

<p>By making the <code>redis</code> integration modular, we also have to think about making sure <code>redis</code> server downtime/failure, does not translate into a cascading effect that may bring the application down.</p>

<pre><code class="language-JavaScript">//in app|server|index.js   
var client = require(&#34;redis&#34;).createClient(); 
var app = require(&#34;./lib&#34;)(client);//&lt;- Injection

//injecting redis into a route
var createClient = require(&#39;./lib/util/redis&#39;);
module.exports = function(redis){
  return function(req, res, next){
    var redisClient = createClient(redis);
    return res.status(200).json({message: &#39;About Issues&#39;});
  };
};

//usage
var getMessage = require(&#39;./&#39;)(redis);
</code></pre>

<h2 id="how-to-modularize-redis-clients-for-composability" id="how-to-modularize-redis-clients-for-composability">How to modularize <code>redis</code> clients for composability</h2>

<p>In the previous two sections, we have seen how <code>pub/sub</code> enhanced by a <code>redis</code> server brings near real-time experience to the program.</p>

<p>The problem we faced in both sections, is that <code>redis</code> is tightly coupled to all modules, even those that do not need to use it.</p>

<p>Composability becomes an issue when we need to avoid having a single point of failure in the program, as well as providing a test coverage deep enough to prevent common use cases of failures.</p>

<pre><code class="language-JavaScript">// in /lib/util/redis
const redis = require(&#39;redis&#39;);
module.exports = function(options){
  return options ?  {} : redis;
}
</code></pre>

<p>The above small factory may look a little weird, but it makes it possible to offset initialization to a third-party service and becomes possible to mock when testing.</p>

<h2 id="techniques-to-modularize-redis-powered-pub-sub" id="techniques-to-modularize-redis-powered-pub-sub">Techniques to modularize <code>redis</code> powered pub/sub</h2>

<p>The need to modularize the <code>pub/sub</code> code has been discussed in previous segments.</p>

<p>The issue we still have at this time is at <code>pub/sub</code> handler level. As we may have noticed already, testing <code>pub/sub</code> handlers is challenging especially when not having an up and running <code>redis</code> instance.</p>

<p>Modularizing that two kinds of handlers provide an opportunity to test <code>pub/sub</code> handlers in isolation. It also makes it possible to share the handlers with other systems that may need exactly the same kind of behavior.</p>

<h2 id="the-need-to-lose-coupling-websocket-with-redis-pub-sub-system" id="the-need-to-lose-coupling-websocket-with-redis-pub-sub-system">The need to lose coupling WebSocket with <code>redis</code> pub/sub system</h2>

<p>One example of decoupling <code>pub/sub</code>from <code>redis</code> and make its handlers re-usable, can be seen when the WebSocket server has to leverage socket server events.</p>

<p>For example, on a new message read on the socket, the socket server should notify other processes that there is in fact a new message on the socket.</p>

<p>The <code>pub</code> is the right place to post this kind of notification. On a new message posted in the store, the WebSocket server may need to respond to a particular user. and so forth.</p>

<h2 id="how-to-modularize-websocket-redis-communications" id="how-to-modularize-websocket-redis-communications">How to modularize WebSocket <code>redis</code> communications</h2>

<p>There is a use case where an infinite same message can be <em>ping-pong</em>-ed between pub and sub.</p>

<p>To make sure such a thing doesn&#39;t happen, a communication protocol should be initialized. For example, when a message is published to the store by a WebSocket and the message is destined to all participating processes, a corresponding listener should read from the store and forward the message to all participating sockets, In such a way a socket that receives the message simply publishes it but does not answer to the sender right away.</p>

<p>Subscribed sockets, can then read from the store, and forward the message to the right receiver.</p>

<blockquote><p>There is an entire blog dedicated to <a href="./how-to-modularize-socket-io-expressjs-application">modularizing <code>nodejs</code> WebSockets here</a></p></blockquote>

<h2 id="how-modularize-redis-configuration" id="how-modularize-redis-configuration">How modularize <code>redis</code> configuration</h2>

<p>The need to configure a server comes not only for <code>redis</code> server but also for any other server or service.</p>

<p>In this particular instance, we will see how we can include <code>redis</code> configuration into an independent module that can then be used with the rest of the configurations.</p>

<pre><code class="language-JavaScript">//from the example above 
const redis = require(&#34;redis&#34;); 
const port = process.ENV.REDIS_PORT || &#34;6379&#34;;
const host = process.ENV.REDIS_HOST || &#34;127.0.0.1&#34;;
module.exports = redis.createClient(port, host);

//abstracting configurations in lib/configs
module.exports = Object.freeze({ 
  redis: {
    port: process.ENV.REDIS_PORT || &#34;6379&#34;,
    port: process.ENV.REDIS_HOST || &#34;127.0.0.1&#34;
  }
});

//using an abstracted configurations
const configs = require(&#39;./lib/configs&#39;);
module.exports = redis.createClient(
  configs.redis.port, 
  configs.redis.host
);
</code></pre>

<blockquote><p>This strategy to rethink, application structure has been <a href="https://stackoverflow.com/a/43038690/132610">found here</a></p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>Modularization is a key strategy in crafting re-usable composable software. Modularization brings not only elegance but makes copy/paste detectors happy, and at the same time improves both performance and testability.</p>

<p>In this article, we revisited how to aggregate WebSocket code into composable and testable modules. The need to group related tasks into modules involves the ability to add support of Pub/Sub on demand and using various solutions as project requirements evolve. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references-reading-list" id="references-reading-list">References + Reading List</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li><code>redis</code> <code>pubsub</code> library ~ <a href="https://github.com/murindwaz/redispubsub">A Github cloned library</a></li>
<li>Building a Chat Server with node and <code>redis</code> – tests ~ <a href="https://matthewdaly.co.uk/blog/2014/12/31/building-a-chat-server-with-node-dot-js-and-redis/">Matthew Daly Blog</a></li>
<li>High Volume, low latency difficulties <code>nodejs</code>/<code>pubsub</code>/<code>redis</code> ~ <a href="https://stackoverflow.com/questions/10557826/node-js-socket-io-redis-pub-sub-high-volume-low-latency-difficulties">StackOverflow Question</a></li>
<li>examples using <code>redis-store</code> with <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/9267292/examples-in-using-redisstore-in-socket-io">StackOverflow Question</a></li>
<li>Using <code>redis</code> as PubSub over <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/32743754/using-redis-as-pubsub-over-socket-io">StackOverflow Question</a></li>
<li><code>socket.io-redis</code> ~ <a href="https://github.com/socketio/socket.io-redis">Github Library</a></li>
<li><code>socket.io</code> within concurrent processes ~ <a href="https://blog.tolleiv.de/2014/05/socket-dot-io-within-concurrent-processes/">Tolle Iv Blog</a></li>
<li>Modularize Your Chat App(or How to Write a <code>nodejs</code> Express App in More Than One File) ~ <a href="https://medium.com/philosophie-is-thinking/modularize-your-chat-app-or-how-to-write-a-node-js-express-app-in-more-than-one-file-bfae2d6b69df#.hfb4r6z3i">Philosophy is Thinking Medium</a></li>
<li><code>bacon.js</code> + <code>nodejs</code> + <code>mongodb</code>: Functional Reactive Programming on the Server ~ <a href="https://blog.carbonfive.com/2014/09/23/bacon-js-node-js-mongodb-functional-reactive-programming-on-the-server/">Carbon Five Blog</a></li>
<li><a href="https://blog.yld.io/2016/11/07/node-js-databases-using-redis-for-fun-and-profit/#.WrL_7pMbPUI">NODE.JS DATABASES: USING REDIS FOR FUN AND PROFIT</a></li></ul>

<p>tags: <a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:redis" class="hashtag"><span>#</span><span class="p-category">redis</span></a> <a href="https://getsimple.works/tag:nodejs" class="hashtag"><span>#</span><span class="p-category">nodejs</span></a> <a href="https://getsimple.works/tag:modularization" class="hashtag"><span>#</span><span class="p-category">modularization</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/how-to-modularize-redis-clients</guid>
      <pubDate>Thu, 17 Jun 2021 05:32:50 +0000</pubDate>
    </item>
    <item>
      <title>Easy nodejs deployment</title>
      <link>https://getsimple.works/easy-nodejs-deployment?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[This article is going to explore how to deploy a nodejs application on a traditional linux server -- in a non-cloud environment. Even though the use case is Ubuntu, any Linux distro or mac would work perfectly fine. &#xA;&#xA;  For information on deploying on non-traditional servers, read: &#34;Deploying nodejs applications&#34;. For zero-downtime knowledge, read  &#34;How to achieve zero downtime deployment with nodejs&#34; &#xA;&#xA;In this article we will talk about: &#xA;&#xA;Preparing nodejs deployable releases &#xA;Configuring nodejs deployment environment &#xA;Deploying nodejs application on bare metal Ubuntu server &#xA;Switching on nodejs application to be available to the world ~ adding nginx for the reverse proxy to make the application available to the world&#xA;post-deployment support -- production support &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book book, the content can help any software developer to level up their knowledge. You may use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Preparing a deployable release&#xA;&#xA;There are several angles to look at release and deployment from. There are also several ways to release nodejs code, npm and tar for instance, and that depending on the environment in which the code is designed to run. Amongst environments, server-side, universal, or command line are classic examples.&#xA;&#xA;In addition, we have to take a look from a dependency management perspective. Managing dependencies at deployment time has two vectors to take into account: whether the deployment happens on online or offline. &#xA;&#xA;  For the code to be prepared for release, it has to be packaged. Two methods of packaging nodejs software, amongst other things, are managed packaging and bundling. More on this is discussed here&#xA;&#xA;As a plus, versioning should be taken into consideration when preparing a deployable release. The versioning that is a little common circulation is SemVer. &#xA;&#xA;Configuring deployment environment &#xA;&#xA;Before we dive into deployment challenges, let&#39;s look at key software and configuration requirements. &#xA;&#xA;As usual, first-time work can be hard to do. But the yield should be then predictable, flexible to improvement, and capable of being built-upon for future deployments. For context, the deployment environment we are talking about in this section is the production environment.  &#xA;&#xA;Two key configurations are an nginx reverse proxy server and nodejs. But, &#34;Why coupling nodejs server to an nginx reverse proxy server&#34;? The answer to this question is two folds. First, both nodejs and nginx are single-threaded non-blocking reactive systems. Second, the wide adoption of these two tools by the developer community makes it an easy choice, from both influence and availability of collective knowledge the developer community shares via forums/blogs and popular QA sites. &#xA;&#xA;  How to install nginx server ~ there is an article dedicated to this. How to configure nginx as a nodejs application proxy server ~ there is an article dedicated to this. &#xA;&#xA;Additional tools to install and configure may include: mongod database server, redis server, monit for monitoring, upstart for enhancing the init system.&#xA;&#xA;There is a need to better understand the tools required to run nodejs application. It is also our responsibility as developers to have a basic understanding of each tool and the roles it plays in our project, in order to figure out how to configure each tool.&#xA;&#xA;Download source code&#xA;&#xA;Starting from the utility perspective, there is quite a collection of tools that are required to run on the server, alongside our nodejs application. Such software needs to be installed, and updated ~ for patch releases, and upgraded ~ to new major versions to keep the system secure and capable(bug-free/enhanced with new features).&#xA;&#xA;From the packaging perspective, both supporting tools and nodejs applications adhere to a packaging strategy that makes it easy to deploy. When packaging is indeed a bundle, wget/curl can be used to download binaries. When dealing with discoverable packages, npm/yarn/brew can also be used to download our application and its dependencies. Both operation yield same outcomes, which is un-packaging, configuration and installation.&#xA;&#xA;To deploy versioned nodejs application on bare metal Ubuntu server  ~ understanding file system tweaks such as symlink-ing for faster deployments can save time for future deployments.&#xA;&#xA;first time on server side  &#xA;$ apt-get update&#xA;$ apt-get install git&#xA;&#xA;updating|upgrading server side code&#xA;$ apt-get update&#xA;$ apt-get upgrade&#xA;$ brew upgrade &#xA;$ npm upgrade &#xA;&#xA;Package download and installs &#xA;$ /bin/bash -c &#34;$(curl -fsSL https://url.tld/version/install.sh)&#34;&#xA;$ wget -O - https://url.tld/version/install.sh | bash&#xA;&#xA;Discoverable packages &#xA;$ npm install application@next &#xA;$ yarn add application@next &#xA;$ brew install application&#xA;Example: &#xA;&#xA;  The command above can be automated via a scheduled task. Both npm and yarn support the installation of applications bundled in a .tar file. See an example of a simple script source. We have to be mindful to clean up download directories, to save disk space. &#xA;&#xA;Switching on the application &#xA;&#xA;It sounds repetitive, but running npm start does not guarantee the application to be visible outside the metal server box the application is hosted on. This magic belongs to the nginx reverse proxy we were referring to in earlier paragraphs. &#xA;&#xA;A typical nodejs application needs to start one or more of the following services, each time to reboot the application. &#xA;&#xA;symlinking new version to default application path&#xA;$ ln -sfn /var/www/new/version/appname /var/www/appname &#xA;&#xA;$ service nginx restart #nginx|apache server&#xA;$ service redis restart #redis server&#xA;$ service restart mongod #database server in some cases&#xA;$ service appname restart #application itself&#xA;Example:&#xA;&#xA;  PS: Above services are managed with uptime&#xA;&#xA;Adding nginx reverse proxy makes the application available to the outside world. Switching on/off the application can be summarized in one command: service nginx stop. Likewise, to switch off and back on can be issued in one command: service nginx restart.&#xA;&#xA;Post-deployment support &#xA;&#xA;Asynchronous timely tasks can be used to resolve a wide range of issues. Background tasks such as fetching updates from third-party data providers, system health check, and notifications, automated software updates, database cleaning, cache busting, scheduled expensive/CPU intensive batch processing jobs just to name a few. &#xA;&#xA;It is possible to leverage existing asynchronous timely OS-provided tasks processing infrastructure to achieve any of the named use cases, as it is true for third-party tools to do exactly the same job. &#xA;&#xA;Rule of thumb&#xA;&#xA;The following is a mental model that can be applied to the common use cases of releases. It may be basic for DevOps professionals, but useful enough for developers doing some operations work as well. &#xA;&#xA;Prepare deployable releases&#xA;Update and install binaries ~ using apt, brew etc.  &#xA;Download binaries ~ using git,wget, curl or brew&#xA;symlink directories(/log, /config, /app)&#xA;Restart  servers and services ~ redis, nginx, mongodb and app &#xA;When something goes bad ~ walk two steps back. That is our rollback strategy.  &#xA;&#xA;  This model can be refined, to make most of these tasks repeatable and automated, deployments included. &#xA;&#xA;Conclusion &#xA;&#xA;In this article, we revisited quick easy, and most basic nodejs deployment strategies. We also revisited how to expose the deployed applications to the world using nginx as a reverse proxy server. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;How to set up CI/CD Pipeline for a nodejs app with Jenkins ~ Moshe Ezderman - Medium&#xA;&#34;Build your dependencies into your deployable packages&#34;&#xA;&#xA;#snippets #code #annotations #question #discuss]]&gt;</description>
      <content:encoded><![CDATA[<p>This article is going to explore how to deploy a <code>nodejs</code> application on a traditional <code>linux</code> server — in a non-cloud environment. Even though the use case is Ubuntu, any Linux <em>distro</em> or <code>mac</code> would work perfectly fine.</p>

<blockquote><p>For information on deploying on non-traditional servers, read: <strong><em><a href="./deploying-nodejs-application">“Deploying <code>nodejs</code> applications”</a></em></strong>. For zero-downtime knowledge, read  <strong><em><a href="./achieving-nodejs-zero-downtime">“How to achieve zero downtime deployment with <code>nodejs</code>“</a></em></strong></p></blockquote>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li>Preparing <code>nodejs</code> deployable releases</li>
<li>Configuring <code>nodejs</code> deployment environment</li>
<li>Deploying <code>nodejs</code> application on bare metal Ubuntu server</li>
<li>Switching on <code>nodejs</code> application to be available to the world ~ adding <code>nginx</code> for the reverse proxy to make the application available to the world</li>
<li>post-deployment support — production support</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong> book, the content can help any software developer to level up their knowledge. <strong><em><a href="https://bit.ly/2ZFJytb">You may use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="preparing-a-deployable-release" id="preparing-a-deployable-release">Preparing a deployable release</h2>

<p>There are several angles to look at release and deployment from. There are also several ways to release <code>nodejs</code> code, <code>npm</code> and <code>tar</code> for instance, and that depending on the environment in which the code is designed to run. Amongst environments, server-side, universal, or command line are classic examples.</p>

<p>In addition, we have to take a look from a dependency management perspective. Managing dependencies at deployment time has two vectors to take into account: whether the deployment happens on <strong><em>online</em></strong> or <strong><em>offline</em></strong>.</p>

<blockquote><p>For the code to be prepared for release, it has to be packaged. Two methods of packaging <code>nodejs</code> software, amongst other things, are managed packaging and bundling. <a href="./deploying-nodejs-applications#reducing-friction">More on this is discussed here</a></p></blockquote>

<p>As a plus, versioning should be taken into consideration when preparing a deployable release. The versioning that is a little common circulation is <strong><em>SemVer</em></strong>.</p>

<h2 id="configuring-deployment-environment" id="configuring-deployment-environment">Configuring deployment environment</h2>

<p>Before we dive into deployment challenges, let&#39;s look at key software and configuration requirements.</p>

<p>As usual, first-time work can be hard to do. But the yield should be then predictable, flexible to improvement, and capable of being built-upon for future deployments. For context, the deployment environment we are talking about in this section is the production environment.</p>

<p>Two key configurations are an <code>nginx</code> reverse proxy server and <code>nodejs</code>. But, <em>“Why coupling <code>nodejs</code> server to an <code>nginx</code> reverse proxy server”</em>? The answer to this question is two folds. First, both <code>nodejs</code> and <code>nginx</code> are single-threaded non-blocking reactive systems. Second, the wide adoption of these two tools by the developer community makes it an easy choice, from both influence and availability of collective knowledge the developer community shares via forums/blogs and popular QA sites.</p>

<blockquote><p>How to install <code>nginx</code> server ~ [there is an article dedicated to this](). How to configure <code>nginx</code> as a <code>nodejs</code> application proxy server ~ <a href="./how-to-configure-nodejs-applications#configure-nginx-to-serve-nodejs-application">there is an article dedicated to this</a>.</p></blockquote>

<p>Additional tools to install and configure may include: <code>mongod</code> database server, <code>redis</code> server, <a href="https://mmonit.com/monit/#home"><code>monit</code></a> for monitoring, <a href="http://upstart.ubuntu.com/download.html"><code>upstart</code></a> for enhancing the <code>init</code> system.</p>

<p>There is a need to better understand the tools required to run <code>nodejs</code> application. It is also our responsibility as developers to have a basic understanding of each tool and the roles it plays in our project, in order to figure out how to configure each tool.</p>

<h2 id="download-source-code" id="download-source-code">Download source code</h2>

<p>Starting from the utility perspective, there is quite a collection of tools that are required to run on the server, alongside our <code>nodejs</code> application. Such software needs to be installed, and updated ~ for patch releases, and upgraded ~ to new major versions to keep the system secure and capable(bug-free/enhanced with new features).</p>

<p>From the packaging perspective, both supporting tools and <code>nodejs</code> applications adhere to a packaging strategy that makes it easy to deploy. When packaging is indeed a bundle, <code>wget</code>/<code>curl</code> can be used to download binaries. When dealing with discoverable packages, <code>npm</code>/<code>yarn</code>/<code>brew</code> can also be used to download our application and its dependencies. Both operation yield same outcomes, which is un-packaging, configuration and installation.</p>

<p>To deploy versioned <code>nodejs</code> application on bare metal Ubuntu server  ~ understanding file system tweaks such as symlink-ing for faster deployments can save time for future deployments.</p>

<pre><code class="language-shell">#first time on server side  
$ apt-get update
$ apt-get install git

#updating|upgrading server side code
$ apt-get update
$ apt-get upgrade
$ brew upgrade 
$ npm upgrade 

# Package download and installs 
$ /bin/bash -c &#34;$(curl -fsSL https://url.tld/version/install.sh)&#34;
$ wget -O - https://url.tld/version/install.sh | bash

# Discoverable packages 
$ npm install application@next 
$ yarn add application@next 
$ brew install application
</code></pre>

<p>_<em>Example</em>: _</p>

<blockquote><p>The command above can be automated via a scheduled task. Both <code>npm</code> and <code>yarn</code> support the installation of applications bundled in a <code>.tar</code> file. See an example of a simple script <a href="https://serverfault.com/a/226389">source</a>. We have to be mindful to clean up download directories, to save disk space.</p></blockquote>

<h2 id="switching-on-the-application" id="switching-on-the-application">Switching on the application</h2>

<p>It sounds repetitive, but running <code>npm start</code> does not guarantee the application to be visible outside the metal server box the application is hosted on. This magic belongs to the <code>nginx</code> reverse proxy we were referring to in earlier paragraphs.</p>

<p>A typical <code>nodejs</code> application needs to start one or more of the following services, each time to reboot the application.</p>

<pre><code class="language-shell"># symlinking new version to default application path
$ ln -sfn /var/www/new/version/appname /var/www/appname 

$ service nginx restart #nginx|apache server
$ service redis restart #redis server
$ service restart mongod #database server in some cases
$ service appname restart #application itself
</code></pre>

<p><em><em>Example</em>:</em></p>

<blockquote><p>PS: Above services are managed with <code>uptime</code></p></blockquote>

<p>Adding <code>nginx</code> reverse proxy makes the application available to the outside world. Switching on/off the application can be summarized in one command: <code>service nginx stop</code>. Likewise, to switch off and back on can be issued in one command: <code>service nginx restart</code>.</p>

<h2 id="post-deployment-support" id="post-deployment-support">Post-deployment support</h2>

<p>Asynchronous timely tasks can be used to resolve a wide range of issues. Background tasks such as <em>fetching updates from third-party data providers</em>, <em>system health check, and notifications</em>, <em>automated software updates</em>, <em>database cleaning</em>, <em>cache busting</em>, <em>scheduled expensive/CPU intensive batch processing jobs</em> just to name a few.</p>

<p>It is possible to leverage existing asynchronous timely OS-provided tasks processing infrastructure to achieve any of the named use cases, as it is true for third-party tools to do exactly the same job.</p>

<h2 id="rule-of-thumb" id="rule-of-thumb">Rule of thumb</h2>

<p>The following is a mental model that can be applied to the common use cases of releases. It may be basic for DevOps professionals, but useful enough for developers doing some operations work as well.</p>
<ul><li>Prepare deployable releases</li>
<li>Update and install binaries ~ using <code>apt</code>, <code>brew</code> etc.<br/></li>
<li>Download binaries ~ using <code>git</code>,<code>wget</code>, <code>curl</code> or <code>brew</code></li>
<li><code>symlink</code> directories(<code>/log</code>, <code>/config</code>, <code>/app</code>)</li>
<li>Restart  servers and services ~ <code>redis</code>, <code>nginx</code>, <code>mongodb</code> and <code>app</code></li>
<li>When something goes bad ~ walk two steps back. That is our rollback strategy.<br/></li></ul>

<blockquote><p>This model can be refined, to make most of these tasks repeatable and automated, deployments included.</p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited quick easy, and most basic <code>nodejs</code> deployment strategies. We also revisited how to expose the deployed applications to the world using <code>nginx</code> as a reverse proxy server. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>How to set up CI/CD Pipeline for a <code>nodejs</code> app with Jenkins ~ <a href="https://medium.com/@mosheezderman/how-to-set-up-ci-cd-pipeline-for-a-node-js-app-with-jenkins-c51581cc783c">Moshe Ezderman – Medium</a></li>
<li><a href="https://strongloop.com/strongblog/node-js-deploy-production-best-practice/"><em>“Build your dependencies into your deployable packages”</em></a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:code" class="hashtag"><span>#</span><span class="p-category">code</span></a> <a href="https://getsimple.works/tag:annotations" class="hashtag"><span>#</span><span class="p-category">annotations</span></a> <a href="https://getsimple.works/tag:question" class="hashtag"><span>#</span><span class="p-category">question</span></a> <a href="https://getsimple.works/tag:discuss" class="hashtag"><span>#</span><span class="p-category">discuss</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/easy-nodejs-deployment</guid>
      <pubDate>Thu, 17 Jun 2021 05:08:19 +0000</pubDate>
    </item>
    <item>
      <title>Integration of redis in nodejs applications </title>
      <link>https://getsimple.works/integration-of-redis-in-nodejs-applications?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[The reactive aspect of nodejs applications is synonymous with the nodejs runtime itself. Even though the real-time aspect may be attributed to WebSocket implementation, the realtime reactive aspect of nodejs applications heavily rely on pub/sub mechanisms -- most of the time backed by datastore engines like redis.  This article explores how to integrate redis datastore into a nodejs application. &#xA;&#xA;In this article we will talk about: &#xA;&#xA;redis support with and without expressjs&#xA;redis support with and without WebSocket push mechanism&#xA;Alternatives to redis in nodejs world and beyond &#xA;&#xA;  Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book.  Testing nodejs Applications Book Cover&#xA;&#xA;Show me the code&#xA;&#xA;The following code sample showcase how nodejs/redis integration can be achieved. It demonstrates that it is still possible to share sessions via a middleware between socket.io and expressjs.&#xA;&#xA;var app = express();&#xA;var server = Server(app);&#xA;var sio = require(&#34;socket.io&#34;)(server),&#xA;&#x9;redis = require(&#39;redis&#39;), &#xA;&#x9;rhost = process.env.REDISHOST,&#xA;&#x9;rport = process.env.REDISPORT,&#xA;&#x9;pub = redis.createClient(rport, rhost), &#xA;&#x9;sub = redis.createClient(rport, rhost);&#xA;&#xA;function middleware(req, res, next){&#xA; //session initialization thing&#xA; next();&#xA;}&#xA;&#xA;//socket.io/expressjs session sharing middleware&#xA;sio.use(function(socket, next){&#xA; &#x9;middleware(socket.request, socket.request.res, next);&#xA;});&#xA;&#xA;//express uses middleware for session management&#xA;app.use(middleware);&#xA;    &#xA;//somewhere&#xA;sio.sockets.on(&#34;connection&#34;, function(socket) {&#xA; &#xA; //socket.request.session &#xA; //Now it&#39;s available from socket.io sockets too! Win!&#xA; socket.on(&#39;message&#39;, (event) =  {&#xA;&#x9; var payload = JSON.parse(event.payload || event),&#xA;&#x9; &#x9;user = socket.handshake.user || false;&#xA;&#x9; &#xA;&#x9; //except when coming from pub  &#x9;&#x9;&#x9;&#xA;&#x9; pub.publish(payload.conversation, payload)); &#xA; });&#xA;&#xA; //redis listener&#xA; sub.on(&#39;message&#39;, function(channel, event) {&#xA;&#x9;var payload = JSON.parse(event.payload || event),&#xA;&#x9;&#x9;user = socket.handshake.user || false;&#xA;&#x9;sio.sockets.in(payload.conversation).emit(&#39;message&#39;, payload);&#xA; });&#xA;Example: excerpt source: StackOverflow&#xA;&#xA;What can possibly go wrong?&#xA;&#xA;When trying to figure out how to approach redis datastore integration into nodejs application for inter-process communication and real-time feature, the following points may be a challenge:&#xA;&#xA;How to decouple the WebSocket events from the redis specific (pub/sub) events. We should be able to decouple, but still provide an environment where interoperability is possible at any time. &#xA;How to make integration modular, testable, and overall friendly to the rest of the application ecosystem&#xA;&#xA;When testing this implementation, we should expect the additional challenge to emerge: &#xA;&#xA;The redis client instances (pub/sub) are created as soon as the library loads, and a redis server should be up and running by that time. The issue is when testing the application, there should be no server or any other system dependency hindering the application from being tested.  &#xA;getting rid of redis server with a drop-in-replacement, or stubs/mocks, is more of a dream than reality ~ hard but feasible.&#xA;&#xA;  There is additional information in mocking and stubbing redis data store in &#34;How to Mock redis datastore&#34; article. &#xA;&#xA;Conclusion &#xA;&#xA;In this article, we revisited how to enhance nodejs application with redis based pub/sub mechanism, critical to having a reactive real-time experience. The use of WebSocket and Pub/Sub powered by a key/value data store was especially the main focus of this article. There are additional complimentary materials in the &#34;Testing nodejs applications&#34; book. &#xA;&#xA;References&#xA;&#xA;Testing nodejs Applications book&#xA;Sharing session between expressjs and socket.io ~ StackOverflow Question&#xA;examples using redis with socket.io ~ StackOverflow Question&#xA;Using redis as PubSub over socket.io ~ StackOVerflow Question&#xA;socket.io - redis&#xA;redis pubsub library ~ Github Cloned Library&#xA;Building a Chat Server with node and redis - tests ~ Matthew Daly Blog&#xA;High Volume, low latency difficulties nodejs/pubsub/redis ~ StackOverflow Question&#xA;&#xA;#snippets #nodejs #integration #redis]]&gt;</description>
      <content:encoded><![CDATA[<p>The reactive aspect of <code>nodejs</code> applications is synonymous with the <code>nodejs</code> runtime itself. Even though the real-time aspect may be attributed to WebSocket implementation, the <strong><em>realtime reactive aspect</em></strong> of <code>nodejs</code> applications heavily rely on pub/sub mechanisms — most of the time backed by datastore engines like <code>redis</code>.  This article explores how to integrate <code>redis</code> datastore into a <code>nodejs</code> application.</p>

<p><strong><em>In this article we will talk about:</em></strong></p>
<ul><li><code>redis</code> support with and without <code>expressjs</code></li>
<li><code>redis</code> support with and without WebSocket push mechanism</li>
<li>Alternatives to <code>redis</code> in <code>nodejs</code> world and beyond</li></ul>

<blockquote><p>Even though this blog post was designed to offer complementary materials to those who bought my <strong><em><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></em></strong>, the content can help any software developer to tuneup working environment. <strong><em><a href="https://bit.ly/2ZFJytb">You use this link to buy the book</a></em></strong>.  <a href="https://bit.ly/2ZFJytb"><img src="https://snap.as/a/42OS2vs.png" alt="Testing nodejs Applications Book Cover"/></a></p></blockquote>

<h2 id="show-me-the-code" id="show-me-the-code">Show me the code</h2>

<p>The following code sample showcase how <code>nodejs</code>/<code>redis</code> integration can be achieved. It demonstrates that it is still possible to share sessions via a middleware between <code>socket.io</code> and <code>expressjs</code>.</p>

<pre><code class="language-JavaScript">var app = express();
var server = Server(app);
var sio = require(&#34;socket.io&#34;)(server),
	redis = require(&#39;redis&#39;), 
	rhost = process.env.REDIS_HOST,
	rport = process.env.REDIS_PORT,
	pub = redis.createClient(rport, rhost), 
	sub = redis.createClient(rport, rhost);


function middleware(req, res, next){
 //session initialization thing
 next();
}

//socket.io/expressjs session sharing middleware
sio.use(function(socket, next){
 	middleware(socket.request, socket.request.res, next);
});

//express uses middleware for session management
app.use(middleware);
    
//somewhere
sio.sockets.on(&#34;connection&#34;, function(socket) {
 
 //socket.request.session 
 //Now it&#39;s available from `socket.io` sockets too! Win!
 socket.on(&#39;message&#39;, (event) =&gt; {
	 var payload = JSON.parse(event.payload || event),
	 	user = socket.handshake.user || false;
	 
	 //except when coming from pub  			
	 pub.publish(payload.conversation, payload)); 
 });

 //redis listener
 sub.on(&#39;message&#39;, function(channel, event) {
	var payload = JSON.parse(event.payload || event),
		user = socket.handshake.user || false;
	sio.sockets.in(payload.conversation).emit(&#39;message&#39;, payload);
 });
</code></pre>

<p><em><em>Example</em>: excerpt <a href="https://stackoverflow.com/a/25618636/132610">source: StackOverflow</a></em></p>

<h2 id="what-can-possibly-go-wrong" id="what-can-possibly-go-wrong">What can possibly go wrong?</h2>

<p>When trying to figure out how to approach <code>redis</code> datastore integration into <code>nodejs</code> application for inter-process communication and real-time feature, the following points may be a challenge:</p>
<ul><li>How to decouple the WebSocket events from the <code>redis</code> specific (<code>pub</code>/<code>sub</code>) events. We should be able to decouple, but still provide an environment where interoperability is possible at any time.</li>
<li>How to make integration modular, testable, and overall friendly to the rest of the application ecosystem</li></ul>

<p>When testing this implementation, we should expect the additional challenge to emerge:</p>
<ul><li>The <code>redis</code> client instances (<code>pub</code>/<code>sub</code>) are created as soon as the library loads, and a <code>redis</code> server should be up and running by that time. The issue is when testing the application, there should be no server or any other system dependency hindering the application from being tested.<br/></li>
<li>getting rid of <code>redis</code> server with a drop-in-replacement, or <code>stubs/mocks</code>, is more of a dream than reality ~ hard but feasible.</li></ul>

<blockquote><p>There is additional information in mocking and stubbing <code>redis</code> data store in <a href="./how-to-mock-redis-datastore.md">“How to Mock <code>redis</code> datastore”</a> article.</p></blockquote>

<h2 id="conclusion" id="conclusion">Conclusion</h2>

<p>In this article, we revisited how to enhance <code>nodejs</code> application with <code>redis</code> based pub/sub mechanism, critical to having a reactive real-time experience. The use of WebSocket and Pub/Sub powered by a key/value data store was especially the main focus of this article. There are additional complimentary materials in the <strong>“Testing <code>nodejs</code> applications”</strong> book.</p>

<h2 id="references" id="references">References</h2>
<ul><li><a href="https://bit.ly/2ZFJytb">Testing <code>nodejs</code> Applications book</a></li>
<li>Sharing session between <code>expressjs</code> and <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/25532692/how-to-share-sessions-with-socket-io-1-x-and-express-4-x">StackOverflow Question</a></li>
<li>examples using <code>redis</code> with <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/9267292/examples-in-using-redisstore-in-socket-io">StackOverflow Question</a></li>
<li>Using <code>redis</code> as <code>PubSub</code> over <code>socket.io</code> ~ <a href="https://stackoverflow.com/questions/32743754/using-redis-as-pubsub-over-socket-io">StackOVerflow Question</a></li>
<li><a href="https://github.com/socketio/socket.io-redis"><code>socket.io</code> – <code>redis</code></a></li>
<li><code>redis</code> <code>pubsub</code> library ~ <a href="https://github.com/murindwaz/redispubsub">Github Cloned Library</a></li>
<li>Building a Chat Server with node and <code>redis</code> – tests ~ <a href="https://matthewdaly.co.uk/blog/2014/12/31/building-a-chat-server-with-node-dot-js-and-redis/">Matthew Daly Blog</a></li>
<li>High Volume, low latency difficulties <code>nodejs</code>/<code>pubsub</code>/<code>redis</code> ~ <a href="https://stackoverflow.com/questions/10557826/node-js-socket-io-redis-pub-sub-high-volume-low-latency-difficulties">StackOverflow Question</a></li></ul>

<p><a href="https://getsimple.works/tag:snippets" class="hashtag"><span>#</span><span class="p-category">snippets</span></a> <a href="https://getsimple.works/tag:nodejs" class="hashtag"><span>#</span><span class="p-category">nodejs</span></a> <a href="https://getsimple.works/tag:integration" class="hashtag"><span>#</span><span class="p-category">integration</span></a> <a href="https://getsimple.works/tag:redis" class="hashtag"><span>#</span><span class="p-category">redis</span></a></p>
]]></content:encoded>
      <guid>https://getsimple.works/integration-of-redis-in-nodejs-applications</guid>
      <pubDate>Thu, 17 Jun 2021 04:46:06 +0000</pubDate>
    </item>
  </channel>
</rss>