gql icon indicating copy to clipboard operation
gql copied to clipboard

[WebsocketLink] Question - is recreating a channel a memory leak?

Open yevyevyev opened this issue 3 years ago • 5 comments

Hi, is recreating the channel without disposing the previous one considered a memory leak?

_connectionStateController.add(connecting);
_channel = await _channelGenerator();
_reconnectTimer?.cancel();

yevyevyev avatar Aug 31 '21 13:08 yevyevyev

_channel = await _channelGenerator();

This line will delegate the channel delegation to the user, you have to close the old channel after you are done with it or when regenerating a new one.

agent3bood avatar Aug 31 '21 15:08 agent3bood

So if I need to close the ws connection by myself, then there is a memory leak in WebSocketLink constructor?

WebSocketLink(
    String? uri, {
    ChannelGenerator? channelGenerator,
    this.autoReconnect = true,
    this.reconnectInterval = const Duration(seconds: 10),
    this.serializer = const RequestSerializer(),
    this.parser = const ResponseParser(),
    this.graphQLSocketMessageEncoder = _defaultGraphQLSocketMessageEncoder,
    this.graphQLSocketMessageDecoder = _defaultGraphQLSocketMessageDecoder,
    this.initialPayload,
    this.inactivityTimeout,
  }) : assert((uri == null && channelGenerator != null) ||
            (uri != null && channelGenerator == null)) {
    _channelGenerator =
        channelGenerator ?? () => WebSocketChannel.connect(Uri.parse(uri!));
  }

The default channel generator creates new channel each reconnection.

yevyevyev avatar Sep 01 '21 11:09 yevyevyev

@tapkain This make sense, Thanks for the feedback.

agent3bood avatar Sep 01 '21 12:09 agent3bood

@tapkain what do you mean by saying dispose a channel? Are you storing the WebSocketChannel as a property and then calling _channel?.innerWebSocket?.close() on it? Thanks

vysotsky avatar Oct 22 '21 12:10 vysotsky

@vysotsky not sure as well what do you mean :D the channel generator will create each reconnect a new web socket channel, and the previous one won't be disposed. Disposing is closing the sink, eg channel.sink.close() it needs to be done cause if the previous stream will have listeners, those listeners will be subscribed to old stream which was not closed properly. Not a big deal but can cause troubles in some cases.

yevyevyev avatar Oct 25 '21 16:10 yevyevyev