Skip to content

Commit

Permalink
sandeep/fix: dbot-slowness issue v2 (#7345)
Browse files Browse the repository at this point in the history
* fix: multiplier is not working fine with the dbot slowness fix

* fix: please log in issue caused due to performance optimization

* Revert "Revert V20230106_0 (#7334)"

This reverts commit 69825d3.

* fix: multiplier contract purchase

* fix: removed multiplier check and new ws creation

* chore: clear timeout resolvers on bot close

Co-authored-by: balakrishna-binary <bala.krishna@regentmarkets.com>
Co-authored-by: Prince <prince@deriv.com>
  • Loading branch information
3 people authored and vinu-deriv committed Jan 19, 2023
1 parent 415b5f8 commit cc8aee7
Show file tree
Hide file tree
Showing 18 changed files with 270 additions and 73 deletions.
2 changes: 2 additions & 0 deletions packages/bot-skeleton/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
"immutable": "^3.8.2",
"localforage": "^1.9.0",
"lz-string": "^1.4.4",
"mobx": "^6.6.1",
"mobx-react": "^7.5.1",
"redux": "^4.0.1",
"redux-thunk": "^2.2.0",
"scratch-blocks": "0.1.0-prerelease.20200917235131",
Expand Down
8 changes: 8 additions & 0 deletions packages/bot-skeleton/src/scratch/dbot-store.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { reaction } from 'mobx';
import { api_base } from '../services/api/api-base';

class DBotStoreInterface {
// TODO here we are suppose to define an interface and implement fields of DBotStore.
handleFileChange = () => {
Expand Down Expand Up @@ -27,6 +30,11 @@ class DBotStore extends DBotStoreInterface {
this.handleFileChange = store.handleFileChange;
this.startLoading = store.startLoading;
this.endLoading = store.endLoading;

reaction(
() => this.client.loginid,
() => api_base.createNewInstance(this.client.loginid)
);
}

static setInstance(store) {
Expand Down
10 changes: 8 additions & 2 deletions packages/bot-skeleton/src/scratch/dbot.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { observer as globalObserver } from '../utils/observer';
import ApiHelpers from '../services/api/api-helpers';
import Interpreter from '../services/tradeEngine/utils/interpreter';
import { setColors } from './hooks/colours';
import { api_base } from '../services/api/api-base';

class DBot {
constructor() {
Expand Down Expand Up @@ -97,7 +98,7 @@ class DBot {
window.dispatchEvent(new Event('resize'));
window.addEventListener('dragover', DBot.handleDragOver);
window.addEventListener('drop', e => DBot.handleDropOver(e, handleFileChange));

api_base.init();
// disable overflow
el_scratch_div.parentNode.style.overflow = 'hidden';
resolve();
Expand Down Expand Up @@ -134,7 +135,7 @@ class DBot {
}

this.interpreter = Interpreter();

api_base.setIsRunning(true);
this.interpreter.run(code).catch(error => {
globalObserver.emit('Error', error);
this.stopBot();
Expand Down Expand Up @@ -226,6 +227,7 @@ class DBot {
* that trade will be completed first to reflect correct contract status in UI.
*/
stopBot() {
api_base.setIsRunning(false);
if (this.interpreter) {
this.interpreter.stop();
}
Expand All @@ -241,6 +243,10 @@ class DBot {
}
}

terminateConnection = () => {
api_base.terminate();
};

/**
* Unselects any selected block before running the bot.
*/
Expand Down
132 changes: 132 additions & 0 deletions packages/bot-skeleton/src/services/api/api-base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { observer as globalObserver } from '../../utils/observer';
import { doUntilDone } from '../tradeEngine/utils/helpers';
import { generateDerivApiInstance, getLoginId, getToken } from './appId';

class APIBase {
api;
token;
account_id;
pip_sizes = {};
account_info = {};
is_running = false;
subscriptions = [];
time_interval = null;
has_activeSymbols = false;

init(force_update = false) {
if (getLoginId()) {
this.toggleRunButton(true);
if (force_update) this.terminate();
this.api = generateDerivApiInstance();
this.initEventListeners();
this.authorizeAndSubscribe();
if (this.time_interval) clearInterval(this.time_interval);
this.time_interval = null;
this.getTime();
}
}

terminate() {
// eslint-disable-next-line no-console
console.log('connection terminated');
if (this.api) this.api.disconnect();
}

initEventListeners() {
if (window) {
window.addEventListener('online', this.reconnectIfNotConnected);
window.addEventListener('focus', this.reconnectIfNotConnected);
}
}

createNewInstance(account_id) {
if (this.account_id !== account_id) {
this.init(true);
}
}

reconnectIfNotConnected = () => {
// eslint-disable-next-line no-console
console.log('connection state: ', this.api.connection.readyState);
if (this.api.connection.readyState !== 1) {
// eslint-disable-next-line no-console
console.log('Info: Connection to the server was closed, trying to reconnect.');
this.init();
}
};

authorizeAndSubscribe() {
const { token, account_id } = getToken();
if (token) {
this.token = token;
this.account_id = account_id;
this.api
.authorize(this.token)
.then(({ authorize }) => {
if (this.has_activeSymbols) {
this.toggleRunButton(false);
} else {
this.getActiveSymbols();
}
this.subscribe();
this.account_info = authorize;
})
.catch(e => {
globalObserver.emit('Error', e);
});
}
}

subscribe() {
doUntilDone(() => this.api.send({ balance: 1, subscribe: 1 }));
doUntilDone(() => this.api.send({ transaction: 1, subscribe: 1 }));
}

getActiveSymbols = async () => {
doUntilDone(() => this.api.send({ active_symbols: 'brief' })).then(({ active_symbols = [] }) => {
const pip_sizes = {};
if (active_symbols.length) this.has_activeSymbols = true;
active_symbols.forEach(({ symbol, pip }) => {
pip_sizes[symbol] = +(+pip).toExponential().substring(3);
});
this.pip_sizes = pip_sizes;
this.toggleRunButton(false);
});
};

toggleRunButton = toggle => {
const run_button = document.querySelector('#db-animation__run-button');
if (!run_button) return;
run_button.disabled = toggle;
};

setIsRunning(toggle = false) {
this.is_running = toggle;
}

pushSubscription(subscription) {
this.subscriptions.push(subscription);
}

clearSubscriptions() {
this.subscriptions.forEach(s => s.unsubscribe());
this.subscriptions = [];

// Resetting timeout resolvers
const global_timeouts = globalObserver.getState('global_timeouts') ?? [];

global_timeouts.forEach((_, i) => {
clearTimeout(i);
});
}

getTime() {
if (!this.time_interval) {
this.time_interval = setInterval(() => {
this.api.send({ time: 1 });
}, 30000);
}
}
}

export const api_base = new APIBase();
16 changes: 16 additions & 0 deletions packages/bot-skeleton/src/services/api/appId.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ export const generateDerivApiInstance = () => {
});
return deriv_api;
};

export const getLoginId = () => {
const login_id = localStorage.getItem('active_loginid');
if (login_id && login_id !== 'null') return login_id;
return null;
};

export const getToken = () => {
const active_loginid = getLoginId();
const client_accounts = JSON.parse(localStorage.getItem('client.accounts')) || undefined;
const active_account = (client_accounts && client_accounts[active_loginid]) || {};
return {
token: active_account?.token || undefined,
account_id: active_loginid || undefined,
};
};
49 changes: 31 additions & 18 deletions packages/bot-skeleton/src/services/api/ticks_service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Map } from 'immutable';
import { historyToTicks, getLast } from 'binary-utils';
import { doUntilDone, getUUID } from '../tradeEngine/utils/helpers';
import { observer as globalObserver } from '../../utils/observer';
import { api_base } from './api-base';

const parseTick = tick => ({
epoch: +tick.epoch,
Expand Down Expand Up @@ -39,8 +40,7 @@ const updateCandles = (candles, ohlc) => {
const getType = isCandle => (isCandle ? 'candles' : 'ticks');

export default class TicksService {
constructor(api) {
this.api = api;
constructor() {
this.ticks = new Map();
this.candles = new Map();
this.tickListeners = new Map();
Expand All @@ -60,23 +60,13 @@ export default class TicksService {

if (!this.active_symbols_promise) {
this.active_symbols_promise = new Promise(resolve => {
this.getActiveSymbols().then(active_symbols => {
this.pipSizes = active_symbols
.reduce((s, i) => s.set(i.symbol, +(+i.pip).toExponential().substring(3)), new Map())
.toObject();
resolve(this.pipSizes);
});
this.pipSizes = api_base.pip_sizes;
resolve(this.pipSizes);
});
}
return this.active_symbols_promise;
}

getActiveSymbols = async () => {
await this.api.expectResponse('authorize');
const active_symbols = await this.api.send({ active_symbols: 'brief' });
return active_symbols.active_symbols;
};

request(options) {
const { symbol, granularity } = options;

Expand All @@ -89,7 +79,6 @@ export default class TicksService {
if (style === 'candles' && this.candles.hasIn([symbol, Number(granularity)])) {
return Promise.resolve(this.candles.getIn([symbol, Number(granularity)]));
}

return this.requestStream({ ...options, style });
}

Expand Down Expand Up @@ -163,7 +152,7 @@ export default class TicksService {
...(tickSubscription || []),
];

Promise.all(subscription.map(id => doUntilDone(() => this.api.forget(id))));
Promise.all(subscription.map(id => doUntilDone(() => api_base.api.forget(id))));

this.subscriptions = new Map();
}
Expand Down Expand Up @@ -195,7 +184,7 @@ export default class TicksService {
}

observe() {
this.api.onMessage().subscribe(({ data }) => {
const subscription = api_base.api.onMessage().subscribe(({ data }) => {
if (data.msg_type === 'tick') {
const { tick } = data;
const { symbol, id } = tick;
Expand All @@ -218,6 +207,7 @@ export default class TicksService {
}
}
});
api_base.pushSubscription(subscription);
}

requestStream(options) {
Expand Down Expand Up @@ -260,7 +250,7 @@ export default class TicksService {
style,
};
return new Promise((resolve, reject) => {
doUntilDone(() => this.api.send(request_object))
doUntilDone(() => api_base.api.send(request_object), [], api_base)
.then(r => {
if (style === 'ticks') {
const ticks = historyToTicks(r.history);
Expand All @@ -278,4 +268,27 @@ export default class TicksService {
.catch(reject);
});
}

forget = subscription_id => {
if (subscription_id) {
api_base.api.forget(subscription_id);
}
};

unsubscribeFromTicksService() {
if (this.ticks_history_promise) {
const { stringified_options } = this.ticks_history_promise;
const { symbol = '' } = JSON.parse(stringified_options);
if (symbol) {
this.forget(this.subscriptions.getIn(['tick', symbol]));
}
}
if (this.candles_promise) {
const { stringified_options } = this.candles_promise;
const { symbol = '' } = JSON.parse(stringified_options);
if (symbol) {
this.forget(this.subscriptions.getIn(['candle', symbol]));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { getFormattedText } from '@deriv/shared';
import { info } from '../utils/broadcast';
import DBotStore from '../../../scratch/dbot-store';
import { api_base } from '../../api/api-base';

let balance_string = '';

export default Engine =>
class Balance extends Engine {
observeBalance() {
this.api.onMessage().subscribe(({ data }) => {
const subscription = api_base.api.onMessage().subscribe(({ data }) => {
if (data.msg_type === 'balance') {
const {
balance: { balance: b, currency },
Expand All @@ -18,6 +19,7 @@ export default Engine =>
info({ accountID: this.accountInfo.loginid, balance: balance_string });
}
});
api_base.pushSubscription(subscription);
}

// eslint-disable-next-line class-methods-use-this
Expand Down
Loading

0 comments on commit cc8aee7

Please sign in to comment.