Skip to content

Chat Stream Hangs for 15 Seconds After Completion #206

@geomags3

Description

@geomags3

When using OpenAI.instance.chat.createStream to create a chat completion stream, the stream remains open for ~15 seconds after completion, even after calling subscription.cancel(). The delay disappears when the subscription is cancelled manually after a short delay.

Steps to Reproduce

  1. Create a chat stream using OpenAI.instance.chat.createStream().
  2. Subscribe to the stream and print responses.
  3. Manually cancel the subscription after a short delay (e.g., 1 second).
  4. Observe that without manual cancellation, the process hangs for ~15 seconds.

Expected Behavior

  • When the stream completes, it should close immediately.
  • Calling subscription.cancel() should immediately stop any lingering connections.

Actual Behavior

  • After "Stream completed" and "Subscription cancelled", the process hangs for ~15 seconds before stopping.
  • When subscription.cancel() is delayed by 1 second, the process stops immediately.

Example Code

🛑 Problem: 15-Second Delay Without Manual Cancellation

import 'dart:async';
import 'package:dart_openai/dart_openai.dart';

void main() async {
  OpenAI.apiKey = 'your-api-key';

  Stream stream = OpenAI.instance.chat.createStream(
    model: 'gpt-4o-mini',
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        content: [OpenAIChatCompletionChoiceMessageContentItemModel.text('Tell me 10 jokes.')],
        role: OpenAIChatMessageRole.user,
      ),
    ],
  );

  late StreamSubscription sub;
  sub = stream.listen(
    (res) => print(res.choices),
    onDone: () async {
      print('✅ Stream completed');
      await sub.cancel();
      print('✅ Subscription cancelled');
    },
    onError: (e) => print('❌ Stream error: $e'),
  );

  // ❌ No manual cancellation
}

⏳ Observed Behavior:

[Assistant Response: Joke 1]
...
[Assistant Response: Joke 10]
✅ Stream completed
✅ Subscription cancelled
(Hangs for 15 seconds)

✅ Immediate Termination with Manual Delay + sub.cancel()

import 'dart:async';
import 'package:dart_openai/dart_openai.dart';

void main() async {
  OpenAI.apiKey = 'your-api-key';

  Stream stream = OpenAI.instance.chat.createStream(
    model: 'gpt-4o-mini',
    messages: [
      OpenAIChatCompletionChoiceMessageModel(
        content: [OpenAIChatCompletionChoiceMessageContentItemModel.text('Tell me 10 jokes.')],
        role: OpenAIChatMessageRole.user,
      ),
    ],
  );

  late StreamSubscription sub;
  sub = stream.listen(
    (res) => print(res.choices),
    onDone: () async {
      print('✅ Stream completed');
      await sub.cancel();
      print('✅ Subscription cancelled');
    },
    onError: (e) => print('❌ Stream error: $e'),
  );

  // ✅ Manual delayed cancellation stops the process immediately
  await Future.delayed(const Duration(seconds: 1));
  await sub.cancel();
  print('✅ Manually cancelled subscription after delay');
}

🚀 Observed Behavior:

[Assistant Response: Joke 1]
...
[Assistant Response: Joke 10]
✅ Stream completed
✅ Subscription cancelled
✅ Manually cancelled subscription after delay
(Process stops immediately)

Would appreciate any insights or workarounds! Thanks! 🙌

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions