HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Creating cover traffic by calling random urls - Javascript loop to decrement float

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
randomcreatingtrafficjavascriptloopfloatdecrementcallingcoverurls

Problem

This is a for-loop which runs once for each step with i>1 and maybe for 0 <= i <= 1.

var i;
var prob_ = 3.5;
for ( i = prob_; i >= 0; i -= 1 ) {
    if ( i > 1 || withProbability(i) ) {
        loadHttp(randomUrl());
    }
}


with

function withProbability(chance) {
    return Math.random() < chance;
}


JsLint gave me a for-loop error. Is this code ok despite that warning, or should this for-loop be changed to some other looping construct?
Background

prob_ is a ratio between fake actions and real actions. The loop is triggered once for each real action. If prob_ is greater than 1, the fake action is done. If it is in between 0 and 1, it is considered a probability and thus maybe a fake action follows.

This is a case where it was not clear how to replace the for-loop with a forEach, as is often recommended. Maybe ES6 tail recursion could be used...
More context

function loadHttp(toLoad) {
    require("sdk/page-worker").Page({
        contentURL: toLoad
    });
}


The implementation of randomUrl() is rather lengthy and does not relate to the question. It determines a statistically probable length of a HTML (or embedded object like js, img, css, ...) site, then does a lookup for the next bigger URL in a hardcoded list. It is supposed that the randomness will confuse someone who watches for traffic patterns.
Full class coverTraffic.js

This is initialized via

const coverTraffic = require('./coverTraffic.js');
coverTraffic.setLoader(require('./load.js'));


with load.js containing similar to loadHttp as above. It is triggered via

function loads(URL) {
    if ( _.contains(activeHosts, URL.host) ) { // has already started
        coverTraffic.loadNext();
    } else {
        activeHosts.push(URL.host);
        coverTraffic.start();
    }
}
exports.loads = URL => loads(URL);


which is called whenever the browser loads a new URL.

```
"use strict";

exports.DOC = 'creates cover traffic, up to predetermined pa

Solution

The problem JSLint is pointing at is that you usually iterate with an index that is an integer. If you were to have an array, you couldn't use i to access the array elements, because if i is big enough, rounding issues may cause you to skip elements or see elements twice!

What I'd recommend is that you just use i as integer, and then once the for loop is done, check if there is an additional chance to roll for. That way, you don't have to worry about floating point rounding errors accumulating.

Another way you could do it is first roll, and then if you roll high enough, up i by 1. That way you only have one place where you run your code.

So like this:

var chance = i % 1;
if (chance !== 0 && withProbability(chance)){
    i = Math.ceil(i);
} else {
    i = Math.floor(i);
}
//for loop goes here

Code Snippets

var chance = i % 1;
if (chance !== 0 && withProbability(chance)){
    i = Math.ceil(i);
} else {
    i = Math.floor(i);
}
//for loop goes here

Context

StackExchange Code Review Q#119508, answer score: 3

Revisions (0)

No revisions yet.