From 326a5276c81600ef7bae790ca85a8c26332fc7ca Mon Sep 17 00:00:00 2001 From: blakeroberts-wk Date: Wed, 21 May 2025 10:07:20 -0600 Subject: [PATCH 1/2] add timeout option unit test --- lib/src/client.dart | 3 +++ test/sockjs_client_wrapper_test.dart | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/src/client.dart b/lib/src/client.dart index 346c59e..0e83f9f 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -15,6 +15,7 @@ import 'dart:async'; import 'dart:js'; +import 'dart:js_util' as js_util; import 'package:js/js.dart'; import 'package:w_common/disposable_browser.dart'; @@ -117,6 +118,8 @@ class SockJSClient extends Disposable { /// The event will include the selected transport as well as the server URL. Stream get onOpen => _onOpenController.stream; + num get timeout => js_util.getProperty(_jsClient, '_timeout'); + /// Close this client. /// /// Optionally, a [closeCode] and [reason] can be provided. diff --git a/test/sockjs_client_wrapper_test.dart b/test/sockjs_client_wrapper_test.dart index 69914a3..60f905c 100644 --- a/test/sockjs_client_wrapper_test.dart +++ b/test/sockjs_client_wrapper_test.dart @@ -96,6 +96,12 @@ void main() { client.close(); await Future.wait([client.onClose.first, client.didDispose]); }); + + test('timeout option should set a timeout', () async { + final options = SockJSOptions(timeout: 1000); + final client = SockJSClient(_echoUri, options: options)..close(); + expect(client.timeout, equals(1000)); + }); }); } From 2f22d87c05a758ad9588402a0c88a90489618bbd Mon Sep 17 00:00:00 2001 From: blakeroberts-wk Date: Wed, 21 May 2025 10:14:30 -0600 Subject: [PATCH 2/2] add otel instrumentation --- lib/src/client.dart | 25 ++++++++++++++++++++++++- pubspec.yaml | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/src/client.dart b/lib/src/client.dart index 0e83f9f..ed332f7 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -18,6 +18,7 @@ import 'dart:js'; import 'dart:js_util' as js_util; import 'package:js/js.dart'; +import 'package:opentelemetry/api.dart'; import 'package:w_common/disposable_browser.dart'; import 'package:sockjs_client_wrapper/src/events.dart'; @@ -54,6 +55,16 @@ class SockJSClient extends Disposable { final StreamController _onOpenController = StreamController.broadcast(); + /// Context used to capture open and close events while establishing the + /// initial connection. + /// + /// This value is set to the current context during construction, then set to + /// root after the first open or close event. This is to correlate events + /// related to initial connection with the construction of this object without + /// creating long running traces due to events from much further along in the + /// sessions lifetime. + Context _context; + /// Constructs a new [SockJSClient] that will attempt to connect to a SockJS /// server at the given [uri]. /// @@ -71,7 +82,7 @@ class SockJSClient extends Disposable { /// final options = new SockJSOptions( /// transports: ['websocket', 'xhr-streaming', 'xhr-polling']); /// final client = new SockJSClient(uri, options: options); - SockJSClient(Uri uri, {SockJSOptions? options}) { + SockJSClient(Uri uri, {SockJSOptions? options}) : _context = Context.current { try { _jsClient = js_interop.SockJS(uri.toString(), null, options?._toJs()); // ignore: avoid_catches_without_on_clauses @@ -156,6 +167,13 @@ class SockJSClient extends Disposable { } void _onClose(js_interop.SockJSCloseEvent event) { + spanFromContext(_context).addEvent('sockjs.close', attributes: [ + Attribute.fromString('sockjs.transport', _jsClient.transport), + Attribute.fromDouble('sockjs.timeout', timeout.toDouble()), + Attribute.fromInt('sockjs.close.code', event.code), + Attribute.fromString('sockjs.close.reason', event.reason), + ]); + _context = Context.root; // Reset context to root for future events. _onCloseController.add(SockJSCloseEvent( event.code, event.reason, @@ -168,6 +186,11 @@ class SockJSClient extends Disposable { } void _onOpen(_) { + spanFromContext(_context).addEvent('sockjs.open', attributes: [ + Attribute.fromString('sockjs.transport', _jsClient.transport), + Attribute.fromDouble('sockjs.timeout', timeout.toDouble()), + ]); + _context = Context.root; // Reset context to root for future events. _onOpenController.add(SockJSOpenEvent( _jsClient.transport, Uri.parse(_jsClient.url), diff --git a/pubspec.yaml b/pubspec.yaml index 9e775cd..277aac0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: js: ^0.6.1 w_common: '>=2.0.0 <4.0.0' + opentelemetry: ^0.18.10 dev_dependencies: build_runner: ^2.1.2