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

MaxListenersExceededWarning in 4.X #6554

Closed
M0cK1nG-b1Rd opened this issue Oct 28, 2023 · 11 comments
Closed

MaxListenersExceededWarning in 4.X #6554

M0cK1nG-b1Rd opened this issue Oct 28, 2023 · 11 comments
Assignees
Labels
4.x 4.0 related Bug Addressing a bug

Comments

@M0cK1nG-b1Rd
Copy link

hello, I am using web3.js of 4.2.0 to listen both pending and confirmed transactions. I get the warning of (node:3862464) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit when my code runs for a while. My code looks like

    async function pendingSubscription() {
        const subscription = await web3.eth.subscribe('pendingTransactions');
        subscription.on('connect', async () => {
            console.log("Scanning mempool...");
        })
        // note that in version 4.x the way you get notified for `data` and `error` has changed
        subscription.on('data', async (txHash) => {
            hashQ.add(txHash)
            checkTransaction(txHash);
        });
        subscription.on('error', (err) => {
            console.log(err);
        });
    }

    async function confirmedSubscription() {
        const subscription = await web3.eth.subscribe('newBlockHeaders');
        subscription.on('connect', async () => {
            console.log("Meanwhile listening for new blocks...");
        })
        // note that in version 4.x the way you get notified for `data` and `error` has changed
        subscription.on('data', async (blockHeader) => {
            processBlock(blockHeader.number);
        });
        subscription.on('error', (err) => {
            console.log(err);
        });
    }

    confirmedSubscription();
    pendingSubscription();

and here is my code when initializing web3 project, I try to use setMaxListenerWarningThreshold as mentioned in #1494, but in vain. Can someone help?

let web3 = new Web3(process.env.websocket);
web3.eth.handleRevert = true;
// no use
web3.eth.setMaxListenerWarningThreshold(50);
// no use
web3.setMaxListenerWarningThreshold(50);
// no use
web3.maxListenersWarningThreshold = 100;
// no use
web3.eth.maxListenersWarningThreshold = 100;
@jdevcs jdevcs added 4.x 4.0 related Investigate labels Oct 30, 2023
@jdevcs
Copy link
Contributor

jdevcs commented Oct 30, 2023

seems issue in setting Warning Threshold. We will investigate and fix.

@Muhammad-Altabba
Copy link
Contributor

Hello @M0cK1nG-b1Rd,
Could you please provide more info about your environment? Are you using nodejs? What is your exact project setup? Could you please refer to a repo or better a link to a Cloud IDE like https://codesandbox.io/?
Thanks,

@Muhammad-Altabba Muhammad-Altabba added the Needs Clarification Requires additional input label Nov 2, 2023
@M0cK1nG-b1Rd
Copy link
Author

hey, I am currently using nodejs of version 18.17.1, and here are my other dependencies.

    "@ethereumjs/common": "^4.0.0",
    "@ethereumjs/tx": "^5.0.0",
    "@ethereumjs/util": "^9.0.0",
    "async": "^3.2.4",
    "axios": "^1.5.1",
    "bignumber.js": "^9.1.2",
    "bn.js": "^5.2.1",
    "cheerio": "^1.0.0-rc.12",
    "clear": "^0.1.0",
    "colors": "^1.4.0",
    "decimal.js": "^10.4.3",
    "dotenv": "^16.3.1",
    "ethers": "^6.8.0",
    "moralis": "^2.23.1",
    "node-cron": "^3.0.2",
    "pkg": "^5.8.1",
    "prompt-sync": "^4.2.0",
    "silly-datetime": "^0.1.2",
    "web3": "^4.2.0"

I think it's rather difficult to refer to a cloud ide because I am currently using web3js to interact with bsc mainnet via a self-build bsc node on my server. It's rather hard to reproduce the whole environment. Is there any alternatives?

@Muhammad-Altabba Muhammad-Altabba removed the Needs Clarification Requires additional input label Nov 5, 2023
@Muhammad-Altabba
Copy link
Contributor

Thanks @M0cK1nG-b1Rd,
We will try to reproduce.
However, I also need a confirmation from you whether you are using the EventEmitter class anywhere in you code? I mean beside using web3.js, do you use EventEmitter somewhere?
Thanks,

