Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Commit

Permalink
perf: optimise activity loading
Browse files Browse the repository at this point in the history
  • Loading branch information
mrfelton committed May 23, 2020
1 parent d483bd8 commit 59f9fd6
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 55 deletions.
6 changes: 3 additions & 3 deletions renderer/components/Activity/Activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Activity = props => {
errorDialogDetails,
currentActivity,
showNotification,
loadNextPage,
loadPage,
intl,
} = props

Expand All @@ -35,7 +35,7 @@ const Activity = props => {

const isRowLoaded = ({ index }) => Boolean(currentActivity[index])

const loadMoreRows = () => loadNextPage()
const loadMoreRows = () => loadPage()
const renderActivityList = () => {
return (
<InfiniteLoader
Expand Down Expand Up @@ -90,7 +90,7 @@ Activity.propTypes = {
hideErrorDetailsDialog: PropTypes.func.isRequired,
intl: intlShape.isRequired,
isErrorDialogOpen: PropTypes.bool,
loadNextPage: PropTypes.func.isRequired,
loadPage: PropTypes.func.isRequired,
showNotification: PropTypes.func.isRequired,
}

Expand Down
19 changes: 12 additions & 7 deletions renderer/components/App/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const App = ({
modals,
redirectPayReq,
updateAutopilotNodeScores,
fetchActivityHistory,
initActivityHistory,
setIsWalletOpen,
fetchDescribeNetwork,
fetchPeers,
fetchTransactions,
setModals,
Expand All @@ -51,8 +52,8 @@ const App = ({
* node data quite frequently but as time goes on the frequency is reduced to a max of PEERS_MAX_REFETCH_INTERVAL
*/
appScheduler.addTask({
task: fetchPeers,
taskId: 'fetchPeers',
task: () => fetchDescribeNetwork() && fetchPeers(),
taskId: 'fetchNetworkData',
baseDelay: PEERS_INITIAL_REFETCH_INTERVAL,
maxDelay: PEERS_MAX_REFETCH_INTERVAL,
backoff: PEERS_REFETCH_BACKOFF_SCHEDULE,
Expand All @@ -73,15 +74,17 @@ const App = ({
return () => {
appScheduler.removeAllTasks()
}
}, [fetchPeers, fetchTransactions, updateAutopilotNodeScores])
}, [fetchDescribeNetwork, fetchPeers, fetchTransactions, updateAutopilotNodeScores])

useEffect(() => {
// Set wallet open state.
setIsWalletOpen(true)
// fetch data from lnd.
fetchActivityHistory()
initActivityHistory()
// fetch node info.
fetchPeers()
// fetch network info
fetchDescribeNetwork()
// Update autopilot node scores.
updateAutopilotNodeScores()
fetchSuggestedNodes()
Expand All @@ -93,7 +96,8 @@ const App = ({
finishLnurlWithdrawal()
}
}, [
fetchActivityHistory,
initActivityHistory,
fetchDescribeNetwork,
fetchPeers,
fetchSuggestedNodes,
initBackupService,
Expand Down Expand Up @@ -128,11 +132,12 @@ const App = ({
}

App.propTypes = {
fetchActivityHistory: PropTypes.func.isRequired,
fetchDescribeNetwork: PropTypes.func.isRequired,
fetchPeers: PropTypes.func.isRequired,
fetchSuggestedNodes: PropTypes.func.isRequired,
fetchTransactions: PropTypes.func.isRequired,
finishLnurlWithdrawal: PropTypes.func.isRequired,
initActivityHistory: PropTypes.func.isRequired,
initBackupService: PropTypes.func.isRequired,
initTickers: PropTypes.func.isRequired,
isAppReady: PropTypes.bool.isRequired,
Expand Down
4 changes: 2 additions & 2 deletions renderer/containers/Activity/Activity.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { connect } from 'react-redux'
import { activitySelectors, loadNextPage, ERROR_DETAILS_DIALOG_ID } from 'reducers/activity'
import { activitySelectors, loadPage, ERROR_DETAILS_DIALOG_ID } from 'reducers/activity'
import { showNotification } from 'reducers/notification'
import { modalSelectors, closeDialog } from 'reducers/modal'
import Activity from 'components/Activity'
Expand All @@ -15,7 +15,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = {
hideErrorDetailsDialog,
showNotification,
loadNextPage,
loadPage,
}

export default connect(mapStateToProps, mapDispatchToProps)(Activity)
6 changes: 4 additions & 2 deletions renderer/containers/App/App.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react'
import { connect } from 'react-redux'
import { fetchPeers } from 'reducers/peers'
import { fetchDescribeNetwork } from 'reducers/network'
import { setIsWalletOpen } from 'reducers/wallet'
import { updateAutopilotNodeScores } from 'reducers/autopilot'
import { fetchActivityHistory } from 'reducers/activity'
import { initActivityHistory } from 'reducers/activity'
import { fetchTransactions } from 'reducers/transaction'
import { appSelectors } from 'reducers/app'
import { finishLnurlWithdrawal, paySelectors } from 'reducers/pay'
Expand All @@ -24,9 +25,10 @@ const mapStateToProps = state => ({
})

const mapDispatchToProps = {
fetchDescribeNetwork,
fetchPeers,
updateAutopilotNodeScores,
fetchActivityHistory,
initActivityHistory,
setIsWalletOpen,
fetchTransactions,
setModals,
Expand Down
86 changes: 45 additions & 41 deletions renderer/reducers/activity/reducer.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { send } from 'redux-electron-ipc'
import groupBy from 'lodash/groupBy'
import range from 'lodash/range'
import config from 'config'
import createReducer from '@zap/utils/createReducer'
import { getIntl } from '@zap/i18n'
import { mainLog } from '@zap/utils/log'
import { openModal, closeModal } from 'reducers/modal'
import { fetchDescribeNetwork } from 'reducers/network'
import { receiveTransactions } from 'reducers/transaction'
import { receivePayments } from 'reducers/payment'
import { receiveInvoices } from 'reducers/invoice'
import { fetchBalance } from 'reducers/balance'
import { showError, showNotification } from 'reducers/notification'
import { fetchChannels } from 'reducers/channels'
import { createActivityPaginator } from './utils'
import { showError, showNotification } from 'reducers/notification'
import { createActivityPaginator, getItemType } from './utils'
import { hasNextPage } from './selectors'
import messages from './messages'
import * as constants from './constants'
Expand Down Expand Up @@ -203,91 +204,94 @@ export const hideActivityModal = () => dispatch => {
}

/**
* resetActivity - Reset user activity history.
* resetActivity - Reset activity history.
*
* @returns {() => void} Thunk
*/
export const resetActivity = () => () => {
paginator = null
loadedPages = 0
}

/**
* resetPaginator - Reset activity paginator.
*
* @returns {() => void} Thunk
*/
export const resetPaginator = () => () => {
paginator = null
}

/**
* loadNextPage - Loads next activity page if it's available.
* loadPage - Loads next activity page if it's available.
*
* @param {number} pageSize Pagesize (defaults to config.activity.pageSize)
* @param {boolean} reload Reload existing pages
* @param {boolean} reload Boolean indicating if this page load is part of a reload.
* @returns {(dispatch:Function, getState:Function) => Promise<void>} Thunk
*/
export const loadNextPage = (pageSize = config.activity.pageSize, reload = false) => async (
dispatch,
getState
) => {
if (reload) {
dispatch(resetActivity())
}
export const loadPage = (reload = false) => async (dispatch, getState) => {
const thisPaginator = getPaginator()

if (hasNextPage(getState())) {
if (reload || hasNextPage(getState())) {
const { pageSize } = config.activity
const { items, hasNextPage: paginatorHasNextPage } = await thisPaginator(pageSize)

if (!reload) {
loadedPages += 1
}

const getItemType = item => {
if (item.destAddresses) {
return 'transactions'
}
if ('addIndex' in item) {
return 'invoices'
}
return 'payments'
dispatch({ type: SET_HAS_NEXT_PAGE, value: paginatorHasNextPage })
}

const { invoices, payments, transactions } = groupBy(items, getItemType)
dispatch({ type: SET_HAS_NEXT_PAGE, value: paginatorHasNextPage })
invoices && dispatch(receiveInvoices(invoices))
payments && dispatch(receivePayments(payments))
transactions && dispatch(receiveTransactions(transactions))
}
}

/**
* fetchActivityHistory - Fetch user activity history, including Balance, Payments, Invoices, Transactions etc.
* reloadPages - Reloads all already loaded activity pages.
*
* @returns {(dispatch:Function) => Promise<void>} Thunk
*/
export const reloadPages = () => async dispatch => {
const pageCount = loadedPages
mainLog.debug(`reloading ${pageCount} activity pages`)
dispatch(resetPaginator())

// eslint-disable-next-line no-unused-vars
for (const page of range(pageCount)) {
mainLog.debug(`reloading activity page ${page}`)
// eslint-disable-next-line no-await-in-loop
await dispatch(loadPage(true))
}
}

/**
* initActivityHistory - Load user activity history.
*
* @returns {(dispatch:Function) => void} Thunk
*/
export const fetchActivityHistory = () => dispatch => {
export const initActivityHistory = () => async dispatch => {
dispatch({ type: FETCH_ACTIVITY_HISTORY })
try {
dispatch(fetchDescribeNetwork())
await dispatch(loadPage())
dispatch(fetchChannels())
dispatch(fetchBalance())

dispatch(resetActivity())
dispatch(loadNextPage())

dispatch({ type: FETCH_ACTIVITY_HISTORY_SUCCESS })
} catch (error) {
dispatch({ type: FETCH_ACTIVITY_HISTORY_FAILURE, error })
}
}

/**
* reloadActivityHistory - Reload activity history, including Balance, Payments, Invoices, Transactions etc.
* reloadActivityHistory - Reload activity history.
*
* @returns {(dispatch:Function) => void} Thunk
*/
export const reloadActivityHistory = () => dispatch => {
export const reloadActivityHistory = () => async dispatch => {
dispatch({ type: FETCH_ACTIVITY_HISTORY })
try {
dispatch(fetchDescribeNetwork())
await dispatch(reloadPages())
dispatch(fetchChannels())
dispatch(fetchBalance())

const itemsToLoad = loadedPages * config.activity.pageSize
dispatch(loadNextPage(itemsToLoad, true))

dispatch({ type: FETCH_ACTIVITY_HISTORY_SUCCESS })
} catch (error) {
dispatch({ type: FETCH_ACTIVITY_HISTORY_FAILURE, error })
Expand Down
16 changes: 16 additions & 0 deletions renderer/reducers/activity/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,19 @@ export const createActivityPaginator = () => {

return combinePaginators(itemSorter, fetchInvoices, fetchPayments, fetchTransactions)
}

/**
* getItemType - Determine an activity item type.
*
* @param {object<string, any>} item Activity item
* @returns {string} Item type
*/
export const getItemType = item => {
if (item.destAddresses) {
return 'transactions'
}
if ('addIndex' in item) {
return 'invoices'
}
return 'payments'
}

0 comments on commit 59f9fd6

Please sign in to comment.