import ProgressPromise from 'progress-promise';
import axios from 'axios';
import httpadapter from 'axios/lib/adapters/http';
import xhradapter from 'axios/lib/adapters/xhr';
let _instance;
/**
* Runner represents the process which will schedule and run operations of the processes
*/
export class Runner {
/**
* Initiates the runner singleton instance
* @param configurations
*/
static initiateRunner(configurations) {
if (!Runner.instance) {
this.config = configurations;
this.cache = {};
_instance = this;
}
}
/**
* Get the Runner instance
* @returns {Runner}
*/
get instance() {
return _instance;
}
/**
* Set the configuration
* @param configurations
*/
set config(configurations) {
this.config = configurations;
}
/**
* Get the configurations
* @returns {*}
*/
get config() {
return this.config;
}
/**
* This callback type is called `resolveCallback`.
*
* @callback resolveCallback
* @param {Object} responseResult
*/
/**
* This callback type is called `rejectCallback`.
*
* @callback rejectCallback
* @param {Error} error
*/
/**
* Fetches the data from the fetcher
* @param {Fetcher} fetcher
* @param {resolveCallback} resolve
* @param {rejectCallback} reject
* @private
*/
_fetch(fetcher, resolve, reject) {
if (!_instance) {
let error =
'Configration not set please configre function ' +
'analytics eg {baseUrl:"dhis_base_url", username:"username", ' +
'password:"password"}';
throw Error(error);
}
let hashed = fetcher.hash();
if (!_instance.cache[hashed]) {
_instance.cache[hashed] = {
finished: false,
resolutions: []
};
const config = {
url: _instance.config.baseUrl + fetcher.url,
method: 'get',
adapter: typeof process !== 'undefined' ? httpadapter : xhradapter
};
if (_instance.config.username && _instance.config.password) {
config.auth = {
username: _instance.config.username,
password: _instance.config.password
};
}
axios.request(config).then(
results => {
_instance.cache[hashed].data = results.data;
resolve(fetcher.performPostProcess(JSON.parse(JSON.stringify(_instance.cache[hashed].data))));
_instance.cache[hashed].resolutions.forEach(function (resolution) {
resolution(fetcher.performPostProcess(JSON.parse(JSON.stringify(_instance.cache[hashed].data))));
});
_instance.cache[hashed].finished = true;
},
err => {
reject(err);
}
);
} else {
if (!_instance.cache[hashed].finished) {
_instance.cache[hashed].resolutions.push(resolve);
} else {
resolve(fetcher.performPostProcess(JSON.parse(JSON.stringify(_instance.cache[hashed].data))));
}
}
}
/**
* Fetches data related to a fetcher
* @param {Fetcher} fetcher
* @returns {ProgressPromise}
*/
getResults(fetcher) {
if (fetcher._fetchers) {
// If is a multifetcher
return this.getAllResults(fetcher);
}
// let hashed = fetcher.hash();
// if (!_instance.cache[hashed]) {
// _instance.cache[hashed] = new ProgressPromise(
// (resolve, reject, progress) => {
// if (fetcher.hasDependencies()) {
// fetcher
// .getDependecyFetchResults()
// .then(() => {
// fetcher.performPreProcess();
// this._fetch(fetcher, resolve, reject);
// })
// .catch(err => {
// console.log('Errrrrrrrrrr:', err);
// reject();
// });
// } else {
// this._fetch(fetcher, resolve, reject);
// }
// }
// );
// }
return new ProgressPromise(
(resolve, reject, progress) => {
if (fetcher.hasDependencies()) {
fetcher
.getDependecyFetchResults()
.then(() => {
fetcher.performPreProcess();
this._fetch(fetcher, resolve, reject);
})
.catch(err => {
console.log('Errrrrrrrrrr:', err);
reject();
});
} else {
this._fetch(fetcher, resolve, reject);
}
}
);
}
/**
* Fetches data for multiple fetchers
* @param {MultiFetcher} multifetcher
* @returns {ProgressPromise}
*/
getAllResults(multifetcher) {
return new ProgressPromise((resolve, reject, progress) => {
const promises = multifetcher.fetchers.map(fetcher =>
new Runner().getResults(fetcher)
);
return ProgressPromise.all(promises)
.then(results => {
resolve(multifetcher.performPostProcess(results));
})
.catch(err => {
reject(err);
});
});
}
}