4

I'm working with Nodejs application, and using a multi-node setup on different servers.

If I have single node end point like http://localhost:8545 I can use Web3 providers as below

var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));

However, I'm not sure how to setup multiple nodes into it. So the first node becomes unhealthy, the system uses the second node and so on.

I have tried with multi-http-provider but it seems not working with web3 v1.2.0

but it seems not working: having an error of uncaughtException : RangeError: Maximum call stack size exceeded

1 Answer 1

1

The following script might help you to achieve the multi-providers case (it is written in Node.js using TypeScript and is quite lightweight):

import Web3 from 'web3';
require('dotenv').config();
const infuraKey = process.env.INFURA_KEY;

// We assign a default web3 provider
let web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:7545'));

// List of our web3 providers
const providers = [
   new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:7545')),
   new Web3(new 
Web3.providers.HttpProvider(`https://ropsten.infura.io/v3/${infuraKey}`)),
];

// Selects the first web3 provider available from our list
const providerSelector = async () => {
   let selectedProvider = null;
   for (let i = 0; i < providers.length; i++) {
       await providers[i].eth.getBlockNumber()
           .then(() => { selectedProvider = providers[i] })
           .catch(() => { console.log(`Provider ${i} not available`) });
       if (selectedProvider) {
           web3 = selectedProvider;
           return true;
       };
   };
   return false;
};

const main = async () => {
   // Example (here we can put any query, transaction, etc)
   web3.eth.getBlockNumber()
      .then(() => { 
         // Do our stuff
      })
      .catch(async (err) => {
         // If current provider is not available, try another one from the list
         const res = JSON.stringify(err, Object.getOwnPropertyNames(err));
         if (res.includes('Invalid JSON RPC response'))
            (await providerSelector()) ? main() : console.log('No providers available');
      });
};

main();

So we have basically providers, which is our list of web3 providers to that we will use depending on their availability.

Whenever we launch a transaction or do any interaction with web3, we need to catch the error exception and in case it is an Invalid JSON RPC response, then we will try finding a new provider and re-try the same function recursively.

In case that no provider is available, the function will just finish because the providerSelector function will return false.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.