Skip to content

Commit

Permalink
Merge pull request #917 from bjoernricks/auto-reload-interval
Browse files Browse the repository at this point in the history
Auto reload interval
  • Loading branch information
swaterkamp authored Sep 6, 2018
2 parents 6bdde33 + 7e0c820 commit 0a4eafa
Show file tree
Hide file tree
Showing 36 changed files with 268 additions and 143 deletions.
1 change: 1 addition & 0 deletions gsa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ set (GSA_JS_SRC_FILES
${GSA_SRC_DIR}/src/web/authorized.js
${GSA_SRC_DIR}/src/web/utils/cert.js
${GSA_SRC_DIR}/src/web/utils/compose.js
${GSA_SRC_DIR}/src/web/utils/constants.js
${GSA_SRC_DIR}/src/web/utils/cpe.js
${GSA_SRC_DIR}/src/web/utils/globalcss.js
${GSA_SRC_DIR}/src/web/utils/os.js
Expand Down
3 changes: 0 additions & 3 deletions gsa/public/config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
const FIVE_SECONDS = 5;

config = {
loglevel: 'warn',
autorefresh: FIVE_SECONDS,
manualurl: 'http://docs.greenbone.net/GSM-Manual/gos-4/',
protocoldocurl: 'http://docs.greenbone.net/API/OMP/omp-7.0.html',
};
12 changes: 6 additions & 6 deletions gsa/src/gmp/__tests__/gmpsettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('GmpSettings tests', () => {
test('should init with passed options', () => {
const storage = createStorage();
const settings = new GmpSettings(storage, {
autorefresh: 10,
reloadinterval: 10,
locale: 'en',
manualurl: 'http://manual',
protocol: 'http',
Expand All @@ -48,7 +48,7 @@ describe('GmpSettings tests', () => {
username: 'foo',
});

expect(settings.autorefresh).toEqual(10);
expect(settings.reloadinterval).toEqual(10);
expect(settings.locale).toEqual('en');
expect(settings.manualurl).toEqual('http://manual');
expect(settings.protocol).toEqual('http');
Expand Down Expand Up @@ -81,7 +81,7 @@ describe('GmpSettings tests', () => {
protocol: 'http',
});

expect(settings.autorefresh).toBeUndefined();
expect(settings.reloadinterval).toEqual(15000);
expect(settings.locale).toEqual('en');
expect(settings.manualurl).toBeUndefined();
expect(settings.protocol).toEqual('http');
Expand All @@ -101,7 +101,7 @@ describe('GmpSettings tests', () => {

test('should ensure options override settings from storage', () => {
const storage = createStorage({
autorefresh: 20,
reloadinterval: 20,
locale: 'de',
manualurl: 'http://ipsum',
protocol: 'https',
Expand All @@ -114,7 +114,7 @@ describe('GmpSettings tests', () => {
});

const settings = new GmpSettings(storage, {
autorefresh: 10,
reloadinterval: 10,
locale: 'en',
manualurl: 'http://manual',
protocol: 'http',
Expand All @@ -126,7 +126,7 @@ describe('GmpSettings tests', () => {
username: 'foo',
});

expect(settings.autorefresh).toEqual(10);
expect(settings.reloadinterval).toEqual(10);
expect(settings.locale).toEqual('en');
expect(settings.manualurl).toEqual('http://manual');
expect(settings.protocol).toEqual('http');
Expand Down
8 changes: 4 additions & 4 deletions gsa/src/gmp/gmp.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class Gmp {

constructor(options = {}) {
const {
autorefresh,
reloadinterval,
protocol,
server,
storage,
Expand All @@ -96,7 +96,7 @@ class Gmp {
log.debug('Using gmp options', options);

this.settings = new GmpSettings(storage, {
autorefresh,
reloadinterval,
manualurl,
protocol,
protocoldocurl,
Expand Down Expand Up @@ -218,8 +218,8 @@ class Gmp {
return this;
}

get autorefresh() {
return this.settings.autorefresh;
get reloadInterval() {
return this.settings.reloadinterval;
}

addHttpErrorHandler(handler) {
Expand Down
6 changes: 4 additions & 2 deletions gsa/src/gmp/gmpsettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
*/
import {isDefined} from './utils/identity';

const DEFAULT_RELOAD_INTERVAL = 15 * 1000; // fifteen seconds

const set = (storage, name, value) => {
if (isDefined(value)) {
storage.setItem(name, value);
Expand All @@ -34,7 +36,7 @@ const set = (storage, name, value) => {
class GmpSettings {
constructor(storage = global.localStorage, options = {}) {
const {
autorefresh,
reloadinterval = DEFAULT_RELOAD_INTERVAL,
locale,
manualurl,
protocol = global.location.protocol,
Expand All @@ -47,7 +49,7 @@ class GmpSettings {
} = {...storage, ...options};
this.storage = storage;

this.autorefresh = autorefresh;
this.reloadinterval = reloadinterval;
this.locale = locale;
this.manualurl = manualurl;
this.protocol = protocol;
Expand Down
69 changes: 58 additions & 11 deletions gsa/src/web/entities/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ const exclude_props = [
'onDownload',
];

const LOAD_TIME_FACTOR = 1.2;

class EntitiesContainer extends React.Component {

constructor(...args) {
Expand Down Expand Up @@ -131,8 +133,11 @@ class EntitiesContainer extends React.Component {
};

componentDidMount() {
this.isRunning = true;
const {filter} = this.props.location.query;

this.startMeasurement();

if (isDefined(filter)) {
// use filter from url
this.load(Filter.fromString(filter));
Expand All @@ -144,6 +149,7 @@ class EntitiesContainer extends React.Component {
}

componentWillUnmount() {
this.isRunning = false;
this.clearTimer(); // remove possible running timer
}

Expand All @@ -170,23 +176,57 @@ class EntitiesContainer extends React.Component {
this.load(this.props.filter);
}

getRefreshInterval() {
const {gmp} = this.props;
return gmp.autorefresh * 1000;
startMeasurement() {
this.startTimeStamp = performance.now();
}

endMeasurement() {
if (!isDefined(this.startTimeStamp)) {
return 0;
}

const duration = performance.now() - this.startTimeStamp;
this.startTimeStamp = undefined;
return duration;
}

getReloadInterval() {
const {
defaultReloadInterval,
reloadInterval,
} = this.props;

return isDefined(reloadInterval) ? reloadInterval(this.props) :
defaultReloadInterval;
}

startTimer() {
const refresh = this.getRefreshInterval();
if (refresh > 0) {
this.timer = global.setTimeout(this.handleTimer, refresh);
if (!this.isRunning) {
return;
}

const loadTime = this.endMeasurement();

log.debug('Loading time was', loadTime, 'milliseconds');

let interval = this.getReloadInterval();

if (loadTime > interval) {
// ensure timer is longer then the loading procedure
interval = loadTime * LOAD_TIME_FACTOR;
}

if (interval > 0) {
this.timer = global.setTimeout(this.handleTimer, interval);
log.debug('Started reload timer with id', this.timer, 'and interval of',
refresh, 'milliseconds');
interval, 'milliseconds for', this.props.gmpname);
}
}

clearTimer() {
if (isDefined(this.timer)) {
log.debug('Clearing reload timer with id', this.timer);
log.debug('Clearing reload timer with id', this.timer, 'for',
this.props.gmpname);
global.clearTimeout(this.timer);
}
}
Expand All @@ -195,13 +235,18 @@ class EntitiesContainer extends React.Component {
log.debug('Timer', this.timer, 'finished. Reloading data.');

this.timer = undefined;
this.reload();

this.startMeasurement();

this.notifyTimer();
this.reload();
}

handleChanged() {
this.reload();
this.startMeasurement();

this.notifyChanged();
this.reload();
}

handleSelectionTypeChange(selectionType) {
Expand Down Expand Up @@ -273,8 +318,8 @@ class EntitiesContainer extends React.Component {
this.handleInteraction();

promise.then(deleted => {
this.reload();
log.debug('successfully deleted entities', deleted);
this.handleChanged();
}, this.handleError);
}

Expand Down Expand Up @@ -641,6 +686,7 @@ class EntitiesContainer extends React.Component {

EntitiesContainer.propTypes = {
children: PropTypes.func.isRequired,
defaultReloadInterval: PropTypes.number.isRequired,
entities: PropTypes.array,
entitiesCounts: PropTypes.counts,
extraLoadParams: PropTypes.object,
Expand All @@ -652,6 +698,7 @@ EntitiesContainer.propTypes = {
loadEntities: PropTypes.func.isRequired,
loadedFilter: PropTypes.filter,
notify: PropTypes.func.isRequired,
reloadInterval: PropTypes.func,
showError: PropTypes.func.isRequired,
showErrorMessage: PropTypes.func.isRequired,
showSuccessMessage: PropTypes.func.isRequired,
Expand Down
5 changes: 4 additions & 1 deletion gsa/src/web/entities/withEntitiesContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import EntitiesContainer from './container';
const withEntitiesContainer = (gmpname, {
entitiesSelector,
loadEntities,
reloadInterval,
}) => Component => {
let EntitiesContainerWrapper = props => (
<SubscriptionProvider>
Expand All @@ -50,6 +51,7 @@ const withEntitiesContainer = (gmpname, {
{...props}
notify={notify}
gmpname={gmpname}
reloadInterval={reloadInterval}
>
{pageProps => (
<Component
Expand All @@ -61,12 +63,13 @@ const withEntitiesContainer = (gmpname, {
</SubscriptionProvider>
);

const mapStateToProps = (state, props) => {
const mapStateToProps = (state, {gmp}) => {
const eSelector = entitiesSelector(state);
const pSelector = getPage(state);
const filter = pSelector.getFilter(gmpname);
const entities = eSelector.getEntities(filter);
return {
defaultReloadInterval: gmp.reloadInterval,
entities,
entitiesCounts: eSelector.getEntitiesCounts(filter),
filter,
Expand Down
40 changes: 31 additions & 9 deletions gsa/src/web/entity/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,18 @@ class EntityContainer extends React.Component {
}

componentDidMount() {
this.isRunning = true;

const {id} = this.props;
this.load(id);
}

componentWillUnmount() {
this.isRunning = false;

this.clearTimer();
}

componentDidUpdate() {
const {id} = this.props;
if (id !== this.state.id) {
Expand All @@ -58,8 +66,11 @@ class EntityContainer extends React.Component {
}

load(id) {
this.props.load(id);
this.clearTimer();

this.setState({id});

this.props.load(id).then(() => this.startTimer());
}

reload() {
Expand All @@ -71,18 +82,27 @@ class EntityContainer extends React.Component {
this.reload();
}

getRefreshInterval() {
const {gmp} = this.props;
return gmp.autorefresh * 1000;
getReloadInterval() {
const {
defaultReloadInterval,
reloadInterval,
} = this.props;

return isDefined(reloadInterval) ? reloadInterval(this.props) :
defaultReloadInterval;
}

startTimer(immediate = false) {
const refresh = immediate ? 0 : this.getRefreshInterval();
startTimer() {
if (!this.isRunning) {
return;
}

const interval = this.getReloadInterval();

if (refresh >= 0) {
this.timer = window.setTimeout(this.handleTimer, refresh);
if (interval > 0) {
this.timer = global.setTimeout(this.handleTimer, interval);
log.debug('Started reload timer with id', this.timer, 'and interval of',
refresh, 'milliseconds');
interval, 'milliseconds');
}
}

Expand Down Expand Up @@ -123,10 +143,12 @@ class EntityContainer extends React.Component {

EntityContainer.propTypes = {
children: PropTypes.func.isRequired,
defaultReloadInterval: PropTypes.number.isRequired,
entityType: PropTypes.string.isRequired,
gmp: PropTypes.gmp.isRequired,
id: PropTypes.id.isRequired,
load: PropTypes.func.isRequired,
reloadInterval: PropTypes.func,
showError: PropTypes.func.isRequired,
showSuccessMessage: PropTypes.func.isRequired,
onDownload: PropTypes.func.isRequired,
Expand Down
Loading

0 comments on commit 0a4eafa

Please sign in to comment.