From d4cd52ca16e7cd5b8f65f155c2211c1938f67a6c Mon Sep 17 00:00:00 2001
From: Bernardo Cardoso <bernardo@elixxir.io>
Date: Wed, 3 Apr 2019 12:18:04 -0600
Subject: [PATCH] Make UDB calls non blocking by using goroutine and callbacks

---
 bindings/client.go | 22 +++++++++++++---------
 cmd/root.go        |  3 +--
 cmd/udb.go         | 39 ++++++++++++++++++++++-----------------
 3 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/bindings/client.go b/bindings/client.go
index ee5dde69b..e401ca3c1 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -191,8 +191,11 @@ func SetRateLimiting(limit int) {
 	api.SetRateLimiting(uint32(limit))
 }
 
-func RegisterForUserDiscovery(emailAddress string) error {
-	return api.RegisterForUserDiscovery(emailAddress)
+func RegisterForUserDiscovery(emailAddress string, callback func(error)) {
+	go func() {
+		err := api.RegisterForUserDiscovery(emailAddress)
+		callback(err)
+	}()
 }
 
 type SearchResult struct {
@@ -200,13 +203,14 @@ type SearchResult struct {
 	PublicKey []byte
 }
 
-func SearchForUser(emailAddress string) (*SearchResult, error) {
-	searchedUser, key, err := api.SearchForUser(emailAddress)
-	if err != nil {
-		return nil, err
-	} else {
-		return &SearchResult{ResultID: searchedUser.Bytes(), PublicKey: key}, nil
-	}
+func SearchForUser(emailAddress string, callback func(SearchResult, error)) {
+	go func() {
+		searchedUser, key, err := api.SearchForUser(emailAddress)
+		callback(SearchResult{
+			ResultID: searchedUser.Bytes(),
+			PublicKey: key},
+			err)
+	}()
 }
 
 // Parses a passed message.  Allows a message to be aprsed using the interal parser
diff --git a/cmd/root.go b/cmd/root.go
index c6ac6aefa..76aaf10b6 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -297,8 +297,7 @@ var rootCmd = &cobra.Command{
 
 			// Handle sending to UDB
 			if *recipientId == *bots.UdbID {
-				grp := user.TheSession.GetGroup()
-				fmt.Println(parseUdbMessage(message, grp))
+				parseUdbMessage(message)
 			} else {
 				// Handle sending to any other destination
 				wireOut := bindings.FormatTextMessage(message)
diff --git a/cmd/udb.go b/cmd/udb.go
index bfe0596a1..1b92972db 100644
--- a/cmd/udb.go
+++ b/cmd/udb.go
@@ -10,12 +10,30 @@ import (
 	"fmt"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/bindings"
-	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/large"
 	"strings"
 )
 
+func handleSearchResults(result bindings.SearchResult, err error) {
+	if err != nil {
+		fmt.Printf("UDB search failed: %v\n", err.Error())
+	} else {
+		userIdText := large.NewIntFromBytes(result.ResultID).Text(10)
+		fmt.Printf("UDB search successful. Returned user %v, "+
+			"public key %q\n", userIdText, result.PublicKey)
+	}
+}
+
+func handleRegisterResult(err error) {
+	if err != nil {
+		fmt.Printf("UDB registration failed: %v\n", err.Error())
+	} else {
+		fmt.Printf("UDB registration successful.\n")
+	}
+}
+
 // Determines what UDB send function to call based on the text in the message
-func parseUdbMessage(msg string, grp *cyclic.Group) string {
+func parseUdbMessage(msg string) {
 	// Split the message on spaces
 	args := strings.Fields(msg)
 	if len(args) < 3 {
@@ -27,23 +45,10 @@ func parseUdbMessage(msg string, grp *cyclic.Group) string {
 	keyword := args[0]
 	// Case-insensitive match the keyword to a command
 	if strings.EqualFold(keyword, "SEARCH") {
-		result, err := bindings.SearchForUser(args[2])
-		if err != nil {
-			return fmt.Sprintf("UDB search failed: %v", err.Error())
-		} else {
-			userIdText := grp.NewIntFromBytes(result.ResultID).Text(10)
-			return fmt.Sprintf("UDB search successful. Returned user %v, "+
-				"public key %q", userIdText, result.PublicKey)
-		}
+		bindings.SearchForUser(args[2], handleSearchResults)
 	} else if strings.EqualFold(keyword, "REGISTER") {
-		err := bindings.RegisterForUserDiscovery(args[2])
-		if err != nil {
-			return fmt.Sprintf("UDB registration failed: %v", err.Error())
-		} else {
-			return "UDB registration successful."
-		}
+		bindings.RegisterForUserDiscovery(args[2], handleRegisterResult)
 	} else {
 		jww.ERROR.Printf("UDB command not recognized!")
 	}
-	return ""
 }
-- 
GitLab