Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better unsubscription handling #14270

Open
3 tasks done
no6v opened this issue Mar 6, 2025 · 0 comments
Open
3 tasks done

Better unsubscription handling #14270

no6v opened this issue Mar 6, 2025 · 0 comments
Assignees
Labels
GraphQL Related to GraphQL API issues pending-maintainer-response Issue is pending a response from the Amplify team. pending-triage Issue is pending triage

Comments

@no6v
Copy link

no6v commented Mar 6, 2025

Before opening, please confirm:

JavaScript Framework

Next.js

Amplify APIs

GraphQL API

Amplify Version

v6

Amplify Categories

api

Backend

Amplify Gen 2

Environment information

# Put output below this line

  System:
    OS: Linux 6.1 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (4) x64 Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
    Memory: 11.01 GB / 15.07 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 18.19.0 - /usr/bin/node
    Yarn: 1.22.19 - ~/bin/yarn
    npm: 9.2.0 - /usr/bin/npm
  Browsers:
    Chrome: 133.0.6943.141
  npmPackages:
    @ampproject/toolbox-optimizer:  undefined ()
    @aws-amplify/backend: ^1.0.0 => 1.14.1 
    @aws-amplify/backend-cli: ^1.0.1 => 1.4.11 
    @aws-amplify/ui-react: ^6.1.12 => 6.9.3 
    @aws-amplify/ui-react-internal:  undefined ()
    @aws-amplify/ui-react-server:  undefined ()
    @aws-sdk/client-cognito-identity-provider: ^3.596.0 => 3.760.0 
    @babel/core:  undefined ()
    @babel/runtime:  7.22.5 
    @edge-runtime/cookies:  5.0.0 
    @edge-runtime/ponyfill:  3.0.0 
    @edge-runtime/primitives:  5.0.0 
    @emotion/react: ^11.14.0 => 11.14.0 
    @emotion/styled: ^11.14.0 => 11.14.0 
    @hapi/accept:  undefined ()
    @mswjs/interceptors:  undefined ()
    @mui/material: ^6.4.4 => 6.4.7 
    @napi-rs/triples:  undefined ()
    @next/font:  undefined ()
    @opentelemetry/api:  undefined ()
    @stylistic/eslint-plugin-js: ^2.3.0 => 2.13.0 
    @testing-library/jest-dom: ^6.4.8 => 6.6.3 
    @testing-library/react: ^16.0.0 => 16.2.0 
    @types/jest: ^29.5.12 => 29.5.14 
    @types/node: ^20 => 20.17.23 
    @types/react: ^18 => 18.3.18 
    @types/react-dom: ^18 => 18.3.5 
    @typescript-eslint/eslint-plugin: ^7.15.0 => 7.18.0 
    @vercel/nft:  undefined ()
    @vercel/og:  0.6.3 
    acorn:  undefined ()
    amphtml-validator:  undefined ()
    anser:  undefined ()
    arg:  undefined ()
    assert:  undefined ()
    async-retry:  undefined ()
    async-sema:  undefined ()
    aws-amplify: ^6.2.0 => 6.13.3 
    aws-amplify/adapter-core:  undefined ()
    aws-amplify/adapter-core/internals:  undefined ()
    aws-amplify/analytics:  undefined ()
    aws-amplify/analytics/kinesis:  undefined ()
    aws-amplify/analytics/kinesis-firehose:  undefined ()
    aws-amplify/analytics/personalize:  undefined ()
    aws-amplify/analytics/pinpoint:  undefined ()
    aws-amplify/api:  undefined ()
    aws-amplify/api/internals:  undefined ()
    aws-amplify/api/server:  undefined ()
    aws-amplify/auth:  undefined ()
    aws-amplify/auth/cognito:  undefined ()
    aws-amplify/auth/cognito/server:  undefined ()
    aws-amplify/auth/enable-oauth-listener:  undefined ()
    aws-amplify/auth/server:  undefined ()
    aws-amplify/data:  undefined ()
    aws-amplify/data/server:  undefined ()
    aws-amplify/datastore:  undefined ()
    aws-amplify/in-app-messaging:  undefined ()
    aws-amplify/in-app-messaging/pinpoint:  undefined ()
    aws-amplify/push-notifications:  undefined ()
    aws-amplify/push-notifications/pinpoint:  undefined ()
    aws-amplify/storage:  undefined ()
    aws-amplify/storage/s3:  undefined ()
    aws-amplify/storage/s3/server:  undefined ()
    aws-amplify/storage/server:  undefined ()
    aws-amplify/utils:  undefined ()
    babel-packages:  undefined ()
    browserify-zlib:  undefined ()
    browserslist:  undefined ()
    buffer:  undefined ()
    bytes:  undefined ()
    ci-info:  undefined ()
    cli-select:  undefined ()
    client-only:  0.0.1 
    commander:  undefined ()
    comment-json:  undefined ()
    compression:  undefined ()
    conf:  undefined ()
    constants-browserify:  undefined ()
    content-disposition:  undefined ()
    content-type:  undefined ()
    cookie:  undefined ()
    cross-spawn:  undefined ()
    crypto-browserify:  undefined ()
    css.escape:  undefined ()
    data-uri-to-buffer:  undefined ()
    debug:  undefined ()
    devalue:  undefined ()
    domain-browser:  undefined ()
    edge-runtime:  undefined ()
    eslint: ^8.57.0 => 8.57.1 
    eslint-config-next: ^14.2.4 => 14.2.24 
    events:  undefined ()
    find-cache-dir:  undefined ()
    find-up:  undefined ()
    fresh:  undefined ()
    get-orientation:  undefined ()
    glob:  undefined ()
    gzip-size:  undefined ()
    http-proxy:  undefined ()
    http-proxy-agent:  undefined ()
    https-browserify:  undefined ()
    https-proxy-agent:  undefined ()
    icss-utils:  undefined ()
    ignore-loader:  undefined ()
    image-size:  undefined ()
    is-animated:  undefined ()
    is-docker:  undefined ()
    is-wsl:  undefined ()
    jest: ^29.7.0 => 29.7.0 
    jest-environment-jsdom: ^29.7.0 => 29.7.0 
    jest-worker:  undefined ()
    json5:  undefined ()
    jsonwebtoken:  undefined ()
    loader-runner:  undefined ()
    loader-utils:  undefined ()
    lodash.curry:  undefined ()
    lru-cache:  undefined ()
    mini-css-extract-plugin:  undefined ()
    nanoid:  undefined ()
    native-url:  undefined ()
    neo-async:  undefined ()
    next: ^14.2.3 => 14.2.24 
    node-fetch:  undefined ()
    node-html-parser:  undefined ()
    ora:  undefined ()
    os-browserify:  undefined ()
    p-limit:  undefined ()
    path-browserify:  undefined ()
    picomatch:  undefined ()
    platform:  undefined ()
    postcss-flexbugs-fixes:  undefined ()
    postcss-modules-extract-imports:  undefined ()
    postcss-modules-local-by-default:  undefined ()
    postcss-modules-scope:  undefined ()
    postcss-modules-values:  undefined ()
    postcss-preset-env:  undefined ()
    postcss-safe-parser:  undefined ()
    postcss-scss:  undefined ()
    postcss-value-parser:  undefined ()
    process:  undefined ()
    punycode:  undefined ()
    querystring-es3:  undefined ()
    raw-body:  undefined ()
    react: ^18 => 18.3.1 
    react-builtin:  undefined ()
    react-dom: ^18 => 18.3.1 
    react-dom-builtin:  undefined ()
    react-dom-experimental-builtin:  undefined ()
    react-experimental-builtin:  undefined ()
    react-is:  18.2.0 
    react-refresh:  0.12.0 
    react-server-dom-turbopack-builtin:  undefined ()
    react-server-dom-turbopack-experimental-builtin:  undefined ()
    react-server-dom-webpack-builtin:  undefined ()
    react-server-dom-webpack-experimental-builtin:  undefined ()
    regenerator-runtime:  0.13.4 
    sass-loader:  undefined ()
    scheduler-builtin:  undefined ()
    scheduler-experimental-builtin:  undefined ()
    schema-utils:  undefined ()
    semver:  undefined ()
    send:  undefined ()
    server-only:  0.0.1 
    setimmediate:  undefined ()
    shell-quote:  undefined ()
    source-map:  undefined ()
    source-map08:  undefined ()
    stacktrace-parser:  undefined ()
    stream-browserify:  undefined ()
    stream-http:  undefined ()
    string-hash:  undefined ()
    string_decoder:  undefined ()
    strip-ansi:  undefined ()
    superstruct:  undefined ()
    tar:  undefined ()
    terser:  undefined ()
    text-table:  undefined ()
    timers-browserify:  undefined ()
    ts-jest: ^29.2.4 => 29.2.6 
    tty-browserify:  undefined ()
    typescript: ^5.3.2 => 5.8.2 (4.4.4, 4.9.5)
    ua-parser-js:  undefined ()
    unistore:  undefined ()
    util:  undefined ()
    uuid: ^10.0.0 => 10.0.0 (9.0.1)
    vm-browserify:  undefined ()
    watchpack:  undefined ()
    web-vitals:  undefined ()
    webpack:  undefined ()
    webpack-sources:  undefined ()
    ws:  undefined ()
    zod:  undefined ()
  npmGlobalPackages:
    typescript-language-server: 4.3.3
    typescript: 5.7.3

