Skip to content

sockets no longer emit removeListener events in v20.11.0 #59977

@baileympearson

Description

@baileympearson

Version

No response

Platform

macos, although I'd be surprised if this issue is platform-specific.

Subsystem

No response

What steps will reproduce the bug?

Here's a reproduction script:

const assert = require('assert');
const { once } = require('events');
const { Server, Socket } = require('net');

async function main() {
  const server = new Server();

  server.on('connection', conn => {
    conn.on('data', () => {
      // do nothing
    });
  });

  server.listen('8000');

  const socket = new Socket();
  await socket.connect({
    host: 'localhost',
    port: '8000'
  });

  const removedListeners = [];
  socket.on('removeListener', name => removedListeners.push(name));

  // write a large buffer to ensure that the socket buffers the data, forcing the drain event
  const buffer = Buffer.alloc(10 * (2 ** 10) ** 2);
  socket.write(buffer);

  const drainEvent = once(socket, 'drain');
  try {
    await drainEvent;
  } finally {
    assert.ok(removedListeners.includes('drain'));
  }
}

main().then(() => process.exit());

This passes on <Node 20.11.0, but fails on any newer version.

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior? Why is that the expected behavior?

I'd expect to see a removeListener event emitted for drain (and other events) on the socket, because the once helper resolves, which indicates that we have received a drain event.

What do you see instead?

No removeListener event is emitted.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions