You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2020/10/20 18:17:03 UTC

[qpid-dispatch] branch master updated: DISPATCH-1751: Rework how AMQP session incoming-window is derived

This is an automated email from the ASF dual-hosted git repository.

chug pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 7525ac6  DISPATCH-1751: Rework how AMQP session incoming-window is derived
7525ac6 is described below

commit 7525ac665c3600805615c86796482914cdba783d
Author: Chuck Rolke <ch...@apache.org>
AuthorDate: Tue Oct 20 14:14:00 2020 -0400

    DISPATCH-1751: Rework how AMQP session incoming-window is derived
    
    Proton allows specification of a session 'capacity'. Initially the
    incoming-window will be (capacity / max-frame-size), defining at most
    how many max-size transfers will definitely be accepted on the session.
    
    Dispatch listener config defines a maxFrameSize and a maxSessionFrames
    the product of which is equal to the capacity to be configured in Proton.
    
    Dispatch vhostUserGroup policy defines a maxFrameSize and a
    maxSessionWindow. The maxSessionWindow is passed directly to Proton
    as the capacity.
    
    This closes #847
---
 src/connection_manager.c                | 42 ++++++++++++++++++++-------------
 tests/system_tests_protocol_settings.py | 22 ++++++++++++-----
 2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/src/connection_manager.c b/src/connection_manager.c
index aa95417..04ce135 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -438,25 +438,33 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, qd_server_config_t *conf
         config->max_frame_size = QD_AMQP_MIN_MAX_FRAME_SIZE;
 
     //
-    // Given session frame count and max frame size compute session incoming_capacity
+    // Given session frame count and max frame size, compute session incoming_capacity
+    //   On 64-bit systems the capacity has no limit.
+    //   On 32-bit systems the largest capacity is defined as half the process address space.
     //
-    if (ssn_frames == 0)
-        config->incoming_capacity = (sizeof(size_t) < 8) ? 0x7FFFFFFFLL : 0x7FFFFFFFLL * config->max_frame_size;
-    else {
-        uint64_t mfs      = (uint64_t) config->max_frame_size;
-        uint64_t trial_ic = ssn_frames * mfs;
-        uint64_t limit    = (sizeof(size_t) < 8) ? (1ll << 31) - 1 : 0;
-        if (limit == 0 || trial_ic < limit) {
-            // Silently promote incoming capacity of zero to one
-            config->incoming_capacity = 
-                (trial_ic < QD_AMQP_MIN_MAX_FRAME_SIZE ? QD_AMQP_MIN_MAX_FRAME_SIZE : trial_ic);
+    if (ssn_frames != 0) {
+        // Limited incoming frames.
+        // Specify this to proton by setting capacity to be
+        // the product (max_frame_size * ssn_frames).
+        size_t capacity = config->max_frame_size * ssn_frames;
+
+        if (sizeof(size_t) == 8) {
+            // 64-bit systems use the configured, unbounded capacity
+            config->incoming_capacity = capacity;
         } else {
-            config->incoming_capacity = limit;
-            uint64_t computed_ssn_frames = limit / mfs;
-            qd_log(qd->connection_manager->log_source, QD_LOG_WARNING,
-                   "Server configuation for I/O adapter entity name:'%s', host:'%s', port:'%s', "
-                   "requested maxSessionFrames truncated from %"PRId64" to %"PRId64,
-                   config->name, config->host, config->port, ssn_frames, computed_ssn_frames);
+            // 32-bit systems have an upper bound to the capacity
+#define AMQP_MAX_WINDOW_SIZE (2147483647)
+            if (capacity <= AMQP_MAX_WINDOW_SIZE) {
+                config->incoming_capacity = capacity;
+            } else {
+                config->incoming_capacity = AMQP_MAX_WINDOW_SIZE;
+
+                qd_log(qd->connection_manager->log_source, QD_LOG_WARNING,
+                    "Server configuation for I/O adapter entity name:'%s', host:'%s', port:'%s', "
+                    "requested maxSessionFrames truncated from %"PRId64" to %"PRId64,
+                    config->name, config->host, config->port, ssn_frames,
+                    AMQP_MAX_WINDOW_SIZE / config->max_frame_size);
+            }
         }
     }
 
diff --git a/tests/system_tests_protocol_settings.py b/tests/system_tests_protocol_settings.py
index 546ffe6..6b0d91d 100644
--- a/tests/system_tests_protocol_settings.py
+++ b/tests/system_tests_protocol_settings.py
@@ -26,6 +26,7 @@ from system_test import TestCase, Qdrouterd, main_module
 from system_test import unittest
 from proton.utils import BlockingConnection
 import subprocess
+import sys
 
 class MaxFrameMaxSessionFramesTest(TestCase):
     """System tests setting proton negotiated size max-frame-size and incoming-window"""
@@ -234,8 +235,11 @@ class MaxSessionFramesDefaultTest(TestCase):
             # if frame size not set then a default is used
             self.assertTrue(" max-frame-size=16384" in open_lines[0])
             begin_lines = [s for s in log_lines if "-> @begin" in s]
-            # incoming-window is defaulted to 2^31-1 (Proton default)
-            self.assertTrue(" incoming-window=2147483647," in begin_lines[0])
+            # incoming-window is defaulted to 2^31-1 (64-bit) or 2^17-1 (32-bit)
+            is_64bits = sys.maxsize > 2 ** 32
+            expected = " incoming-window=2147483647," if is_64bits else " incoming-window=131071,"
+            self.assertTrue(expected in begin_lines[0],
+                            "Expected:'%s' not found in '%s'" % (expected, begin_lines[0]))
 
 
 class MaxFrameMaxSessionFramesZeroTest(TestCase):
@@ -270,8 +274,11 @@ class MaxFrameMaxSessionFramesZeroTest(TestCase):
             # max-frame gets set to protocol min
             self.assertTrue(' max-frame-size=512,' in open_lines[0])
             begin_lines = [s for s in log_lines if "-> @begin" in s]
-            # incoming-window is defaulted to 2^31-1 (Proton default)
-            self.assertTrue(" incoming-window=2147483647," in begin_lines[0])
+            # incoming-window is defaulted to 2^31-1 (64-bit) or 2^17-1 (32-bit)
+            is_64bits = sys.maxsize > 2 ** 32
+            expected = " incoming-window=2147483647," if is_64bits else " incoming-window=131071,"
+            self.assertTrue(expected in begin_lines[0],
+                            "Expected:'%s' not found in '%s'" % (expected, begin_lines[0]))
 
 
 class ConnectorSettingsDefaultTest(TestCase):
@@ -323,8 +330,11 @@ class ConnectorSettingsDefaultTest(TestCase):
             self.assertTrue(' max-frame-size=16384,' in open_lines[0])
             self.assertTrue(' channel-max=32767,' in open_lines[0])
             begin_lines = [s for s in log_lines if "<- @begin" in s]
-            # defaults
-            self.assertTrue(" incoming-window=2147483647," in begin_lines[0])
+            # incoming-window is defaulted to 2^31-1 (64-bit) or 2^17-1 (32-bit)
+            is_64bits = sys.maxsize > 2 ** 32
+            expected = " incoming-window=2147483647," if is_64bits else " incoming-window=131071,"
+            self.assertTrue(expected in begin_lines[0],
+                            "Expected:'%s' not found in '%s'" % (expected, begin_lines[0]))
 
 
 class ConnectorSettingsNondefaultTest(TestCase):


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org