)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1000377,"name":"Brett Lawson","email":"brett19@gmail.com","username":"brett19","avatars":[{"url":"https://www.gravatar.com/avatar/e7d7c9c704693cb552c9dc9d9e4a27d1.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/e7d7c9c704693cb552c9dc9d9e4a27d1.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/e7d7c9c704693cb552c9dc9d9e4a27d1.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/e7d7c9c704693cb552c9dc9d9e4a27d1.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bf190d5f8f565a90980f73fefd6496381a476af5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":31,"id":"26522adc_22a88cfa","updated":"2026-03-30 21:43:23.000000000","message":"Re-+2 based on Dimitris\u0027s +2 due to rebasing.","commit_id":"ff9875f47a1b199904ac2d27259e8d5621cd5bfa"}],"acouchbase/logic/cluster_impl.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":176,"context_line":"        try:"},{"line_number":177,"context_line":"            tracer \u003d self._cluster_settings.tracer.tracer"},{"line_number":178,"context_line":"            if hasattr(tracer, \u0027close\u0027) and callable(getattr(tracer, \u0027close\u0027)):"},{"line_number":179,"context_line":"                # Check if it\u0027s specifically a ThresholdLoggingTracer before closing"},{"line_number":180,"context_line":"                from couchbase.logic.observability import ThresholdLoggingTracer"},{"line_number":181,"context_line":"                if isinstance(tracer, ThresholdLoggingTracer):"},{"line_number":182,"context_line":"                    tracer.close()"}],"source_content_type":"text/x-python","patch_set":15,"id":"6c95aa23_3a54d475","line":179,"updated":"2026-03-12 17:52:14.000000000","message":"Is there benefit in checking for the presence of `close` if we are checking that it\u0027s a `ThresholdLoggingTracer`? Is this to avoid the import?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":176,"context_line":"        try:"},{"line_number":177,"context_line":"            tracer \u003d self._cluster_settings.tracer.tracer"},{"line_number":178,"context_line":"            if hasattr(tracer, \u0027close\u0027) and callable(getattr(tracer, \u0027close\u0027)):"},{"line_number":179,"context_line":"                # Check if it\u0027s specifically a ThresholdLoggingTracer before closing"},{"line_number":180,"context_line":"                from couchbase.logic.observability import ThresholdLoggingTracer"},{"line_number":181,"context_line":"                if isinstance(tracer, ThresholdLoggingTracer):"},{"line_number":182,"context_line":"                    tracer.close()"}],"source_content_type":"text/x-python","patch_set":15,"id":"680a806c_27c136bc","line":179,"in_reply_to":"6c95aa23_3a54d475","updated":"2026-03-13 20:56:59.000000000","message":"Fair point.  Not a real benefit has been updated in the latest patchset.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"}],"acouchbase/tests/tracing_tests/management_t.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"60651ed8c8a866c3d25c5e956df0b48d329c0a3c","unresolved":false,"context_lines":[{"line_number":727,"context_line":"        # └── manager_query_get_all_deferred_indexes (C++ core)"},{"line_number":728,"context_line":"        #     ├── dispatch_to_server (C++ core)"},{"line_number":729,"context_line":"        #     └── manager_query_build_indexes (C++ core)"},{"line_number":730,"context_line":"        #         └── dispatch_to_server (C++ core)"},{"line_number":731,"context_line":"        # validator.validate_http_op()"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"        op_name \u003d OpName.QueryIndexWatchIndexes"}],"source_content_type":"text/x-python","patch_set":29,"id":"686ea22d_829c9064","line":730,"updated":"2026-03-25 14:36:14.000000000","message":"I think `manager_query_build_indexes` shouldn\u0027t be a child of `manager_query_get_all_deferred_indexes`:\n\n```\nmanager_query_build_deferred_indexes (python)\n└── manager_query_get_all_deferred_indexes (C++ core)\n    └── dispatch_to_server (C++ core)\n└── manager_query_build_indexes (C++ core)\n    └── dispatch_to_server (C++ core)\n```\n\nThat\u0027s because `manager_query_get_all_deferred_indexes` ends, and then `manager_query_build_indexes` follows afterwards.\n\nThis is on the C++ side though (I should have spotted this on that review!). Does this sound reasonable to you? I\u0027ll file a CXXCBC to change that if so.","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"ba921cf0b8b36b80da6f073becbf81809d9df24a","unresolved":false,"context_lines":[{"line_number":727,"context_line":"        # └── manager_query_get_all_deferred_indexes (C++ core)"},{"line_number":728,"context_line":"        #     ├── dispatch_to_server (C++ core)"},{"line_number":729,"context_line":"        #     └── manager_query_build_indexes (C++ core)"},{"line_number":730,"context_line":"        #         └── dispatch_to_server (C++ core)"},{"line_number":731,"context_line":"        # validator.validate_http_op()"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"        op_name \u003d OpName.QueryIndexWatchIndexes"}],"source_content_type":"text/x-python","patch_set":29,"id":"7bc4e8e0_b2826ae4","line":730,"in_reply_to":"686ea22d_829c9064","updated":"2026-03-25 18:31:51.000000000","message":"Ahhh, yes, this makes sense.  Ha -- I apologize I could have thought that through a bit more too.  I was just thinking about getting spans back and now the structure of said spans until I got here in the Python work (and then I forgot about what was done in the C++ client 😊)","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"}],"acouchbase/tests/tracing_tests/streaming_t.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"60651ed8c8a866c3d25c5e956df0b48d329c0a3c","unresolved":true,"context_lines":[{"line_number":103,"context_line":"            pass"},{"line_number":104,"context_line":"        validator.validate_http_op()"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if acb_env.server_version_short \u003c\u003d 6.6:"},{"line_number":107,"context_line":"            return  # scope-level query support added in server 7.0, so skip rest of test if not supported"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        # dunno why we have this on analytics_query...buuuut we do..."}],"source_content_type":"text/x-python","patch_set":29,"id":"d2203c7f_19e2100f","line":106,"updated":"2026-03-25 14:36:14.000000000","message":"Should this (and the ones below) be a `EnvironmentFeatures.is_feature_supported(\u0027collections\u0027, ...)` call instead?","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"ba921cf0b8b36b80da6f073becbf81809d9df24a","unresolved":false,"context_lines":[{"line_number":103,"context_line":"            pass"},{"line_number":104,"context_line":"        validator.validate_http_op()"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if acb_env.server_version_short \u003c\u003d 6.6:"},{"line_number":107,"context_line":"            return  # scope-level query support added in server 7.0, so skip rest of test if not supported"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        # dunno why we have this on analytics_query...buuuut we do..."}],"source_content_type":"text/x-python","patch_set":29,"id":"2fb31fe5_f06530c5","line":106,"in_reply_to":"d2203c7f_19e2100f","updated":"2026-03-25 18:31:51.000000000","message":"Done","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"}],"couchbase/analytics.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"f0c0db453a499486e2ca9590c3a4eba511ab8ec4","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        # We want to end the streaming op span once we have a response from the C++ core."},{"line_number":88,"context_line":"        # Unfortunately right now, that means we need to wait until we have the first row (or we have an error)."},{"line_number":89,"context_line":"        # As this method is idempotent, it is safe to call for each row (it will only do work for the first call)."},{"line_number":90,"context_line":"        self._process_core_span()"},{"line_number":91,"context_line":"        return self.serializer.deserialize(row)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def __next__(self):"}],"source_content_type":"text/x-python","patch_set":29,"id":"99da9cac_ace7b445","line":90,"updated":"2026-03-24 17:44:45.000000000","message":"Should we make this call before raising any of the exceptions above?\n\nIf I\u0027m understanding the code correctly, it looks like if there was an error when executing the query, the span would not be closed.\n\n(The other streaming operations have the same logic, so this comment also applies to them)","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"60651ed8c8a866c3d25c5e956df0b48d329c0a3c","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        # We want to end the streaming op span once we have a response from the C++ core."},{"line_number":88,"context_line":"        # Unfortunately right now, that means we need to wait until we have the first row (or we have an error)."},{"line_number":89,"context_line":"        # As this method is idempotent, it is safe to call for each row (it will only do work for the first call)."},{"line_number":90,"context_line":"        self._process_core_span()"},{"line_number":91,"context_line":"        return self.serializer.deserialize(row)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def __next__(self):"}],"source_content_type":"text/x-python","patch_set":29,"id":"9f0b8dbf_0eb95e18","line":90,"in_reply_to":"72d95d0c_c4b1ecc5","updated":"2026-03-25 14:36:14.000000000","message":"Yes, I see, that sounds right.\n\nCould this `_process_core_span` call also have been in `__next__()` (or the opposite, all of them in `_get_next_row()`? That would keep them all in the same place and make it easier to follow the logic. (This is kind of a nit though, so I\u0027m fine with keeping it as is)","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"f265d15755d063c64da248b7c6e27970ead8166a","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        # We want to end the streaming op span once we have a response from the C++ core."},{"line_number":88,"context_line":"        # Unfortunately right now, that means we need to wait until we have the first row (or we have an error)."},{"line_number":89,"context_line":"        # As this method is idempotent, it is safe to call for each row (it will only do work for the first call)."},{"line_number":90,"context_line":"        self._process_core_span()"},{"line_number":91,"context_line":"        return self.serializer.deserialize(row)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def __next__(self):"}],"source_content_type":"text/x-python","patch_set":29,"id":"72d95d0c_c4b1ecc5","line":90,"in_reply_to":"99da9cac_ace7b445","updated":"2026-03-25 04:25:53.000000000","message":"`_get_next_row()` is called by `__next__()`, so any exception that is raised should be handled via the `try`/`except` block in `__next__()` and we will call `_process_core_span()` there.\n\nThat makes sense?  Or is there an angle I\u0027m missing?","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"ba921cf0b8b36b80da6f073becbf81809d9df24a","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        # We want to end the streaming op span once we have a response from the C++ core."},{"line_number":88,"context_line":"        # Unfortunately right now, that means we need to wait until we have the first row (or we have an error)."},{"line_number":89,"context_line":"        # As this method is idempotent, it is safe to call for each row (it will only do work for the first call)."},{"line_number":90,"context_line":"        self._process_core_span()"},{"line_number":91,"context_line":"        return self.serializer.deserialize(row)"},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"    def __next__(self):"}],"source_content_type":"text/x-python","patch_set":29,"id":"06c4e885_2ce80ee0","line":90,"in_reply_to":"9f0b8dbf_0eb95e18","updated":"2026-03-25 18:31:51.000000000","message":"Cool! Good suggestion on consolidating the logic.  Updates made in all APIs 👍","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"}],"couchbase/logic/observability/handler.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"class CollectionDetails(TypedDict):"},{"line_number":50,"context_line":"    bucket: str"},{"line_number":51,"context_line":"    scope: str"},{"line_number":52,"context_line":"    collection_name: str"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"c3c73aec_77eca6dc","line":51,"updated":"2026-03-12 17:52:14.000000000","message":"Kind of a NIT (so I\u0027m fine if you don\u0027t change this), but I think it would be better if the above were called `bucket_name` and `scope_name`, just for consistency with `collection_name`. Otherwise, I can see someone in the future accidentally trying to access `bucket_name` instead of `bucket`.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"class CollectionDetails(TypedDict):"},{"line_number":50,"context_line":"    bucket: str"},{"line_number":51,"context_line":"    scope: str"},{"line_number":52,"context_line":"    collection_name: str"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"bf65f65f_59308832","line":51,"in_reply_to":"c3c73aec_77eca6dc","updated":"2026-03-13 20:56:59.000000000","message":"Sooo, the original reason for this was b/c `CollectionDetails` in `couchbase.logic.collection_types.py` is the dataclass that is used to house this information.  The txn logic wants to pass `bucket`, `scope` and `collection_name` down into the bindings.  I just kept that consistent.\n\nHowever, I agree this would be more intuitive, so I updated things and gave the txn logic a special method.  I will create a PYCBC to make the txn logic consistent.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"def get_attributes_for_kv_op(op_name: str,"},{"line_number":62,"context_line":"                             collection_details: CollectionDetails,"},{"line_number":63,"context_line":"                             durability: Optional[int] \u003d None) -\u003e Mapping[str, str]:"},{"line_number":64,"context_line":"    attrs \u003d {"},{"line_number":65,"context_line":"        OpAttributeName.SystemName.value: \u0027couchbase\u0027,"},{"line_number":66,"context_line":"        OpAttributeName.Service.value: ServiceType.KeyValue.value,"}],"source_content_type":"text/x-python","patch_set":15,"id":"cb5841ac_f5bed0ec","line":63,"updated":"2026-03-12 17:52:14.000000000","message":"The `durability` can also be a `dict` at this point.\n\nI think it would be better if durability reached this as an `Optional[DurabilityLevel]`. It would make the behavior more obvious, and we have to cast it to `DurabilityLevel` anyway.\n\nThe conversion of the final arg to `DurabilityLevel` could be handled in the constructor of `WrappedSpan` instead.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"def get_attributes_for_kv_op(op_name: str,"},{"line_number":62,"context_line":"                             collection_details: CollectionDetails,"},{"line_number":63,"context_line":"                             durability: Optional[int] \u003d None) -\u003e Mapping[str, str]:"},{"line_number":64,"context_line":"    attrs \u003d {"},{"line_number":65,"context_line":"        OpAttributeName.SystemName.value: \u0027couchbase\u0027,"},{"line_number":66,"context_line":"        OpAttributeName.Service.value: ServiceType.KeyValue.value,"}],"source_content_type":"text/x-python","patch_set":15,"id":"b84b1155_1b51da1b","line":63,"in_reply_to":"cb5841ac_f5bed0ec","updated":"2026-03-13 20:56:59.000000000","message":"Good point.  I have rearrange the handler to have a separate method for handling KV durability.  I did this b/c the request builders are already branching based on the type of durability (e.g. legacy or not), so I figured it would be ideal to not duplicate those checks.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":407,"context_line":"        return self.__enter__()"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"    async def __aexit__(self, exc_type, exc_val, exc_tb) -\u003e Optional[bool]:"},{"line_number":410,"context_line":"        self.__exit__(exc_type, exc_val, exc_tb)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"class WrappedSpan:"}],"source_content_type":"text/x-python","patch_set":15,"id":"fb630684_bdb198a4","line":410,"updated":"2026-03-12 17:52:14.000000000","message":"Is a `return` missing here?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":407,"context_line":"        return self.__enter__()"},{"line_number":408,"context_line":""},{"line_number":409,"context_line":"    async def __aexit__(self, exc_type, exc_val, exc_tb) -\u003e Optional[bool]:"},{"line_number":410,"context_line":"        self.__exit__(exc_type, exc_val, exc_tb)"},{"line_number":411,"context_line":""},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"class WrappedSpan:"}],"source_content_type":"text/x-python","patch_set":15,"id":"bb17ee7a_285a3b08","line":410,"in_reply_to":"fb630684_bdb198a4","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":418,"context_line":"                 wrapped_tracer: WrappedTracer,"},{"line_number":419,"context_line":"                 collection_details: Optional[CollectionDetails] \u003d None,"},{"line_number":420,"context_line":"                 parent_span: Optional[Union[SpanProtocol, WrappedSpan]] \u003d None,"},{"line_number":421,"context_line":"                 durability: Optional[int] \u003d None,"},{"line_number":422,"context_line":"                 start_time: Optional[int] \u003d None,"},{"line_number":423,"context_line":"                 statement: Optional[str] \u003d None) -\u003e None:"},{"line_number":424,"context_line":"        self._service_type \u003d service_type"}],"source_content_type":"text/x-python","patch_set":15,"id":"aebe40b9_1e8c5036","line":421,"updated":"2026-03-12 17:52:14.000000000","message":"The type here might also need to reflect that `durability` can also be a dict. The same applies to all the methods in `ObservableRequestHandler(Impl)` that have the `durability` parameter.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":418,"context_line":"                 wrapped_tracer: WrappedTracer,"},{"line_number":419,"context_line":"                 collection_details: Optional[CollectionDetails] \u003d None,"},{"line_number":420,"context_line":"                 parent_span: Optional[Union[SpanProtocol, WrappedSpan]] \u003d None,"},{"line_number":421,"context_line":"                 durability: Optional[int] \u003d None,"},{"line_number":422,"context_line":"                 start_time: Optional[int] \u003d None,"},{"line_number":423,"context_line":"                 statement: Optional[str] \u003d None) -\u003e None:"},{"line_number":424,"context_line":"        self._service_type \u003d service_type"}],"source_content_type":"text/x-python","patch_set":15,"id":"2cdfaf19_76f31bc2","line":421,"in_reply_to":"aebe40b9_1e8c5036","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":448,"context_line":"        # legacy operations did not create an encoding span; not support now"},{"line_number":449,"context_line":"        # we only expect certain ops to have multiple encoding spans"},{"line_number":450,"context_line":"        if self._wrapped_tracer.is_legacy or not self._has_multiple_encoding_spans:"},{"line_number":451,"context_line":"            return"},{"line_number":452,"context_line":"        if not self._encoding_spans:"},{"line_number":453,"context_line":"            self._encoding_spans \u003d []"},{"line_number":454,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"d6c080e1_298366d8","line":451,"updated":"2026-03-12 17:52:14.000000000","message":"This path currently returns `None`. Should it be returning the encoded data?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":448,"context_line":"        # legacy operations did not create an encoding span; not support now"},{"line_number":449,"context_line":"        # we only expect certain ops to have multiple encoding spans"},{"line_number":450,"context_line":"        if self._wrapped_tracer.is_legacy or not self._has_multiple_encoding_spans:"},{"line_number":451,"context_line":"            return"},{"line_number":452,"context_line":"        if not self._encoding_spans:"},{"line_number":453,"context_line":"            self._encoding_spans \u003d []"},{"line_number":454,"context_line":""}],"source_content_type":"text/x-python","patch_set":15,"id":"5f122071_3dc8bbf5","line":451,"in_reply_to":"d6c080e1_298366d8","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":470,"context_line":"        # legacy operations did not create an encoding span; not support now"},{"line_number":471,"context_line":"        # if the op is expected to have multiple encoding spans, maybe_add_encoding_span() should be used instead"},{"line_number":472,"context_line":"        if self._wrapped_tracer.is_legacy or self._has_multiple_encoding_spans:"},{"line_number":473,"context_line":"            return"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"        encoding_span \u003d self._wrapped_tracer.tracer.request_span(OpAttributeName.EncodingSpanName.value,"},{"line_number":476,"context_line":"                                                                 self._request_span)"}],"source_content_type":"text/x-python","patch_set":15,"id":"5d59234e_87563dc5","line":473,"updated":"2026-03-12 17:52:14.000000000","message":"Ditto, should this be returning the encoded data?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        # legacy operations did not create an encoding span; not support now"},{"line_number":471,"context_line":"        # if the op is expected to have multiple encoding spans, maybe_add_encoding_span() should be used instead"},{"line_number":472,"context_line":"        if self._wrapped_tracer.is_legacy or self._has_multiple_encoding_spans:"},{"line_number":473,"context_line":"            return"},{"line_number":474,"context_line":""},{"line_number":475,"context_line":"        encoding_span \u003d self._wrapped_tracer.tracer.request_span(OpAttributeName.EncodingSpanName.value,"},{"line_number":476,"context_line":"                                                                 self._request_span)"}],"source_content_type":"text/x-python","patch_set":15,"id":"d781f27f_e962296e","line":473,"in_reply_to":"5d59234e_87563dc5","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"}],"couchbase/logic/observability/no_op.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":68,"context_line":"        self,"},{"line_number":69,"context_line":"        name: str,"},{"line_number":70,"context_line":"        parent_span: Optional[RequestSpan] \u003d None,"},{"line_number":71,"context_line":"        start_stime: Optional[int] \u003d None"},{"line_number":72,"context_line":"    ) -\u003e RequestSpan:"},{"line_number":73,"context_line":"        return NoOpSpan()"}],"source_content_type":"text/x-python","patch_set":15,"id":"986dbfca_d8a2b9b8","line":71,"updated":"2026-03-12 17:52:14.000000000","message":"NIT: typo\n\n\n```suggestion\n        start_time: Optional[int] \u003d None\n```","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        self,"},{"line_number":69,"context_line":"        name: str,"},{"line_number":70,"context_line":"        parent_span: Optional[RequestSpan] \u003d None,"},{"line_number":71,"context_line":"        start_stime: Optional[int] \u003d None"},{"line_number":72,"context_line":"    ) -\u003e RequestSpan:"},{"line_number":73,"context_line":"        return NoOpSpan()"}],"source_content_type":"text/x-python","patch_set":15,"id":"930e3878_fbd168c7","line":71,"in_reply_to":"986dbfca_d8a2b9b8","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"}],"couchbase/logic/observability/observability_types.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":121,"context_line":"    Analytics \u003d \u0027analytics\u0027"},{"line_number":122,"context_line":"    Eventing \u003d \u0027eventing\u0027"},{"line_number":123,"context_line":"    KeyValue \u003d \u0027kv\u0027"},{"line_number":124,"context_line":"    KeyValueMulti \u003d \u0027kv_multi\u0027"},{"line_number":125,"context_line":"    Management \u003d \u0027management\u0027"},{"line_number":126,"context_line":"    Query \u003d \u0027query\u0027"},{"line_number":127,"context_line":"    Search \u003d \u0027search\u0027"}],"source_content_type":"text/x-python","patch_set":15,"id":"e59eee04_dbe2a3d9","line":124,"updated":"2026-03-12 17:52:14.000000000","message":"What was the motivation behind having `kv_multi` be a separate service?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":121,"context_line":"    Analytics \u003d \u0027analytics\u0027"},{"line_number":122,"context_line":"    Eventing \u003d \u0027eventing\u0027"},{"line_number":123,"context_line":"    KeyValue \u003d \u0027kv\u0027"},{"line_number":124,"context_line":"    KeyValueMulti \u003d \u0027kv_multi\u0027"},{"line_number":125,"context_line":"    Management \u003d \u0027management\u0027"},{"line_number":126,"context_line":"    Query \u003d \u0027query\u0027"},{"line_number":127,"context_line":"    Search \u003d \u0027search\u0027"}],"source_content_type":"text/x-python","patch_set":15,"id":"597ce45d_5c454f8d","line":124,"in_reply_to":"e59eee04_dbe2a3d9","updated":"2026-03-13 20:56:59.000000000","message":"It seems that the multi methods are different enough to where having that as a separate service could have potential for being useful.  But, I have removed this in the latest patchset.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":145,"context_line":"        return ServiceType(service_type)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    @classmethod"},{"line_number":148,"context_line":"    def from_op_type(cls, opt_type: OpTypes) -\u003e ServiceType:"},{"line_number":149,"context_line":"        if isinstance(opt_type, KeyValueMultiOperationType):"},{"line_number":150,"context_line":"            return ServiceType.KeyValueMulti"},{"line_number":151,"context_line":"        elif isinstance(opt_type, (KeyValueOperationType, DatastructureOperationType)):"}],"source_content_type":"text/x-python","patch_set":15,"id":"97ccb5e5_bd4d9199","line":148,"updated":"2026-03-12 17:52:14.000000000","message":"This can, in theory, also return `None`. Should there be an exception if the service type can\u0027t be determined?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        return ServiceType(service_type)"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"    @classmethod"},{"line_number":148,"context_line":"    def from_op_type(cls, opt_type: OpTypes) -\u003e ServiceType:"},{"line_number":149,"context_line":"        if isinstance(opt_type, KeyValueMultiOperationType):"},{"line_number":150,"context_line":"            return ServiceType.KeyValueMulti"},{"line_number":151,"context_line":"        elif isinstance(opt_type, (KeyValueOperationType, DatastructureOperationType)):"}],"source_content_type":"text/x-python","patch_set":15,"id":"2984c088_789e7457","line":148,"in_reply_to":"97ccb5e5_bd4d9199","updated":"2026-03-13 20:56:59.000000000","message":"Done","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":168,"context_line":"                                   SearchIndexMgmtOperationType,"},{"line_number":169,"context_line":"                                   UserMgmtOperationType,"},{"line_number":170,"context_line":"                                   ViewIndexMgmtOperationType)):"},{"line_number":171,"context_line":"            return ServiceType.Management"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"class OpAttributeName(Enum):"}],"source_content_type":"text/x-python","patch_set":15,"id":"38a38f75_a776d9bf","line":171,"updated":"2026-03-12 17:52:14.000000000","message":"Management is meant to be used only for ns_server operations, (user, collection, bucket management). For other management operations, it should represent the underlying service. For `EventingFunctionManager`, that\u0027s eventing, for `QueryIndexManager` query, and so on.\n\nFrom the [RFC](https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0067-extended-sdk-observability-rto-v2.md#attribute-service-identifier):\n\u003e The management service should only be used by requests which actually go to the cluster manager. If a management operation i.e. executes a N1QL query it should use the query service instead. The span name already reflects the actual operation type.","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":false,"context_lines":[{"line_number":168,"context_line":"                                   SearchIndexMgmtOperationType,"},{"line_number":169,"context_line":"                                   UserMgmtOperationType,"},{"line_number":170,"context_line":"                                   ViewIndexMgmtOperationType)):"},{"line_number":171,"context_line":"            return ServiceType.Management"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"class OpAttributeName(Enum):"}],"source_content_type":"text/x-python","patch_set":15,"id":"f63c21d7_494c535a","line":171,"in_reply_to":"38a38f75_a776d9bf","updated":"2026-03-13 20:56:59.000000000","message":"Thanks for calling me out!  Forgot about that.  Updated in the latest patchset 👍","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"}],"couchbase/options.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"5ff910efda28f074691ff5811f53a328b42ecbf0","unresolved":true,"context_lines":[{"line_number":897,"context_line":"    def __init__("},{"line_number":898,"context_line":"        self,"},{"line_number":899,"context_line":"        timeout\u003dNone,           # type: Optional[timedelta]"},{"line_number":900,"context_line":"        span\u003dNone,              # type: Optional[SpanProtocol]"},{"line_number":901,"context_line":"        transcoder\u003dNone,        # type: Optional[Transcoder]"},{"line_number":902,"context_line":"        read_preference\u003dNone,   # type: Optional[ReadPreference]"},{"line_number":903,"context_line":"        per_key_options\u003dNone,   # type: Dict[str, GetAllReplicasOptions]"}],"source_content_type":"text/x-python","patch_set":15,"id":"c3720b6d_2111c8e5","line":900,"updated":"2026-03-12 17:52:14.000000000","message":"Should this option be called `parent_span` instead? That would make it consistent with other SDKs and the RFC: https://github.com/couchbaselabs/sdk-rfcs/blob/master/rfc/0067-extended-sdk-observability-rto-v2.md#sdk-api-surface-area\n\nDoes the type need to be `SpanProtocol`? That appears to be an internal type. Would it not be better to use the `RequestSpan` abstract base class here?","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"bd7eb33e898830601c1e9ecc37c1ff7a40bef045","unresolved":true,"context_lines":[{"line_number":897,"context_line":"    def __init__("},{"line_number":898,"context_line":"        self,"},{"line_number":899,"context_line":"        timeout\u003dNone,           # type: Optional[timedelta]"},{"line_number":900,"context_line":"        span\u003dNone,              # type: Optional[SpanProtocol]"},{"line_number":901,"context_line":"        transcoder\u003dNone,        # type: Optional[Transcoder]"},{"line_number":902,"context_line":"        read_preference\u003dNone,   # type: Optional[ReadPreference]"},{"line_number":903,"context_line":"        per_key_options\u003dNone,   # type: Dict[str, GetAllReplicasOptions]"}],"source_content_type":"text/x-python","patch_set":15,"id":"cdab57dc_ed911b74","line":900,"in_reply_to":"c3720b6d_2111c8e5","updated":"2026-03-13 20:56:59.000000000","message":"So this is somewhat tricky.  At first I was thinking `parent_span`, but then I thought maybe I should be consistent w/ the SDK, which uses `span` historically. However, the path I decided on (after thinking about your comment) is that for option blocks that previously had `span`, I have added `parent_span`.  All option blocks that are new to supporting spans, those will only have `parent_span`.\n\nFor the type, we REALLY want to discourage the use of the deprecated/legacy observability \u0027things\u0027.  So, the doc strings only reference the `parent_span` (even if `span` is okay) and we type those w/ the new `RequestSpan`.  However, we need to support the `SpanProtocol` for both (`span` and `parent_span`) as I only wanted to go so far to add logic in splitting out the legacy vs. modern tracing. I added a static method (`maybe_get_parent_span`) to the `ObservableRequestHandler` to try and iron out the type of span and raise warnings/errors where appropriate.\n\nAlso, I dunno if I\u0027d see `SpanProtocol` is \"internal\" per-say.  I moved it to the `logic` package as it provided a bit more flexibility w.r.t. avoiding circular imports (and to a user we can call it internal which means we can move it around as needed while we sort out typing and restructuring for new protocol support).  Soon, when we have a `common` package, that is where the `SpanProtocol` would live (unless I can get permission to remove all the legacy cruft, which means we only need `RequestSpan` and don\u0027t need to worry about these hoops...one can hope 😊).\n\nCurious to your thoughts!","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"},{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"315da8f4760081051a7986d16e9f50f629118287","unresolved":false,"context_lines":[{"line_number":897,"context_line":"    def __init__("},{"line_number":898,"context_line":"        self,"},{"line_number":899,"context_line":"        timeout\u003dNone,           # type: Optional[timedelta]"},{"line_number":900,"context_line":"        span\u003dNone,              # type: Optional[SpanProtocol]"},{"line_number":901,"context_line":"        transcoder\u003dNone,        # type: Optional[Transcoder]"},{"line_number":902,"context_line":"        read_preference\u003dNone,   # type: Optional[ReadPreference]"},{"line_number":903,"context_line":"        per_key_options\u003dNone,   # type: Dict[str, GetAllReplicasOptions]"}],"source_content_type":"text/x-python","patch_set":15,"id":"97a7ebb9_b2b4ac6c","line":900,"in_reply_to":"cdab57dc_ed911b74","updated":"2026-03-20 17:13:21.000000000","message":"Thanks for the explanation, this makes sense. I see now where the need for `SpanProtocol` is coming from, and I suppose since it\u0027s just a type hint it doesn\u0027t really matter that it\u0027s from the logic package (since users wouldn\u0027t use it directly)","commit_id":"6fde1860676332aa86303553adcdbe7c3b3b357e"}],"couchbase/tests/tracing_tests/streaming_t.py":[{"author":{"_account_id":1005035,"name":"Dimitris Christodoulou","email":"dimitris.christodoulou@couchbase.com","username":"DemetrisChr","avatars":[{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/4291f7baa025a5558b77019a9c264ab2.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"60651ed8c8a866c3d25c5e956df0b48d329c0a3c","unresolved":true,"context_lines":[{"line_number":162,"context_line":"            pass"},{"line_number":163,"context_line":"        validator.validate_http_op()"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"        if cb_env.server_version_short \u003c\u003d 6.6:"},{"line_number":166,"context_line":"            return  # scope-level query support added in server 7.0, so skip rest of test if not supported"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        validator \u003d cb_env.http_span_validator"}],"source_content_type":"text/x-python","patch_set":29,"id":"f3f3db58_93c60ce3","line":165,"updated":"2026-03-25 14:36:14.000000000","message":"Should this be a `EnvironmentFeatures.is_feature_supported(\u0027collections\u0027, ...)` call instead?","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"},{"author":{"_account_id":1004568,"name":"Jared Casey","email":"jared.casey@couchbase.com","username":"thejcfactor","avatars":[{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d32","height":32},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d56","height":56},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d100","height":100},{"url":"https://www.gravatar.com/avatar/20ac69da8a1fb4cc11bdd1c880389132.jpg?d\u003didenticon\u0026r\u003dpg\u0026s\u003d120","height":120}]},"change_message_id":"ba921cf0b8b36b80da6f073becbf81809d9df24a","unresolved":false,"context_lines":[{"line_number":162,"context_line":"            pass"},{"line_number":163,"context_line":"        validator.validate_http_op()"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"        if cb_env.server_version_short \u003c\u003d 6.6:"},{"line_number":166,"context_line":"            return  # scope-level query support added in server 7.0, so skip rest of test if not supported"},{"line_number":167,"context_line":""},{"line_number":168,"context_line":"        validator \u003d cb_env.http_span_validator"}],"source_content_type":"text/x-python","patch_set":29,"id":"fcb6dee0_64aa0d9a","line":165,"in_reply_to":"f3f3db58_93c60ce3","updated":"2026-03-25 18:31:51.000000000","message":"Done","commit_id":"70a8a89ebf8b70af6b368d28ac282da7de5857c8"}]}
