refactor: make tx history fetch async again

This commit is contained in:
Jonathan Rainville 2021-11-01 14:08:55 -04:00 committed by Iuri Matias
parent 8aec0c62e7
commit 8dcc63bdf6
6 changed files with 106 additions and 85 deletions

View File

@ -133,7 +133,7 @@ proc newAppController*(appService: AppService): AppController =
result.walletAccountService = wallet_account_service.newService( result.walletAccountService = wallet_account_service.newService(
appService.status.events, result.settingService, result.tokenService appService.status.events, result.settingService, result.tokenService
) )
result.transactionService = transaction_service.newService(result.walletAccountService) result.transactionService = transaction_service.newService(appService.status.events, appService.threadpool, result.walletAccountService)
result.bookmarkService = bookmark_service.newService() result.bookmarkService = bookmark_service.newService()
result.profileService = profile_service.newService() result.profileService = profile_service.newService()
result.settingsService = settings_service.newService() result.settingsService = settings_service.newService()

View File

@ -41,7 +41,7 @@ proc newModule*[T](
delegate: T, delegate: T,
events: EventEmitter, events: EventEmitter,
tokenService: token_service.ServiceInterface, tokenService: token_service.ServiceInterface,
transactionService: transaction_service.ServiceInterface, transactionService: transaction_service.Service,
collectibleService: collectible_service.ServiceInterface, collectibleService: collectible_service.ServiceInterface,
walletAccountService: wallet_account_service.ServiceInterface, walletAccountService: wallet_account_service.ServiceInterface,
settingService: setting_service.ServiceInterface settingService: setting_service.ServiceInterface

View File

@ -19,7 +19,7 @@ type
Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface delegate: io_interface.AccessInterface
events: EventEmitter events: EventEmitter
transactionService: transaction_service.ServiceInterface transactionService: transaction_service.Service
walletAccountService: wallet_account_service.ServiceInterface walletAccountService: wallet_account_service.ServiceInterface
# Forward declaration # Forward declaration
@ -29,7 +29,7 @@ method getWalletAccounts*[T](self: Controller[T]): seq[WalletAccountDto]
proc newController*[T]( proc newController*[T](
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
transactionService: transaction_service.ServiceInterface, transactionService: transaction_service.Service,
walletAccountService: wallet_account_service.ServiceInterface walletAccountService: wallet_account_service.ServiceInterface
): Controller[T] = ): Controller[T] =
result = Controller[T]() result = Controller[T]()
@ -61,6 +61,10 @@ method init*[T](self: Controller[T]) =
self.delegate.setHistoryFetchState(addresses, false) self.delegate.setHistoryFetchState(addresses, false)
else: else:
echo "Unhandled wallet signal: ", data.eventType echo "Unhandled wallet signal: ", data.eventType
self.events.on(SIGNAL_TRANSACTIONS_LOADED) do(e:Args):
let args = TransactionsLoadedArgs(e)
self.delegate.setTrxHistoryResult(args.transactions, args.address, args.wasFetchMore)
method checkRecentHistory*[T](self: Controller[T]) = method checkRecentHistory*[T](self: Controller[T]) =
self.transactionService.checkRecentHistory() self.transactionService.checkRecentHistory()
@ -75,26 +79,4 @@ method getAccountByAddress*[T](self: Controller[T], address: string): WalletAcco
self.walletAccountService.getAccountByAddress(address) self.walletAccountService.getAccountByAddress(address)
method loadTransactions*[T](self: Controller[T], address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) = method loadTransactions*[T](self: Controller[T], address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) =
let transactions = self.transactionService.getTransfersByAddressTemp(address, toBlock, limit, loadMore) self.transactionService.loadTransactions(address, toBlock, limit, loadMore)
self.setTrxHistoryResult(transactions)
# TODO reimplement thread task
# let arg = LoadTransactionsTaskArg(
# address: address,
# tptr: cast[ByteAddress](loadTransactionsTask),
# vptr: cast[ByteAddress](self.vptr),
# slot: "setTrxHistoryResult",
# toBlock: toBlock,
# limit: limit,
# loadMore: loadMore
# )
# self.appService.threadpool.start(arg)
method setTrxHistoryResult*[T](self: Controller[T], historyJSON: string) {.slot.} =
let historyData = parseJson(historyJSON)
let address = historyData["address"].getStr
let wasFetchMore = historyData["loadMore"].getBool
var transactions: seq[TransactionDto] = @[]
for tx in historyData["history"]["result"].getElems():
transactions.add(tx.toTransactionDto())
self.delegate.setTrxHistoryResult(transactions, address, wasFetchMore)

View File

@ -22,7 +22,7 @@ method loadTransactions*[T](self: Module[T], address: string, toBlock: string =
proc newModule*[T]( proc newModule*[T](
delegate: T, delegate: T,
events: EventEmitter, events: EventEmitter,
transactionService: transaction_service.ServiceInterface, transactionService: transaction_service.Service,
walletAccountService: wallet_account_service.ServiceInterface walletAccountService: wallet_account_service.ServiceInterface
): Module[T] = ): Module[T] =
result = Module[T]() result = Module[T]()
@ -75,4 +75,4 @@ method setTrxHistoryResult*[T](self: Module[T], transactions: seq[TransactionDto
self.view.setTrxHistoryResult(transactions, address, wasFetchMore) self.view.setTrxHistoryResult(transactions, address, wasFetchMore)
method setHistoryFetchState*[T](self: Module[T], addresses: seq[string], isFetching: bool) = method setHistoryFetchState*[T](self: Module[T], addresses: seq[string], isFetching: bool) =
self.view.setHistoryFetchStateForAccounts(addresses, isFetching) self.view.setHistoryFetchStateForAccounts(addresses, isFetching)

View File

@ -0,0 +1,23 @@
include ../../common/json_utils
include ../../tasks/common
#################################################
# Async load transactions
#################################################
type
LoadTransactionsTaskArg* = ref object of QObjectTaskArg
address: string
toBlock: Uint256
limit: int
loadMore: bool
const loadTransactionsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let
arg = decode[LoadTransactionsTaskArg](argEncoded)
output = %*{
"address": arg.address,
"history": transactions.getTransfersByAddress(arg.address, arg.toBlock, arg.limit, arg.loadMore),
"loadMore": arg.loadMore
}
arg.finish(output)

View File

@ -1,6 +1,9 @@
import chronicles, sequtils, sugar, stint, json import NimQml, chronicles, sequtils, sugar, stint, json
import status/statusgo_backend_new/transactions as transactions import status/statusgo_backend_new/transactions as transactions
import eventemitter
import ../../tasks/[qt, threadpool]
import ../wallet_account/service as wallet_account_service import ../wallet_account/service as wallet_account_service
import ./service_interface, ./dto import ./service_interface, ./dto
@ -12,68 +15,81 @@ logScope:
import ../../../app_service/[main] import ../../../app_service/[main]
import ../../../app_service/tasks/[qt, threadpool] import ../../../app_service/tasks/[qt, threadpool]
include async_tasks
# Signals which may be emitted by this service:
const SIGNAL_TRANSACTIONS_LOADED* = "SIGNAL_TRANSACTIONS_LOADED"
type type
LoadTransactionsTaskArg* = ref object of QObjectTaskArg TransactionsLoadedArgs* = ref object of Args
address: string transactions*: seq[TransactionDto]
toBlock: Uint256 address*: string
limit: int wasFetchMore*: bool
loadMore: bool
const loadTransactionsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = QtObject:
let type Service* = ref object of QObject
arg = decode[LoadTransactionsTaskArg](argEncoded) events: EventEmitter
output = %*{ threadpool: ThreadPool
"address": arg.address,
"history": transactions.getTransfersByAddress(arg.address, arg.toBlock, arg.limit, arg.loadMore),
"loadMore": arg.loadMore
}
arg.finish(output)
type
Service* = ref object of service_interface.ServiceInterface
walletAccountService: wallet_account_service.ServiceInterface walletAccountService: wallet_account_service.ServiceInterface
method delete*(self: Service) = proc delete*(self: Service) =
discard self.QObject.delete
proc newService*(walletAccountService: wallet_account_service.ServiceInterface): Service = proc newService*(events: EventEmitter, threadpool: ThreadPool, walletAccountService: wallet_account_service.ServiceInterface): Service =
result = Service() new(result, delete)
result.walletAccountService = walletAccountService result.QObject.setup
result.events = events
result.threadpool = threadpool
result.walletAccountService = walletAccountService
method init*(self: Service) = proc init*(self: Service) =
discard discard
method checkRecentHistory*(self: Service) = proc checkRecentHistory*(self: Service) =
try: try:
let addresses = self.walletAccountService.getWalletAccounts().map(a => a.address) let addresses = self.walletAccountService.getWalletAccounts().map(a => a.address)
transactions.checkRecentHistory(addresses) transactions.checkRecentHistory(addresses)
except Exception as e: except Exception as e:
let errDesription = e.msg let errDesription = e.msg
error "error: ", errDesription error "error: ", errDesription
return return
method getTransfersByAddress*(self: Service, address: string, toBlock: Uint256, limit: int, loadMore: bool = false): seq[TransactionDto] = proc getTransfersByAddress*(self: Service, address: string, toBlock: Uint256, limit: int, loadMore: bool = false): seq[TransactionDto] =
try: try:
let response = transactions.getTransfersByAddress(address, toBlock, limit, loadMore) let response = transactions.getTransfersByAddress(address, toBlock, limit, loadMore)
result = map( result = map(
response.result.getElems(), response.result.getElems(),
proc(x: JsonNode): TransactionDto = x.toTransactionDto() proc(x: JsonNode): TransactionDto = x.toTransactionDto()
)
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return
proc setTrxHistoryResult*(self: Service, historyJSON: string) {.slot.} =
let historyData = parseJson(historyJSON)
let address = historyData["address"].getStr
let wasFetchMore = historyData["loadMore"].getBool
var transactions: seq[TransactionDto] = @[]
for tx in historyData["history"]["result"].getElems():
transactions.add(tx.toTransactionDto())
# emit event
self.events.emit(SIGNAL_TRANSACTIONS_LOADED, TransactionsLoadedArgs(
transactions: transactions,
address: address,
wasFetchMore: wasFetchMore
))
proc loadTransactions*(self: Service, address: string, toBlock: Uint256, limit: int = 20, loadMore: bool = false) =
let arg = LoadTransactionsTaskArg(
address: address,
tptr: cast[ByteAddress](loadTransactionsTask),
vptr: cast[ByteAddress](self.vptr),
slot: "setTrxHistoryResult",
toBlock: toBlock,
limit: limit,
loadMore: loadMore
) )
except Exception as e: self.threadpool.start(arg)
let errDesription = e.msg
error "error: ", errDesription
return
method getTransfersByAddressTemp*(self: Service, address: string, toBlock: Uint256, limit: int, loadMore: bool = false): string =
try:
let resp = transactions.getTransfersByAddress(address, toBlock, limit, loadMore)
return $(%*{
"address": address,
"history": resp,
"loadMore": loadMore
})
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return