Describe the bug

Hello,

I encountered MaxSubscriptionsReachedError. There were some similar issues reported in this repository, and it seems the most of the problems are caused by unsubscription handling.

The script below is a simplified Provider, and try to simulateunsubscribe() right after subscribe() to the subscription. This can happen in development build environment of React application, etc.

The result is cannot wait for subscription to be connected. This means that the _waitForSubscriptionToBeConnected cannot wait for subscription to be connected properly, of course it depends on the situation.

The very first subscriptionObserverMap.set() requires only query, variables and observer essentially, so we can be done it right after the subscriptionId is issued. How do you feel?

Thanks,

Expected behavior

Unsubscription message should be sent even if unsubscribe immediately.

Reproduction steps

A proof of concept code below.

Code Snippet

import { Observable } from "rxjs";

class SimpleProvier {
  constructor() {
    this.map = new Map();
  }

  subscribe() {
    return new Observable((observer) => {
      const id = "ID";
      // this.map.set(id, { observer }); // preferred here
      const startSubscription = () => {
        this._startSubscriptionWithAWSAppSyncRealTime({ observer, id }).catch().finally();
      }
      startSubscription();
      return async () => {
        await this._cleanupSubscription(id);
      }
    });
  }

  async additionalHeadersFromOptions() {
    return {}
  }

  async _startSubscriptionWithAWSAppSyncRealTime({ observer, id }) {
    await this.additionalHeadersFromOptions();
    this.map.set(id, { observer }); // current
  }

  async _cleanupSubscription(id) {
    await this._waitForSubscriptionToBeConnected(id);
  }

  async _waitForSubscriptionToBeConnected(id) {
    const subscriptionObserver = this.map.get(id);
    if (subscriptionObserver) {
      console.log(subscriptionObserver.observer);
    } else {
      console.error("cannot wait for subscription to be connected");
    }
  }
}

const provier = new SimpleProvier();
provier.subscribe().subscribe().unsubscribe();

Log output

// Put your logs below this line


aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

No response

@github-actions github-actions bot added pending-triage Issue is pending triage pending-maintainer-response Issue is pending a response from the Amplify team. labels Mar 6, 2025
@HuiSF HuiSF added the GraphQL Related to GraphQL API issues label Mar 6, 2025
@chrisbonifacio chrisbonifacio self-assigned this Mar 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GraphQL Related to GraphQL API issues pending-maintainer-response Issue is pending a response from the Amplify team. pending-triage Issue is pending triage
Projects
None yet
Development

No branches or pull requests

3 participants