skip to Main Content

I’m working on something in an older version of Node (8.x), and I wrote a function that counts values from a bunch of hashes in redis.

The problem is, the code always uses the default value of 0, because the function seems to run after its being used in the lines below it. I can see in my logs that the value returned from the function is not 0.

How can I ensure the function runs before it moves on and is used in the redis commands below it?

Thanks, sorry if this is a rookie qestion:

You can see below i’m defining blockEffort = 0. I then call the function below to get the real values. but by the time blockEffort is used in "redisCommands.push([‘sadd’, coin + ‘:blocksExplorer’, [dateNow, shareData.height, shareData.blockHash, shareData.worker, blockEffort].join(‘:’)]);" it’s still zero.

if (isValidBlock) {
            var blockEffort = parseFloat(0);
            this.getCurrentRoundShares(function (roundShares) {
                    logger.debug("calling GetCurrentRoundShares");
                    blockEffort = [roundShares / shareData.blockDiff];
                    logger.debug(`{"message": "Calculating Block Effort", "totalRoundShares": "${roundShares}", "blockEffort": "${blockEffort}"}`);
                });
            redisCommands.push(['rename', coin + ':shares:roundCurrent', coin + ':shares:round' + shareData.height]);
            redisCommands.push(['rename', coin + ':shares:timesCurrent', coin + ':shares:times' + shareData.height]);
            redisCommands.push(['sadd', coin + ':blocksPending', [shareData.blockHash, shareData.txHash, shareData.height].join(':')]);
            redisCommands.push(['sadd', coin + ':blocksExplorer', [dateNow, shareData.height, shareData.blockHash, shareData.worker, blockEffort].join(':')]);
            redisCommands.push(['zadd', coin + ':lastBlock', dateNow / 1000 | 0, [shareData.blockHash, shareData.txHash, shareData.worker, shareData.height, dateNow].join(':')]);
            redisCommands.push(['zadd', coin + ':lastBlockTime', dateNow / 1000 | 0, [dateNow].join(':')]);
            redisCommands.push(['hincrby', coin + ':stats', 'validBlocks', 1]);
            redisCommands.push(['hincrby', coin + ':blocksFound', shareData.worker, 1]);
}



this.getCurrentRoundShares = function(cback) {
        
        connection.hgetall('ravencoin:shares:roundCurrent', function(error,result) {
            if (error) {
                logger.error(`{"message": "Error getCurrentRoundShares", "data": "${error}"}`);
                cback(error);
                return;
            } else {
                logger.debug(`{"message": "Calculating all shares in current round"}`);
                logger.debug(result.toString());

                var _shareTotal = parseFloat(0);
                for (var worker in result) {
                    logger.debug(`{"message": "Shares for each Worker", "worker": "${worker}", "shares": "${parseFloat(result[worker])}"} }`);
                    _shareTotal += parseFloat(result[worker]);
                }
                logger.debug("Total Shares: " + _shareTotal );
                cback(_shareTotal);
            }
        });         
        },
        function(err) {
              if (err) {
                logger.error(`{"message": "Error getCurrentRoundShares", "data": "${err}"}`);
                cback(0);
                return;
            }
    };

The full file is here: https://github.com/devdevdevdev1/rvnpool/blob/main/shareProcessor.js

2

Answers


  1. You could make the this.getCurrentRoundShares function return a Promise.

    this.getCurrentRoundShares = function(cback) {
        return new Promise((resolve, reject) => {
            // do your stuf..
            
            let processHasFinishedSuccessfully = true;
            // if your stuff failed
            if (processHasFinishedSuccessfully){
               resolve();
            }
            else {
               reject(Error('Failed'));
            }
        };
    

    Then, in your this.handleShare function, you await for the response

    this.handleShare = async function(isValidShare, isValidBlock, shareData) {
        // your stuff ...
    
                await this.getCurrentRoundShares(function (roundShares) {
                        logger.debug("calling GetCurrentRoundShares");
                        blockEffort = parseFloat([roundShares / shareData.blockDiff]);
                        logger.debug(`{"message": "Calculating Block Effort", "totalRoundShares": "${roundShares}", "blockEffort": "${blockEffort}"}`);
                    });
    
        // your stuff...
        };
    

    This should ensure that the code execution does not proceed further until you get a response from the getCurrentRoundShares () function.

    Login or Signup to reply.
  2. If you’re using this redis module, then it already has promise support built-in and you can use that directly. You don’t show the calling code, but if you make the calling function async, you can do this:

    async function someFunction() {
    
        // ... other code here
    
        if (isValidBlock) {
            try {
                var blockEffort = parseFloat(0);
                let roundShares = await this.getCurrentRoundShares();
                logger.debug("calling GetCurrentRoundShares");
                blockEffort = [roundShares / shareData.blockDiff];
                logger.debug(`{"message": "Calculating Block Effort", "totalRoundShares": "${roundShares}", "blockEffort": "${blockEffort}"}`);
                redisCommands.push(['rename', coin + ':shares:roundCurrent', coin + ':shares:round' + shareData.height]);
                redisCommands.push(['rename', coin + ':shares:timesCurrent', coin + ':shares:times' + shareData.height]);
                redisCommands.push(['sadd', coin + ':blocksPending', [shareData.blockHash, shareData.txHash, shareData.height].join(':')]);
                redisCommands.push(['sadd', coin + ':blocksExplorer', [dateNow, shareData.height, shareData.blockHash, shareData.worker, blockEffort].join(':')]);
                redisCommands.push(['zadd', coin + ':lastBlock', dateNow / 1000 | 0, [shareData.blockHash, shareData.txHash, shareData.worker, shareData.height, dateNow].join(':')]);
                redisCommands.push(['zadd', coin + ':lastBlockTime', dateNow / 1000 | 0, [dateNow].join(':')]);
                redisCommands.push(['hincrby', coin + ':stats', 'validBlocks', 1]);
                redisCommands.push(['hincrby', coin + ':blocksFound', shareData.worker, 1]);
            } catch(e) {
                logger.debug(e);
                // handle error in this.getCurrentRoundShares() here
            }
        }
    }
    
    this.getCurrentRoundShares = async function() {
        let result = await connection.hGetAll('ravencoin:shares:roundCurrent');
        logger.debug(`{"message": "Calculating all shares in current round"}`);
        logger.debug(result.toString());
    
        let _shareTotal = parseFloat(0);
        for (var worker in result) {
            logger.debug(
                `{"message": "Shares for each Worker", "worker": "${worker}", "shares": "${parseFloat(result[worker])}"} }`
                );
            _shareTotal += parseFloat(result[worker]);
        }
        logger.debug("Total Shares: " + _shareTotal);
        return _shareTotal;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search