FEATURE: support status 429 from server and Retry-After header

FEATURE: support status 429 from server and Retry-After header

In some cases you may need to get message bus to reject requests cause server is overloaded, this allows server to communicate with client and ask it to back off for N seconds by return 429 with a Retry-After header with the amount of seconds to wait

diff --git a/CHANGELOG b/CHANGELOG
index 6645622..dbaf146 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
 Unreleased
 
+- Version 2.2.1
+
+  - FEATURE: Support rate limiting by server, 429 status codes are respected and we hold off as needed
+
   - FIX: In the redis backend make the `is_readonly?` method compatible with the redis gem both pre and post v4.0 when the `client` attribute was removed
 
 30-04-2019
diff --git a/assets/message-bus.js b/assets/message-bus.js
index 7ac115d..7ad8f34 100644
--- a/assets/message-bus.js
+++ b/assets/message-bus.js
@@ -163,6 +163,9 @@
 
     var gotData = false;
     var aborted = false;
+    var rateLimited = false;
+    var rateLimitedSeconds;
+
     lastAjax = new Date();
     totalAjaxCalls += 1;
     data.__seq = totalAjaxCalls;
@@ -293,7 +296,18 @@
         }
       },
       error: function(xhr, textStatus, err) {
-        if (textStatus === "abort") {
+        if (xhr.status === 429) {
+          var tryAfter =
+            parseInt(
+              xhr.getResponseHeader && xhr.getResponseHeader("Retry-After")
+            ) || 0;
+          tryAfter = tryAfter || 0;
+          if (tryAfter < 15) {
+            tryAfter = 15;
+          }
+          rateLimitedSeconds = tryAfter;
+          rateLimited = true;
+        } else if (textStatus === "abort") {
           aborted = true;
         } else {
           failCount += 1;
@@ -305,7 +319,9 @@
 
         var interval;
         try {
-          if (gotData || aborted) {
+          if (rateLimited) {
+            interval = Math.max(me.minPollInterval, rateLimitedSeconds * 1000);
+          } else if (gotData || aborted) {
             interval = me.minPollInterval;
           } else {
             interval = me.callbackInterval;
diff --git a/lib/message_bus/version.rb b/lib/message_bus/version.rb
index a43aac7..f24b102 100644
--- a/lib/message_bus/version.rb
+++ b/lib/message_bus/version.rb
@@ -1,5 +1,5 @@
 # frozen_string_literal: true
 
 module MessageBus
-  VERSION = "2.2.1"
+  VERSION = "2.2.2"
 end

GitHub sha: 138d74ea

1 Like