Skip to content

Commit

Permalink
chore: add polling for funds endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
kleyow committed Nov 11, 2021
1 parent 327815d commit f9c6901
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,6 @@ test(
dismissConfirmationModal: false,
runAssertion: false,
});
await t.expect(FinancialPositionsPage.balanceInsufficientError).ok();
await t.expect(FinancialPositionsPage.balanceInsufficientError.exists).ok();
},
);
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@svgr/webpack": "^5.5.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@types/async-retry": "^1.4.3",
"@types/classnames": "^2.2.10",
"@types/history": "^4.7.7",
"@types/html-webpack-plugin": "^3.2.3",
Expand All @@ -52,6 +53,7 @@
"@typescript-eslint/eslint-plugin": "4.9.0",
"@typescript-eslint/parser": "4.9.0",
"assert": "^2.0.0",
"async-retry": "^1.3.3",
"axios": "^0.21.2",
"babel-jest": "^27.0.6",
"babel-loader": "^8.1.0",
Expand Down
47 changes: 39 additions & 8 deletions src/App/FinancialPositions/sagas.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { strict as assert } from 'assert';
import { PayloadAction } from '@reduxjs/toolkit';
import { all, call, put, select, takeLatest, takeEvery } from 'redux-saga/effects';
import api from 'utils/api';
import api, { centralLedgerURL } from 'utils/api';
import { v4 as uuid } from 'uuid';
import retry from 'async-retry';
import axios from 'axios';
import { getDfsps } from '../DFSPs/selectors';
import { DFSP } from '../DFSPs/types';
import { Currency } from '../types';
Expand Down Expand Up @@ -31,6 +33,37 @@ import {
getSelectedFinancialPositionUpdateAction,
} from './selectors';

// Adding and withdrawing funds in the central ledger are not truly synchronous.
// So we poll the account endpoint a bit until there is a change before reloading
// the UI.
async function pollAccountFundsUpdate(oldAccountFunds: string, dfspName: string) {
return retry(
async (bail) => {
const accounts = await axios.get(`${centralLedgerURL}/participants/${dfspName}/accounts`);
if (accounts.status !== 200) {
bail(new Error('Unable to fetch DFSP data'));
return;
}

const account = accounts.data.filter(
(acc: { ledgerAccountType: string }) => acc.ledgerAccountType === 'SETTLEMENT',
)[0];

if (account.value !== oldAccountFunds) {
// eslint-disable-next-line consistent-return
return true;
}
},
{
retries: 5,
},
);
}

function* checkAccountFundUpdate(oldAccountFunds: string, dfspName: string) {
yield call(pollAccountFundsUpdate, oldAccountFunds, dfspName);
}

function* fetchDFSPPositions(dfsp: DFSP) {
// @ts-ignore
const accounts = yield call(api.participantAccounts.read, {
Expand All @@ -42,17 +75,16 @@ function* fetchDFSPPositions(dfsp: DFSP) {
const limits = yield call(api.participantLimits.read, { participantName: dfsp.name });
assert.equal(limits.status, 200, `Failed to retrieve limits for ${dfsp.name}`);

const activeAccounts = accounts.data.filter((a: any) => a.isActive === 1);
const currencies = new Set<Currency>(activeAccounts.map((a: Account) => a.currency));
const currencies = new Set<Currency>(accounts.data.map((a: Account) => a.currency));

return [...currencies].map((c) => ({
dfsp,
currency: c,
ndc: limits.data.find((l: Limit) => l.currency === c)?.limit.value,
settlementAccount: activeAccounts.find(
settlementAccount: accounts.data.find(
(a: Account) => a.currency === c && a.ledgerAccountType === 'SETTLEMENT',
),
positionAccount: activeAccounts.find(
positionAccount: accounts.data.find(
(a: Account) => a.currency === c && a.ledgerAccountType === 'POSITION',
),
}));
Expand Down Expand Up @@ -178,7 +210,7 @@ function* updateFinancialPositionsParticipant() {
const response = yield call(api.fundsIn.create, args);

assert(response.status === 202, 'Unable to update Financial Position Balance');

yield call(checkAccountFundUpdate, account.value, position.dfsp.name);
break;
}
case FinancialPositionsUpdateAction.WithdrawFunds: {
Expand Down Expand Up @@ -209,9 +241,8 @@ function* updateFinancialPositionsParticipant() {
);
// @ts-ignore
const response = yield call(api.fundsOut.create, args);

assert(response.status === 202, 'Unable to update Financial Position Balance');

yield call(checkAccountFundUpdate, account.value, position.dfsp.name);
break;
}
default: {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { State } from 'store';
import buildApi, { buildEndpointBuilder, EndpointConfig } from '@modusbox/redux-utils/lib/api';

const [centralLedgerURL] =
export const [centralLedgerURL] =
process.env.NODE_ENV === 'production'
? [window.positionsEnv.CENTRAL_LEDGER_ENDPOINT]
: [process.env.CENTRAL_LEDGER_ENDPOINT || ''];
Expand Down
2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ module.exports = {
'/central-ledger': {
// For local testing update `target` to point to your
// locally hosted or port-forwarded `central-ledger` service
target: 'http://localhost:port',
target: 'http://localhost:38561',
pathRewrite: { '^/central-ledger': '' },
secure: false,
},
Expand Down
24 changes: 24 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2475,6 +2475,13 @@
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==

"@types/async-retry@^1.4.3":
version "1.4.3"
resolved "https://registry.yarnpkg.com/@types/async-retry/-/async-retry-1.4.3.tgz#8b78f6ce88d97e568961732cdd9e5325cdc8c246"
integrity sha512-B3C9QmmNULVPL2uSJQ088eGWTNPIeUk35hca6CV8rRDJ8GXuQJP5CCVWA1ZUCrb9xYP7Js/RkLqnNNwKhe+Zsw==
dependencies:
"@types/retry" "*"

"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7":
version "7.1.16"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702"
Expand Down Expand Up @@ -2762,6 +2769,11 @@
resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.29.tgz#68ccecec3d4ffdafb9c577fe764f912afc050fe6"
integrity sha512-QSvevZ+IRww2ldtfv1QskYsqVVVwCKQf1XbwtcyyoRvLIQzfyPhj/C+3+PKzSDRdiyejaiLgnq//XTkleorpLg==

"@types/retry@*":
version "0.12.1"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==

"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
Expand Down Expand Up @@ -3601,6 +3613,13 @@ async-limiter@~1.0.0:
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==

async-retry@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.3.3.tgz#0e7f36c04d8478e7a58bdbed80cedf977785f280"
integrity sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==
dependencies:
retry "0.13.1"

async@^2.6.2:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
Expand Down Expand Up @@ -10805,6 +10824,11 @@ ret@~0.1.10:
resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==

retry@0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==

retry@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"
Expand Down

0 comments on commit f9c6901

Please sign in to comment.