alexbosworth / ln-service

Node.js interface to LND
MIT License
319 stars 60 forks source link

An `EventEmitter` can no longer be used after all listeners have been removed? #178

Closed andreashuber69 closed 1 year ago

andreashuber69 commented 1 year ago

Apparently, removing all listeners from an EventEmitter somehow cancels the emitter, such that subscribing again results in an error (see below for details). Is this expected or a bug?

The program...

import { subscribeToBlocks } from "lightning";
import { connectLnd } from "./lightning/connectLnd.js";
const emitter = subscribeToBlocks(await connectLnd());

while (true) {
    try {
        // eslint-disable-next-line no-await-in-loop
        console.log(await new Promise((resolve, reject) => {
            emitter.on("block", resolve);
            emitter.on("error", reject);
        }));
    }
    catch (error) {
        console.error(error);
    }
    finally {
        emitter.removeAllListeners();
    }
}

... produces the this output:

{
  height: 803584,
  id: '000000000000000000003d97a46dbbb4cca4b3e23c39c446df75cfe726163bb5'
}
[
  503,
  'UnexpectedErrInBlocksSubscription',
  {
    err: Error: 1 CANCELLED: Cancelled on client
        at callErrorFromStatus (/home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/call.js:31:19)
        at Object.onReceiveStatus (/home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/client.js:357:73)
        at Object.onReceiveStatus (/home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
        at /home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/resolving-call.js:99:78
        at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
    for call at
        at ServiceClientImpl.makeServerStreamRequest (/home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/client.js:340:32)
        at ServiceClientImpl.<anonymous> (/home/a/git/lightning-node-operator/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)
        at module.exports (/home/a/git/lightning-node-operator/node_modules/lightning/lnd_methods/onchain/subscribe_to_blocks.js:41:32)
        at file:///home/a/git/lightning-node-operator/dist/main.js:3:17
        at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
      code: 1,
      details: 'Cancelled on client',
      metadata: [Metadata]
    }
  }
]
alexbosworth commented 1 year ago

That's by design, if you remove all listeners the subscription is released and you should then resubscribe

andreashuber69 commented 1 year ago

That's by design, if you remove all listeners the subscription is released and you should then resubscribe

Thanks, would you consider merging a PR, which adds a section to README explaining this as well as the fact that the emitters returned by all subscribeTo... functions expose an "error" event?

alexbosworth commented 1 year ago

Sure

andreashuber69 commented 1 year ago

Here it is: https://github.com/alexbosworth/ln-service/pull/179