{"id":223,"date":"2013-03-20T23:14:06","date_gmt":"2013-03-20T23:14:06","guid":{"rendered":"https:\/\/gosqeng.test\/?p=223"},"modified":"2019-11-28T12:34:01","modified_gmt":"2019-11-28T12:34:01","slug":"new-node-js-module-ribbon","status":"publish","type":"post","link":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon","title":{"rendered":"Introducing Ribbon"},"content":{"rendered":"<p>This morning the silence of my room, and subsequently the serenity of my rare hours of sleep were suddenly pierced by my iPhone&#8217;s ringtone at 5am. On the other end of the line was the mechanised TTS-voice of our server monitoring system, informing me that our DBs had noticed a drop in connections.<\/p>\n<p>As was my duty, I hopped on to find the source of the issue. It turned out to be faulty reconnection logic in one of many adapters we had developed for managing connections to MySQL servers in our applications. It was a bug that still existed simply because we had too many of these adapters lying around to feasibly maintain, and this one slipped through.<\/p>\n<p>Over many months, I&#8217;ve noticed that the various clients on offer for connecting to and working with external services, like Redis, MongoDB, RabbitMQ, MySQL etc. all share very similar concepts: a connection is established to a service running on a server, and depending on the state of that connection, you interact with that service using the client.<\/p>\n<p>However, it&#8217;s apparent that while sharing similar concepts (such as a connection must be active before querying, and you won&#8217;t get anywhere with a dead connection), these modules didn&#8217;t stick to a consistent methodology for your application to understand and respond to changes in state. They&#8217;d often use different event names to describe the same states (such as &#8216;connected&#8217;, &#8216;ready&#8217; &#8216;open&#8217; to represent an active connection, and &#8216;close&#8217;, &#8216;end&#8217;, &#8216;exit&#8217;, &#8216;error&#8217; to denote an inactive connection). Worse still, they commonly lacked convenience methods to check the state, such as .isUp() or .isDown().<\/p>\n<h3>That&#8217;s why I wrote <a href=\"https:\/\/github.com\/TheDeveloper\/ribbon\" target=\"_blank\" rel=\"noopener noreferrer\">Ribbon<\/a><\/h3>\n<p>Predominantly formulated during the small hours of this morning, <a href=\"https:\/\/github.com\/TheDeveloper\/ribbon\" target=\"_blank\" rel=\"noopener noreferrer\">Ribbon<\/a> is simply defined as a lightweight Node.js service wrapper. It provides a standard set of events and methods for use in your applications to react to and verify the status of external services, as an alternative to dealing with various different terminology and definitions for common state events.<\/p>\n<p>Ribbon instead exposes a set of standard events, such as simply &#8216;up&#8217; for connection available, and &#8216;down&#8217; for connection unavailable.<\/p>\n<p><b>Adaptors<\/b><br \/>\nRibbon includes a collection of adaptors which inherit the ribbon interface. An adaptor is a controller for your underlying connection or service, known as the client. The adaptor is the interface between the service&#8217;s client and ribbon.<\/p>\n<p>Adaptors are bundled as part of Ribbon, and I&#8217;d be grateful to anyone contributing adaptors for their use case. I&#8217;ll be putting together a guide to building an adapter before too long.<\/p>\n<p>See the <a href=\"https:\/\/github.com\/TheDeveloper\/ribbon\" target=\"_blank\" rel=\"noopener noreferrer\">repo<\/a> for more info + README.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This morning the silence of my room, and subsequently the serenity of my rare hours of sleep were suddenly pierced by my iPhone&#8217;s ringtone at 5am. On the other end of the line was the mechanised TTS-voice of our server monitoring system, informing me that our DBs had noticed a drop in connections.<\/p>\n<p>As was my duty, I hopped on to find the source of the issue. Here&#8217;s what came out of it.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1452],"tags":[622,1540,1121],"class_list":["post-223","post","type-post","status-publish","format-standard","hentry","category-engineering","tag-module","tag-node-js-2","tag-service"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v18.6 (Yoast SEO v19.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introducing Ribbon - GoSquared Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing Ribbon\" \/>\n<meta property=\"og:description\" content=\"This morning the silence of my room, and subsequently the serenity of my rare hours of sleep were suddenly pierced by my iPhone&#039;s ringtone at 5am. On the other end of the line was the mechanised TTS-voice of our server monitoring system, informing me that our DBs had noticed a drop in connections. As was my duty, I hopped on to find the source of the issue. Here&#039;s what came out of it.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon\" \/>\n<meta property=\"og:site_name\" content=\"GoSquared Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/GoSquared\" \/>\n<meta property=\"article:published_time\" content=\"2013-03-20T23:14:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-28T12:34:01+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@TheDeveloper\" \/>\n<meta name=\"twitter:site\" content=\"@GoSquared\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Geoff Wagstaff\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\",\"name\":\"GoSquared\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"sameAs\":[\"https:\/\/instagram.com\/gosquaredteam\",\"https:\/\/www.linkedin.com\/company\/go-squared-ltd.\",\"https:\/\/www.facebook.com\/GoSquared\",\"https:\/\/twitter.com\/GoSquared\"],\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"contentUrl\":\"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png\",\"width\":1270,\"height\":250,\"caption\":\"GoSquared\"},\"image\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\",\"url\":\"https:\/\/www.gosquared.com\/blog\/\",\"name\":\"GoSquared Blog\",\"description\":\"Turn visitors into customers.\",\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage\",\"url\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon\",\"name\":\"Introducing Ribbon - GoSquared Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#website\"},\"datePublished\":\"2013-03-20T23:14:06+00:00\",\"dateModified\":\"2019-11-28T12:34:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.gosquared.com\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing Ribbon\"}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage\"},\"author\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448\"},\"headline\":\"Introducing Ribbon\",\"datePublished\":\"2013-03-20T23:14:06+00:00\",\"dateModified\":\"2019-11-28T12:34:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage\"},\"wordCount\":430,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.gosquared.com\/blog\/#organization\"},\"keywords\":[\"Module\",\"Node.js\",\"Service\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#respond\"]}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448\",\"name\":\"Geoff Wagstaff\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g\",\"caption\":\"Geoff Wagstaff\"},\"sameAs\":[\"https:\/\/twitter.com\/TheDeveloper\"],\"url\":\"https:\/\/www.gosquared.com\/blog\/author\/echo\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Introducing Ribbon - GoSquared Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon","og_locale":"en_US","og_type":"article","og_title":"Introducing Ribbon","og_description":"This morning the silence of my room, and subsequently the serenity of my rare hours of sleep were suddenly pierced by my iPhone's ringtone at 5am. On the other end of the line was the mechanised TTS-voice of our server monitoring system, informing me that our DBs had noticed a drop in connections. As was my duty, I hopped on to find the source of the issue. Here's what came out of it.","og_url":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon","og_site_name":"GoSquared Blog","article_publisher":"https:\/\/www.facebook.com\/GoSquared","article_published_time":"2013-03-20T23:14:06+00:00","article_modified_time":"2019-11-28T12:34:01+00:00","twitter_card":"summary_large_image","twitter_creator":"@TheDeveloper","twitter_site":"@GoSquared","twitter_misc":{"Written by":"Geoff Wagstaff","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Organization","@id":"https:\/\/www.gosquared.com\/blog\/#organization","name":"GoSquared","url":"https:\/\/www.gosquared.com\/blog\/","sameAs":["https:\/\/instagram.com\/gosquaredteam","https:\/\/www.linkedin.com\/company\/go-squared-ltd.","https:\/\/www.facebook.com\/GoSquared","https:\/\/twitter.com\/GoSquared"],"logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","contentUrl":"https:\/\/www.gosquared.com\/blog\/wp-content\/uploads\/2015\/07\/gosquared.png","width":1270,"height":250,"caption":"GoSquared"},"image":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"WebSite","@id":"https:\/\/www.gosquared.com\/blog\/#website","url":"https:\/\/www.gosquared.com\/blog\/","name":"GoSquared Blog","description":"Turn visitors into customers.","publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.gosquared.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage","url":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon","name":"Introducing Ribbon - GoSquared Blog","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/#website"},"datePublished":"2013-03-20T23:14:06+00:00","dateModified":"2019-11-28T12:34:01+00:00","breadcrumb":{"@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.gosquared.com\/blog"},{"@type":"ListItem","position":2,"name":"Introducing Ribbon"}]},{"@type":"Article","@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#article","isPartOf":{"@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage"},"author":{"@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448"},"headline":"Introducing Ribbon","datePublished":"2013-03-20T23:14:06+00:00","dateModified":"2019-11-28T12:34:01+00:00","mainEntityOfPage":{"@id":"https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#webpage"},"wordCount":430,"commentCount":0,"publisher":{"@id":"https:\/\/www.gosquared.com\/blog\/#organization"},"keywords":["Module","Node.js","Service"],"articleSection":["Engineering"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.gosquared.com\/blog\/new-node-js-module-ribbon#respond"]}]},{"@type":"Person","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/56a3341790c8a0603f96066fb8d42448","name":"Geoff Wagstaff","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.gosquared.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/66792d2e4d04406697b9a5f322664691590a386bc15b7146d143bbca07aa8889?s=96&d=mm&r=g","caption":"Geoff Wagstaff"},"sameAs":["https:\/\/twitter.com\/TheDeveloper"],"url":"https:\/\/www.gosquared.com\/blog\/author\/echo"}]}},"wps_subtitle":"A lightweight Node.js service wrapper","_links":{"self":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/comments?post=223"}],"version-history":[{"count":0,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/posts\/223\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/media?parent=223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/categories?post=223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gosquared.com\/blog\/wp-json\/wp\/v2\/tags?post=223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}