Skip to content

Mongoose multiple connection; disconnecting not work. #9107

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

Closed
mhf-ir opened this issue Jun 8, 2020 · 1 comment
Closed

Mongoose multiple connection; disconnecting not work. #9107

mhf-ir opened this issue Jun 8, 2020 · 1 comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@mhf-ir
Copy link

mhf-ir commented Jun 8, 2020

const mongoose = require('mongoose');

class Mongoose {
  constructor(Config) {
    this.ACTIVE_URI = Config.ACTIVE_URI;
    this.ARCHIVE_URI = Config.ARCHIVE_URI;

    /** @type {import('mongoose').Mongoose} */
    this.activeConnection = undefined;
    /** @type {import('mongoose').Mongoose} */
    this.archiveConnection = undefined;
  }

  async getActiveConnection() {
    if (!this.activeConnection) {
      console.log('connection is not set so try to connect new ACTIVE');
      this.activeConnection = await mongoose.connect(this.ACTIVE_URI, {
        useCreateIndex: true,
        useFindAndModify: false,
        useUnifiedTopology: true,
        useNewUrlParser: true,
        family: 4,
      });
    }
    return this.activeConnection;
  }

  async quiteActive() {
    if (this.activeConnection) {
      console.log('connection is ready so try to disconnect, ACTIVE');
      console.log(this.activeConnection.connection.readyState);
      await this.activeConnection.disconnect();
      console.log(this.activeConnection.connection.readyState);
      this.activeConnection = undefined;
    }
  }

  async getArchiveConnection() {
    if (!this.archiveConnection) {
      console.log('connection is not set so try to connect new ARCHIVE');
      this.archiveConnection = await mongoose.connect(this.ARCHIVE_URI, {
        useCreateIndex: true,
        useFindAndModify: false,
        useUnifiedTopology: true,
        useNewUrlParser: true,
        family: 4,
      });
    }
    return this.archiveConnection;
  }

  async quiteArchive() {
    if (this.archiveConnection) {
      console.log('connection is ready so try to disconnect, ARCHIVE');
      console.log(this.archiveConnection.connection.readyState);
      await this.archiveConnection.disconnect();
      console.log(this.archiveConnection.connection.readyState);

      this.archiveConnection = undefined;
    }
  }

  async quite() {
    await this.quiteActive();
    await this.quiteArchive();
  }
}

(async () => {
  const m = new Mongoose({
    ACTIVE_URI: process.env.ACTIVE_URI,
    ARCHIVE_URI: process.env.ARCHIVE_URI,
  });
  await m.getActiveConnection();
  await m.getActiveConnection();
  await m.getArchiveConnection();
  await m.getArchiveConnection();
  await new Promise((r) => setTimeout(r, 1000));
  console.log('after connected :D');

  await m.quite();
  await m.quite();
  console.log(process._getActiveHandles());
  // console.log(process._getActiveRequests() ); = []
  console.log('after all disconnected :D');
})();

Output:

connection is not set so try to connect new ACTIVE
connection is not set so try to connect new ARCHIVE
after connected :D
connection is ready so try to disconnect, ACTIVE
1
0
connection is ready so try to disconnect, ARCHIVE
0
0
[
  <ref *1> WriteStream {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: null,
      ended: false,
      endEmitted: false,
      reading: false,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      errored: false,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      readable: false,
      [Symbol(kPaused)]: null
    },
    _events: [Object: null prototype] { end: [Function: onReadableStreamEnd] },
    _eventsCount: 1,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      errored: false,
      closed: false
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    columns: 180,
    rows: 32,
    _type: 'tty',
    fd: 2,
    _isStdio: true,
    destroySoon: [Function: destroy],
    _destroy: [Function: dummyDestroy],
    [Symbol(async_id_symbol)]: 3,
    [Symbol(kHandle)]: TTY { [Symbol(owner)]: [Circular *1] },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  <ref *2> WriteStream {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: null,
      ended: false,
      endEmitted: false,
      reading: false,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      errored: false,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      readable: false,
      [Symbol(kPaused)]: null
    },
    _events: [Object: null prototype] { end: [Function: onReadableStreamEnd] },
    _eventsCount: 1,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: [Object],
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 4,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      errored: false,
      closed: false
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    columns: 180,
    rows: 32,
    _type: 'tty',
    fd: 1,
    _isStdio: true,
    destroySoon: [Function: destroy],
    _destroy: [Function: dummyDestroy],
    [Symbol(async_id_symbol)]: 5,
    [Symbol(kHandle)]: TTY { [Symbol(owner)]: [Circular *2] },
    [Symbol(kSetNoDelay)]: false,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  <ref *3> Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: 'mongo-active',
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [Array],
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      destroyed: false,
      errored: false,
      closed: false,
      closeEmitted: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    _events: [Object: null prototype] {
      end: [Array],
      error: [Array],
      close: [Array],
      timeout: [Function (anonymous)],
      data: [Function: ondata],
      unpipe: [Function: onunpipe],
      finish: [Function]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: false,
      autoDestroy: false,
      errored: false,
      closed: false,
      writable: true
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: null,
    _server: null,
    timeout: 360000,
    _peername: { address: '172.17.0.3', family: 'IPv4', port: 27017 },
    [Symbol(async_id_symbol)]: 9,
    [Symbol(kHandle)]: TCP {
      reading: true,
      onconnection: null,
      [Symbol(owner)]: [Circular *3]
    },
    [Symbol(kSetNoDelay)]: true,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: Timeout {
      _idleTimeout: 360000,
      _idlePrev: [TimersList],
      _idleNext: [TimersList],
      _idleStart: 298,
      _onTimeout: [Function: bound ],
      _timerArgs: undefined,
      _repeat: null,
      _destroyed: false,
      [Symbol(refed)]: false,
      [Symbol(asyncId)]: 21,
      [Symbol(triggerId)]: 9
    },
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  }
]
after all disconnected :D

Problem

seems be after disconnect still remain ActiveHandle for process.

@vkarpov15 vkarpov15 added this to the 5.9.20 milestone Jun 11, 2020
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Jun 11, 2020
@vkarpov15
Copy link
Collaborator

Part of the issue is that you're not creating multiple connections, you're using the same connection for both the active and archive collection. Please read the multiple connections docs - this works fine if you follow the instructions there.

Although, this points to a potential issue: Mongoose allows you to call connect() on a connection even when it is already connected. That can lead to tricky errors, and we should remove the ability to do that in Mongoose 6. You would need to explicitly close() the connection first before connecting to a different URI.

We'll work around this by closing the old connection in Mongoose 5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

No branches or pull requests

2 participants