-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Closed
Labels
Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.
Description
Memory usage through 1:33 minute
Is this a bug report?
Yes.
Have you read the Contributing Guidelines?
Yes.
Environment
Environment:
OS: macOS High Sierra 10.13.1
Node: 8.5.0
Yarn: 1.0.2
npm: 5.3.0
Watchman: 4.9.0
Xcode: Xcode 9.1 Build version 9B55
Android Studio: 3.0 AI-171.4408382
Packages: (wanted => installed)
react: 16.0.0-beta.5 => 16.0.0-beta.5
react-native: 0.49.1 => 0.49.1
Steps to Reproduce
- react-native init test
- Change content of app.js to the provided example
- Add provided "Speedtester.js" file in src/Speedtester.js
- run project, and notice the memory usage keep increasing.
Expected Behavior
I expected the memory usage to increase during the speedtest and then decrease again afterwards.
Actual Behavior
The memory usage increases during the test but never decreases.
Reproducible Demo
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Speedtester from './src/Speedtester';
export default class App extends Component {
constructor() {
super();
this.state = { rate: 0 };
}
componentDidMount() {
this.runTest();
}
runTest() {
const sptest = new Speedtester();
sptest.runDownloadTest(10000, (rate) => {
this.setState({ rate });
}, () => {
setTimeout(() => {
this.runTest()
}, 10000)
});
}
render() {
return (
<View style={{ flex: 1, justifyContent: 'center' }}>
<Text style={styles.rate}>
{this.state.rate}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
rate: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
Speedtester.js
/* eslint-disable */
import React, { Component } from 'react';
import { View, Text } from 'react-native';
class Speedtester {
constructor() {
if (!String.prototype.startsWith) {
String.prototype.startsWith = function (searchString, position) {
return this.substr(position || 0, searchString.length) === searchString;
};
}
}
runLatencyTest(onprogress, end) {
var target = "wss://speedtest.fullrate.dk/backend/ws";
Promise.resolve()
.then(function () {
return latencytest({
target: target,
}).then(function (samples) {
for (var i = 0; i < samples.length; i++) {
onprogress(samples[i])
}
});
}).then(end);
}
runDownloadTest(duration, onprogress, end) {
var target = "wss://speedtest.fullrate.dk/backend/ws";
Promise.resolve()
.then(function () {
return speedtest({
target: target,
session: session_download,
duration: duration || 10000,
finish: end,
progressinterval: 800,
onprogress: function (speed, elapsed, total, time) {
if (speed > 30) {
var rate = speed.toFixed(0);
} else {
var rate = speed.toFixed(1);
}
if (time) {
var eta = time;
} else {
var eta = 0;
}
onprogress(rate, eta);
}
});
});
}
runUploadTest(duration, onprogress, end) {
var target = "wss://speedtest.fullrate.dk/backend/ws";
const tmpWs = new WebSocket(target);
tmpWs.binaryType = 'blob';
tmpWs.onopen = function (event) {
send = true;
const size = (1 * 1024 * 1024);
tmpWs.send('DOWNLOAD ' + size);
tmpWs.onmessage = function (event) {
const uploadbuf = event.data;
tmpWs.close();
var rate = 0;
var eta = 0;
Promise.resolve()
.then(function () {
return speedtest({
target: target,
session: session_upload,
duration: 10000,
finish: end,
uploadbuf: uploadbuf,
onprogress: function (speed, elapsed, total, time) {
if (speed > 30) {
rate = speed.toFixed(0);
} else {
rate = speed.toFixed(1);
}
if (time) {
eta = time;
} else {
eta = 0;
}
onprogress(rate, eta);
}
});
});
}
}
}
stopTest() {
if(_cleanup) {
_cleanup();
}
}
}
/**
* SPEED TEST FUNCS
*/
function now() {
return (new Date).getTime();
}
function uint8tostr(data) {
return String.fromCharCode.apply(null, new Uint8Array(data));
}
// Returns a function that will cancel the session
function session(target, queuelen, onreceive, handler) {
var sendtimes = [];
var replies = 0;
var nextinc = 0;
var size = handler.minsize;
var mintime = 100;
var exit = false;
function fill_queue() {
if (exit) return;
while (sendtimes.length < queuelen) {
sendtimes.push(now());
ws.send(handler.req(size));
}
}
var ws = new WebSocket(target);
ws.binaryType = handler.resulttype;
ws.onopen = function () {
if (exit) return;
fill_queue();
}
ws.onclose = function () {
if (exit) return;
exit = true;
onreceive("closed");
}
ws.onerror = function (e) {
if (exit) return;
exit = true;
onreceive(e);
};
ws.onmessage = function (e) {
if (exit) return;
var v = handler.rep(e.data);
if (v === false) {
exit = true;
onreceive("Unexpected data returned");
return;
}
onreceive(undefined, v);
var td = now() - sendtimes.shift();
if (td < mintime && nextinc <= replies && size < handler.maxsize) {
size = size * 2;
nextinc = replies + queuelen;
if (size > handler.maxsize) size = handler.maxsize;
}
fill_queue();
replies++;
};
return function () {
exit = true;
return new Promise(function (resolve) {
ws.onclose = ws.onerror = function () {
resolve();
};
ws.close();
});
};
}
function session_download(target, queuelen, uploadbuf, onreceive) {
return session(target, queuelen, onreceive, {
resulttype: 'blob',
minsize: 10000,
maxsize: 1000000,
req: function req_download(size) {
return 'DOWNLOAD ' + size;
},
rep: function rep_download(data) {
var s = data.size || data.byteLength;
return s;
},
});
}
//var uploadbuf = new Blob([new Uint8Array(1 * 1024 * 1024)]);
function session_upload(target, queuelen, uploadbuf, onreceive) {
return session(target, queuelen, onreceive, {
resulttype: 'arraybuffer',
minsize: 10000,
maxsize: 1000000,
req: function req_upload(size) {
var s = uploadbuf.slice(size);
return s;
},
rep: function rep_upload(data) {
var str = uint8tostr(data);
if (!str.startsWith('OK ')) return false;
var s = parseInt(str.substr(3), 10);
return s;
},
});
}
var timeRemaining;
var elapsed;
var delta;
var _cleanup;
function speedtest(opts) {
var target = opts.target;
if (!target) return Promise.reject("No target URL");
var session = opts.session;
if (!session) return Promise.reject("No session");
var duration = opts.duration || 10000;
var progressinterval = opts.progress_interval || 400;
var queuelen = opts.queuelen || 10;
var concurrency = opts.concurrency || 5;
var total = 0;
var begintime = now();
var samples = [[0, 0]];
var smoothtime = opts.smoothtime || 3000;
var first;
timeRemaining = duration;
return new Promise(function (resolve, reject) {
var cancels = [];
for (var i = 0; i < concurrency; i++) {
cancels.push(session(target, queuelen, opts.uploadbuf, function (err, amount) {
if (err) {
cleanup();
}
total += amount;
}));
}
var interval = setInterval(function () {
elapsed = now() - begintime;
while (samples.length > 0 && samples[0][0] < (elapsed - smoothtime)) samples.shift();
samples.push([elapsed, total]);
var first = samples[0];
delta = samples.length <= 1 || elapsed === first[0] ? 0 : (total - first[1]) / (elapsed - first[0]);
timeRemaining = timeRemaining - progressinterval;
var speed = 8 * delta / 1000;
if (opts.onprogress) opts.onprogress(speed, elapsed, total, timeRemaining);
}, progressinterval);
var timeout = setTimeout(function () {
cleanup();
opts.finish();
}, duration);
if (opts.onprogress) opts.onprogress(0, 0, 0, 0);
function cleanup() {
if (opts.onprogress) opts.onprogress(8 * delta / 1000, elapsed, total, 0);
clearInterval(interval);
clearTimeout(timeout);
return Promise.all(cancels.map(function (c) { return c(); }));
}
_cleanup = cleanup;
});
}
function latencytest(opts) {
const probes = opts.probes || 20;
var target = opts.target;
if (!target) return Promise.reject("No target URL");
return new Promise(function (resolve, reject) {
const results = [];
const ws = new WebSocket(target);
ws.binaryType = 'arraybuffer';
function sendping() {
ws.send('PING ' + now());
}
ws.onopen = function () {
sendping();
};
ws.onclose = function () {
resolve(results);
};
ws.onerror = function () {
reject("An error occured"); // TODO?
};
ws.onmessage = function (e) {
var msg = uint8tostr(e.data);
// if (msg.indexOf('PONG ') !== -1) reject("Invalid response from server"); appearantly this breaks on android?
var ts = parseInt(msg.substr(5), 10);
var delta = now() - ts;
if (delta === 0) delta = 1;
results.push(delta);
if (results.length < probes) {
sendping();
} else {
ws.close();
}
};
});
}
export default Speedtester;
balsloev, FlyveHest, kesha-antonov, charmixer, wraix and 4 more
Metadata
Metadata
Assignees
Labels
Resolution: LockedThis issue was locked by the bot.This issue was locked by the bot.