From 374f2e2149b2c284067af8bae2c73dc91680d12e Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Wed, 2 Aug 2023 13:59:29 -0400 Subject: [PATCH] feat(community): make importCommunity async Fixes #11693 --- .../modules/main/communities/controller.nim | 2 +- .../service/community/async_tasks.nim | 17 ++++++++ src/app_service/service/community/service.nim | 43 ++++++++++++------- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/app/modules/main/communities/controller.nim b/src/app/modules/main/communities/controller.nim index 8b653ca13b..7d47ebe419 100644 --- a/src/app/modules/main/communities/controller.nim +++ b/src/app/modules/main/communities/controller.nim @@ -279,7 +279,7 @@ proc removePrivateKey*(self: Controller, communityId: string) = self.communityService.removePrivateKey(communityId) proc importCommunity*(self: Controller, communityKey: string) = - self.communityService.importCommunity(communityKey) + self.communityService.asyncImportCommunity(communityKey) proc setCommunityMuted*(self: Controller, communityId: string, mutedType: int) = self.communityService.setCommunityMuted(communityId, mutedType) diff --git a/src/app_service/service/community/async_tasks.nim b/src/app_service/service/community/async_tasks.nim index 14334c20bb..29ea8c75c6 100644 --- a/src/app_service/service/community/async_tasks.nim +++ b/src/app_service/service/community/async_tasks.nim @@ -168,3 +168,20 @@ const asyncCheckPermissionsToJoinTask: Task = proc(argEncoded: string) {.gcsafe, "communityId": arg.communityId, "error": e.msg, }) + +type + AsyncImportCommunityTaskArg = ref object of QObjectTaskArg + communityKey: string + +const asyncImportCommunityTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = + let arg = decode[AsyncImportCommunityTaskArg](argEncoded) + try: + let response = status_go.importCommunity(arg.communityKey) + arg.finish(%* { + "response": response, + "error": "", + }) + except Exception as e: + arg.finish(%* { + "error": e.msg, + }) diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim index 4cc70c52bf..e2464383c4 100644 --- a/src/app_service/service/community/service.nim +++ b/src/app_service/service/community/service.nim @@ -1636,33 +1636,44 @@ QtObject: except Exception as e: error "Error removing community private key: ", msg = e.msg - proc importCommunity*(self: Service, communityKey: string) = + proc asyncImportCommunity*(self: Service, communityKey: string) = + let arg = AsyncImportCommunityTaskArg( + tptr: cast[ByteAddress](asyncImportCommunityTask), + vptr: cast[ByteAddress](self.vptr), + slot: "onAsyncImportCommunityCompleted", + communityKey: communityKey, + ) + self.threadpool.start(arg) + + proc onAsyncImportCommunityCompleted*(self: Service, response: string) {.slot.} = try: - let response = status_go.importCommunity(communityKey) + let rpcResponseObj = response.parseJson + if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "": + raise newException(RpcException, rpcResponseObj["error"].getStr) ## after `importCommunity` call everything should be handled in a slot cnnected to `SignalType.CommunityFound.event` ## but because of insufficient data (chats details are missing) sent as a payload of that signal we're unable to do ## that until `status-go` part gets improved in ragards of that. - if (response.error != nil): - let error = Json.decode($response.error, RpcError) - raise newException(RpcException, fmt"community id `{communityKey}` err: {error.message}") + if rpcResponseObj["response"]{"error"}.kind != JNull: + let error = Json.decode(rpcResponseObj["response"]["error"].getStr, RpcError) + raise newException(RpcException, error.message) - if response.result == nil or response.result.kind != JObject: - raise newException(RpcException, fmt"response is empty or not an json object, community id `{communityKey}`") + if rpcResponseObj["response"]{"result"} == nil or rpcResponseObj["response"]{"result"}.kind != JObject: + raise newException(RpcException, "response is empty or not an json object") var communityJArr: JsonNode - if(not response.result.getProp("communities", communityJArr)): - raise newException(RpcException, fmt"there is no `communities` key in the response for community id: {communityKey}") + if not rpcResponseObj["response"]{"result"}.getProp("communities", communityJArr): + raise newException(RpcException, "there is no `communities` key in the response") - if(communityJArr.len == 0): - raise newException(RpcException, fmt"`communities` array is empty in the response for community id: {communityKey}") + if communityJArr.len == 0: + raise newException(RpcException, "`communities` array is empty in the response") var communitiesSettingsJArr: JsonNode - if(not response.result.getProp("communitiesSettings", communitiesSettingsJArr)): - raise newException(RpcException, fmt"there is no `communitiesSettings` key in the response for community id: {communityKey}") + if not rpcResponseObj["response"]{"result"}.getProp("communitiesSettings", communitiesSettingsJArr): + raise newException(RpcException, "there is no `communitiesSettings` key in the response") - if(communitiesSettingsJArr.len == 0): - raise newException(RpcException, fmt"`communitiesSettings` array is empty in the response for community id: {communityKey}") + if communitiesSettingsJArr.len == 0: + raise newException(RpcException, "`communitiesSettings` array is empty in the response") var communityDto = communityJArr[0].toCommunityDto() let communitySettingsDto = communitiesSettingsJArr[0].toCommunitySettingsDto() @@ -1671,7 +1682,7 @@ QtObject: self.communities[communityDto.id] = communityDto var chatsJArr: JsonNode - if(response.result.getProp("chats", chatsJArr)): + if rpcResponseObj["response"]{"result"}.getProp("chats", chatsJArr): for chatObj in chatsJArr: let chatDto = chatObj.toChatDto(communityDto.id) self.chatService.updateOrAddChat(chatDto) # we have to update chats stored in the chat service.