@M0cK1nG-b1Rd
Copy link
Author

M0cK1nG-b1Rd commented Nov 6, 2023

heyyy, seems I made a mistake. I use --trace-warnings to dig more about the warnings and it turns out it's somewhere else that triggers the warning. But it is still within web3.js.

(node:333935) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 message listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit
    at _addListener (node:events:588:17)
    at EventEmitter.addListener (node:events:606:10)
    at WebSocketProvider.on (/home/test/node_modules/web3-utils/lib/commonjs/socket_provider.js:123:28)
    at Web3SubscriptionManager.listenToProviderEvents (/home/test/node_modules/web3-core/lib/commonjs/web3_subscription_manager.js:59:46)
    at new Web3SubscriptionManager (/home/test/node_modules/web3-core/lib/commonjs/web3_subscription_manager.js:47:14)
    at new Web3Context (/home/test/node_modules/web3-core/lib/commonjs/web3_context.js:42:41)
    at new Contract (/home/test/node_modules/web3-eth-contract/lib/commonjs/contract.js:82:9)
    at new ContractBuilder (/home/test/node_modules/web3/lib/commonjs/web3.js:103:21)
    at checkSingleToken (/home/test/pancakeWork.js:4428:33)

and my checkSingleToken has nothing special, just

const checkSingleToken = async (newTokenInfo, tokenAddress) => {
    if (newTokenInfo.safe == 6) {
        try {
            const owner = await new Contract(standardTokenAbi, tokenAddress, web3).methods.owner().call();
            newTokenInfo.owner = owner.toLowerCase();
        } catch (error) {
        }
    }
    worker.postMessage({ "action": "checkSingleTokenIsSafe", "data": newTokenInfo });
};

the trace indicates that the warning comes from const owner = await new Contract(standardTokenAbi, tokenAddress, web3).methods.owner().call(); Also the code to set threshold like web3.setMaxListenerWarningThreshold(50); didn't help.
I also try to upgrade node version to 20.9.0 and it didn't works.

BTW, This code is originally used in web3.js of version 1.X, I do the upgrade and not sure if I handle this correctly, from

const owner = await new web3.eth.Contract(standardTokenAbi, tokenAddress).methods.owner().call();

to

const owner = await new Contract(standardTokenAbi, tokenAddress, web3).methods.owner().call();

For this, I recheck my code and I am sure I am not using EventEmitter somewhere else.

Thanks @M0cK1nG-b1Rd, We will try to reproduce. However, I also need a confirmation from you whether you are using the EventEmitter class anywhere in you code? I mean beside using web3.js, do you use EventEmitter somewhere? Thanks,

@Muhammad-Altabba
Copy link
Contributor

Thanks @M0cK1nG-b1Rd,
Could you please also share the full code so we can reproduce? You may share a github repository or better to share on some Cloud IDE like https://codesandbox.io/, for example.

@M0cK1nG-b1Rd
Copy link
Author

Thanks @M0cK1nG-b1Rd, Could you please also share the full code so we can reproduce? You may share a github repository or better to share on some Cloud IDE like https://codesandbox.io/, for example.

heyy, I create a minimun test case to stablely reproduce the problem in https://github.com/M0cK1nG-b1Rd/web3js_reproduce, might need a bsc node to run the script

@Muhammad-Altabba
Copy link
Contributor

Thanks @M0cK1nG-b1Rd
I am facing issues when trying to run BSC inside a docker: bnb-chain/bsc-docker#15
Do you run the node natively or inside a docker container? What guide do you recommend to follow to run the node using docker?

@M0cK1nG-b1Rd
Copy link
Author

M0cK1nG-b1Rd commented Jan 8, 2024

Thanks @M0cK1nG-b1Rd I am facing issues when trying to run BSC inside a docker: bnb-chain/bsc-docker#15 Do you run the node natively or inside a docker container? What guide do you recommend to follow to run the node using docker?

I run the node natively and I am not so familiar with bsc inside docker. Building a node yourself occupies so many server resources so I actually recommend using some third party node provider, as long as it supports wss. I tried quicknode and it can also reproduce this issue. Setup a bsc node in quicknode dashboard and choose free plan will be just ok.

