From 8dcc63bdf6dedeb187341acd04e0b3a8b208373a Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Mon, 1 Nov 2021 14:08:55 -0400 Subject: [PATCH] refactor: make tx history fetch async again --- src/app/boot/app_controller.nim | 2 +- .../modules/main/wallet_section/module.nim | 2 +- .../transactions/controller.nim | 32 +---- .../wallet_section/transactions/module.nim | 4 +- .../service/transaction/async_tasks.nim | 23 ++++ .../service/transaction/service.nim | 128 ++++++++++-------- 6 files changed, 106 insertions(+), 85 deletions(-) create mode 100644 src/app_service/service/transaction/async_tasks.nim diff --git a/src/app/boot/app_controller.nim b/src/app/boot/app_controller.nim index df79e596a3..ecda2946bb 100644 --- a/src/app/boot/app_controller.nim +++ b/src/app/boot/app_controller.nim @@ -133,7 +133,7 @@ proc newAppController*(appService: AppService): AppController = result.walletAccountService = wallet_account_service.newService( 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.profileService = profile_service.newService() result.settingsService = settings_service.newService() diff --git a/src/app/modules/main/wallet_section/module.nim b/src/app/modules/main/wallet_section/module.nim index 8119f4d65f..080d4aa195 100644 --- a/src/app/modules/main/wallet_section/module.nim +++ b/src/app/modules/main/wallet_section/module.nim @@ -41,7 +41,7 @@ proc newModule*[T]( delegate: T, events: EventEmitter, tokenService: token_service.ServiceInterface, - transactionService: transaction_service.ServiceInterface, + transactionService: transaction_service.Service, collectibleService: collectible_service.ServiceInterface, walletAccountService: wallet_account_service.ServiceInterface, settingService: setting_service.ServiceInterface diff --git a/src/app/modules/main/wallet_section/transactions/controller.nim b/src/app/modules/main/wallet_section/transactions/controller.nim index 917bf434ed..02be89dcbe 100644 --- a/src/app/modules/main/wallet_section/transactions/controller.nim +++ b/src/app/modules/main/wallet_section/transactions/controller.nim @@ -19,7 +19,7 @@ type Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface delegate: io_interface.AccessInterface events: EventEmitter - transactionService: transaction_service.ServiceInterface + transactionService: transaction_service.Service walletAccountService: wallet_account_service.ServiceInterface # Forward declaration @@ -29,7 +29,7 @@ method getWalletAccounts*[T](self: Controller[T]): seq[WalletAccountDto] proc newController*[T]( delegate: io_interface.AccessInterface, events: EventEmitter, - transactionService: transaction_service.ServiceInterface, + transactionService: transaction_service.Service, walletAccountService: wallet_account_service.ServiceInterface ): Controller[T] = result = Controller[T]() @@ -61,6 +61,10 @@ method init*[T](self: Controller[T]) = self.delegate.setHistoryFetchState(addresses, false) else: 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]) = self.transactionService.checkRecentHistory() @@ -75,26 +79,4 @@ method getAccountByAddress*[T](self: Controller[T], address: string): WalletAcco self.walletAccountService.getAccountByAddress(address) 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.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) + self.transactionService.loadTransactions(address, toBlock, limit, loadMore) diff --git a/src/app/modules/main/wallet_section/transactions/module.nim b/src/app/modules/main/wallet_section/transactions/module.nim index 77b600e55b..fe1d2520ac 100644 --- a/src/app/modules/main/wallet_section/transactions/module.nim +++ b/src/app/modules/main/wallet_section/transactions/module.nim @@ -22,7 +22,7 @@ method loadTransactions*[T](self: Module[T], address: string, toBlock: string = proc newModule*[T]( delegate: T, events: EventEmitter, - transactionService: transaction_service.ServiceInterface, + transactionService: transaction_service.Service, walletAccountService: wallet_account_service.ServiceInterface ): Module[T] = result = Module[T]() @@ -75,4 +75,4 @@ method setTrxHistoryResult*[T](self: Module[T], transactions: seq[TransactionDto self.view.setTrxHistoryResult(transactions, address, wasFetchMore) method setHistoryFetchState*[T](self: Module[T], addresses: seq[string], isFetching: bool) = - self.view.setHistoryFetchStateForAccounts(addresses, isFetching) \ No newline at end of file + self.view.setHistoryFetchStateForAccounts(addresses, isFetching) diff --git a/src/app_service/service/transaction/async_tasks.nim b/src/app_service/service/transaction/async_tasks.nim new file mode 100644 index 0000000000..1b3ea9e81d --- /dev/null +++ b/src/app_service/service/transaction/async_tasks.nim @@ -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) diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim index bc44530e1a..e15156fa75 100644 --- a/src/app_service/service/transaction/service.nim +++ b/src/app_service/service/transaction/service.nim @@ -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 eventemitter +import ../../tasks/[qt, threadpool] + import ../wallet_account/service as wallet_account_service import ./service_interface, ./dto @@ -12,68 +15,81 @@ logScope: import ../../../app_service/[main] 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 - LoadTransactionsTaskArg* = ref object of QObjectTaskArg - address: string - toBlock: Uint256 - limit: int - loadMore: bool + TransactionsLoadedArgs* = ref object of Args + transactions*: seq[TransactionDto] + address*: string + wasFetchMore*: 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) - -type - Service* = ref object of service_interface.ServiceInterface +QtObject: + type Service* = ref object of QObject + events: EventEmitter + threadpool: ThreadPool walletAccountService: wallet_account_service.ServiceInterface -method delete*(self: Service) = - discard + proc delete*(self: Service) = + self.QObject.delete -proc newService*(walletAccountService: wallet_account_service.ServiceInterface): Service = - result = Service() - result.walletAccountService = walletAccountService + proc newService*(events: EventEmitter, threadpool: ThreadPool, walletAccountService: wallet_account_service.ServiceInterface): Service = + new(result, delete) + result.QObject.setup + result.events = events + result.threadpool = threadpool + result.walletAccountService = walletAccountService -method init*(self: Service) = - discard + proc init*(self: Service) = + discard -method checkRecentHistory*(self: Service) = - try: - let addresses = self.walletAccountService.getWalletAccounts().map(a => a.address) - transactions.checkRecentHistory(addresses) - except Exception as e: - let errDesription = e.msg - error "error: ", errDesription - return + proc checkRecentHistory*(self: Service) = + try: + let addresses = self.walletAccountService.getWalletAccounts().map(a => a.address) + transactions.checkRecentHistory(addresses) + except Exception as e: + let errDesription = e.msg + error "error: ", errDesription + return -method getTransfersByAddress*(self: Service, address: string, toBlock: Uint256, limit: int, loadMore: bool = false): seq[TransactionDto] = - try: - let response = transactions.getTransfersByAddress(address, toBlock, limit, loadMore) + proc getTransfersByAddress*(self: Service, address: string, toBlock: Uint256, limit: int, loadMore: bool = false): seq[TransactionDto] = + try: + let response = transactions.getTransfersByAddress(address, toBlock, limit, loadMore) - result = map( - response.result.getElems(), - proc(x: JsonNode): TransactionDto = x.toTransactionDto() + result = map( + response.result.getElems(), + 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: - 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 \ No newline at end of file + self.threadpool.start(arg) \ No newline at end of file