@mconnelly8 mconnelly8 added the Bug Addressing a bug label Jan 8, 2024
@Muhammad-Altabba Muhammad-Altabba self-assigned this Feb 16, 2024
@Muhammad-Altabba
Copy link
Contributor

Hi @M0cK1nG-b1Rd ,
I am happy to tell you that this issue has been resolved in the later versions of web3.js. So, you just need to update your web3.js dependency to the latest.

However, if you updated to the latest (4.5.0) and you are still facing this issue. Feel free to reopen it. And if you faced a different issue, you can open a new issue for that.

And a note on the side, you do not need to instantiate new Contract instance everytime you are calling a contract method.
so instead of having:

const checkSingleToken = async (newTokenInfo, tokenAddress) => {
    if (newTokenInfo.safe == 6) {
        try {
            const owner = await new Contract(standardTokenAbi, tokenAddress, web3).methods.owner().call();
            newTokenInfo.owner = owner.toLowerCase();
        } catch (error) {
        }
    }
    worker.postMessage({ "action": "checkSingleTokenIsSafe", "data": newTokenInfo });
};

You can have:

const myContract = new Contract(standardTokenAbi, tokenAddress, web3);
const checkSingleToken = async (newTokenInfo, tokenAddress) => {
    if (newTokenInfo.safe == 6) {
        try {
            const owner = await myContract.methods.owner().call();
            newTokenInfo.owner = owner.toLowerCase();
        } catch (error) {
        }
    }
    worker.postMessage({ "action": "checkSingleTokenIsSafe", "data": newTokenInfo });
};

@baixiang0101
Copy link

Hi @M0cK1nG-b1Rd , 你好, I am happy to tell you that this issue has been resolved in the later versions of web3.js. So, you just need to update your web3.js dependency to the latest.我很高兴地告诉您,这个问题在 web3.js 的更高版本中已经得到解决。因此,您只需将 web3.js 依赖项更新到最新即可。

However, if you updated to the latest (4.5.0) and you are still facing this issue. Feel free to reopen it. And if you faced a different issue, you can open a new issue for that.但是,如果您更新到最新版本(4.5.0)并且仍然面临此问题。请随意重新打开它。如果您遇到不同的问题,您可以为此打开一个新问题。

And a note on the side, you do not need to instantiate new Contract instance everytime you are calling a contract method.另外需要注意的是,您不需要每次调用合约方法时都实例化新的 Contract 实例。 so instead of having:所以不要有:

const checkSingleToken = async (newTokenInfo, tokenAddress) => {
    if (newTokenInfo.safe == 6) {
        try {
            const owner = await new Contract(standardTokenAbi, tokenAddress, web3).methods.owner().call();
            newTokenInfo.owner = owner.toLowerCase();
        } catch (error) {
        }
    }
    worker.postMessage({ "action": "checkSingleTokenIsSafe", "data": newTokenInfo });
};

You can have: 你可以有:

const myContract = new Contract(standardTokenAbi, tokenAddress, web3);
const checkSingleToken = async (newTokenInfo, tokenAddress) => {
    if (newTokenInfo.safe == 6) {
        try {
            const owner = await myContract.methods.owner().call();
            newTokenInfo.owner = owner.toLowerCase();
        } catch (error) {
        }
    }
    worker.postMessage({ "action": "checkSingleTokenIsSafe", "data": newTokenInfo });
};

My code is written like this, using web3js version 4.5.0, and I still receive this warning: (node:1) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added to [ClientHttp2Session]. Use emitter.setMaxListeners() to increase the limit (Use node --trace-warnings ... to show where the warning was created).

this.web3 = new Web3(new Web3.providers.WebsocketProvider(providerUrl));
        this.contracts = contractConfig.map((config) => {
            return new this.web3.eth.Contract(config[1].abi, config[0]);
        });
this.contracts.forEach((contract) => {
            console.log(`[${new Date().toLocaleString()}] EventListener listening contractAddress ${contract.options.address} start...`);
            contract.events.allEvents(
                {fromBlock: process.env.FROM_BLOCK}
            )
                .on('data', (event) => {
                    // ...
                })
        });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4.x 4.0 related Bug Addressing a bug
Projects
None yet
Development

No branches or pull requests

5 participants