Browse Source

db cache nodes and hosts

Abhishek Kondur 2 years ago
parent
commit
4071bb2bac
8 changed files with 180 additions and 285 deletions
  1. 1 0
      controllers/node_test.go
  2. 2 6
      logic/dns.go
  3. 2 6
      logic/extpeers.go
  4. 4 23
      logic/gateway.go
  5. 90 16
      logic/hosts.go
  6. 2 161
      logic/networks.go
  7. 76 45
      logic/nodes.go
  8. 3 28
      logic/relay.go

+ 1 - 0
controllers/node_test.go

@@ -217,6 +217,7 @@ func TestNodeACLs(t *testing.T) {
 }
 
 func deleteAllNodes() {
+	logic.ClearNodeCache()
 	database.DeleteAllRecords(database.NODES_TABLE_NAME)
 }
 

+ 2 - 6
logic/dns.go

@@ -69,16 +69,12 @@ func GetNodeDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
 
-	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	nodes, err := GetNetworkNodes(network)
 	if err != nil {
 		return dns, err
 	}
 
-	for _, value := range collection {
-		var node models.Node
-		if err = json.Unmarshal([]byte(value), &node); err != nil {
-			continue
-		}
+	for _, node := range nodes {
 		if node.Network != network {
 			continue
 		}

+ 2 - 6
logic/extpeers.go

@@ -46,15 +46,11 @@ func GetExtPeersList(node *models.Node) ([]models.ExtPeersResponse, error) {
 func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
 
 	var result []string
-	nodesData, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	networkNodes, err := GetNetworkNodes(client.Network)
 	if err != nil {
 		return []string{}, err
 	}
-	for _, nodeData := range nodesData {
-		var currentNode models.Node
-		if err = json.Unmarshal([]byte(nodeData), &currentNode); err != nil {
-			continue
-		}
+	for _, currentNode := range networkNodes {
 		if currentNode.Network != client.Network {
 			continue
 		}

+ 4 - 23
logic/gateway.go

@@ -1,7 +1,6 @@
 package logic
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"time"
@@ -53,11 +52,7 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	node.EgressGatewayNatEnabled = models.ParseBool(gateway.NatEnabled)
 	node.EgressGatewayRequest = gateway // store entire request for use when preserving the egress gateway
 	node.SetLastModified()
-	nodeData, err := json.Marshal(&node)
-	if err != nil {
-		return node, err
-	}
-	if err = database.Insert(node.ID.String(), string(nodeData), database.NODES_TABLE_NAME); err != nil {
+	if err = UpsertNode(&node); err != nil {
 		return models.Node{}, err
 	}
 	return node, nil
@@ -84,12 +79,7 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) {
 	node.EgressGatewayRanges = []string{}
 	node.EgressGatewayRequest = models.EgressGatewayRequest{} // remove preserved request as the egress gateway is gone
 	node.SetLastModified()
-
-	data, err := json.Marshal(&node)
-	if err != nil {
-		return models.Node{}, err
-	}
-	if err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil {
+	if err = UpsertNode(&node); err != nil {
 		return models.Node{}, err
 	}
 	return node, nil
@@ -128,11 +118,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
 	if ingress.Failover && servercfg.Is_EE {
 		node.Failover = true
 	}
-	data, err := json.Marshal(&node)
-	if err != nil {
-		return models.Node{}, err
-	}
-	err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
+	err = UpsertNode(&node)
 	if err != nil {
 		return models.Node{}, err
 	}
@@ -173,12 +159,7 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, bool,
 				node.EgressGatewayRequest.NodeID, node.EgressGatewayRequest.NetID, err))
 		}
 	}
-
-	data, err := json.Marshal(&node)
-	if err != nil {
-		return models.Node{}, false, removedClients, err
-	}
-	err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
+	err = UpsertNode(&node)
 	if err != nil {
 		return models.Node{}, wasFailover, removedClients, err
 	}

+ 90 - 16
logic/hosts.go

@@ -10,6 +10,7 @@ import (
 	"net/http"
 	"sort"
 	"strconv"
+	"sync"
 
 	"github.com/devilcove/httpclient"
 	"github.com/google/uuid"
@@ -20,6 +21,11 @@ import (
 	"golang.org/x/crypto/bcrypt"
 )
 
+var (
+	HostCacheMutex = &sync.RWMutex{}
+	HostsCacheMap  = make(map[string]models.Host)
+)
+
 var (
 	// ErrHostExists error indicating that host exists when trying to create new host
 	ErrHostExists error = errors.New("host already exists")
@@ -27,6 +33,37 @@ var (
 	ErrInvalidHostID error = errors.New("invalid host id")
 )
 
+func GetHostsFromCache() (hostsMap map[string]models.Host) {
+	HostCacheMutex.RLock()
+	hostsMap = HostsCacheMap
+	HostCacheMutex.RUnlock()
+	return
+}
+
+func GetHostFromCache(hostID string) (host models.Host, ok bool) {
+	HostCacheMutex.RLock()
+	host, ok = HostsCacheMap[hostID]
+	HostCacheMutex.RUnlock()
+	return
+}
+
+func StoreHostInCache(h models.Host) {
+	HostCacheMutex.Lock()
+	HostsCacheMap[h.ID.String()] = h
+	HostCacheMutex.Unlock()
+}
+
+func DeleteHostFromCache(hostID string) {
+	HostCacheMutex.Lock()
+	delete(HostsCacheMap, hostID)
+	HostCacheMutex.Unlock()
+}
+func LoadHostsIntoCache(hMap map[string]models.Host) {
+	HostCacheMutex.Lock()
+	HostsCacheMap = hMap
+	HostCacheMutex.Unlock()
+}
+
 const (
 	maxPort = 1<<16 - 1
 	minPort = 1025
@@ -34,17 +71,31 @@ const (
 
 // GetAllHosts - returns all hosts in flat list or error
 func GetAllHosts() ([]models.Host, error) {
-	currHostMap, err := GetHostsMap()
-	if err != nil {
+	currHosts := []models.Host{}
+	hostsMap := GetHostsFromCache()
+	if len(hostsMap) != 0 {
+		for _, host := range hostsMap {
+			currHosts = append(currHosts, host)
+		}
+		return currHosts, nil
+	}
+	records, err := database.FetchRecords(database.HOSTS_TABLE_NAME)
+	if err != nil && !database.IsEmptyRecord(err) {
 		return nil, err
 	}
-	var currentHosts = []models.Host{}
-	for k := range currHostMap {
-		var h = *currHostMap[k]
-		currentHosts = append(currentHosts, h)
+	currHostsMap := make(map[string]models.Host)
+	defer LoadHostsIntoCache(currHostsMap)
+	for k := range records {
+		var h models.Host
+		err = json.Unmarshal([]byte(records[k]), &h)
+		if err != nil {
+			return nil, err
+		}
+		currHosts = append(currHosts, h)
+		currHostsMap[h.ID.String()] = h
 	}
 
-	return currentHosts, nil
+	return currHosts, nil
 }
 
 // GetAllHostsAPI - get's all the hosts in an API usable format
@@ -58,19 +109,24 @@ func GetAllHostsAPI(hosts []models.Host) []models.ApiHost {
 }
 
 // GetHostsMap - gets all the current hosts on machine in a map
-func GetHostsMap() (map[string]*models.Host, error) {
+func GetHostsMap() (map[string]models.Host, error) {
+	hostsMap := GetHostsFromCache()
+	if len(hostsMap) != 0 {
+		return hostsMap, nil
+	}
 	records, err := database.FetchRecords(database.HOSTS_TABLE_NAME)
 	if err != nil && !database.IsEmptyRecord(err) {
 		return nil, err
 	}
-	currHostMap := make(map[string]*models.Host)
+	currHostMap := make(map[string]models.Host)
+	defer LoadHostsIntoCache(currHostMap)
 	for k := range records {
 		var h models.Host
 		err = json.Unmarshal([]byte(records[k]), &h)
 		if err != nil {
 			return nil, err
 		}
-		currHostMap[h.ID.String()] = &h
+		currHostMap[h.ID.String()] = h
 	}
 
 	return currHostMap, nil
@@ -78,6 +134,10 @@ func GetHostsMap() (map[string]*models.Host, error) {
 
 // GetHost - gets a host from db given id
 func GetHost(hostid string) (*models.Host, error) {
+
+	if host, ok := GetHostFromCache(hostid); ok {
+		return &host, nil
+	}
 	record, err := database.FetchRecord(database.HOSTS_TABLE_NAME, hostid)
 	if err != nil {
 		return nil, err
@@ -87,7 +147,7 @@ func GetHost(hostid string) (*models.Host, error) {
 	if err = json.Unmarshal([]byte(record), &h); err != nil {
 		return nil, err
 	}
-
+	StoreHostInCache(h)
 	return &h, nil
 }
 
@@ -215,8 +275,12 @@ func UpsertHost(h *models.Host) error {
 	if err != nil {
 		return err
 	}
-
-	return database.Insert(h.ID.String(), string(data), database.HOSTS_TABLE_NAME)
+	err = database.Insert(h.ID.String(), string(data), database.HOSTS_TABLE_NAME)
+	if err != nil {
+		return err
+	}
+	StoreHostInCache(*h)
+	return nil
 }
 
 // RemoveHost - removes a given host from server
@@ -227,8 +291,12 @@ func RemoveHost(h *models.Host) error {
 	if servercfg.IsUsingTurn() {
 		DeRegisterHostWithTurn(h.ID.String())
 	}
-
-	return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
+	err := database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
+	if err != nil {
+		return err
+	}
+	DeleteHostFromCache(h.ID.String())
+	return nil
 }
 
 // RemoveHostByID - removes a given host by id from server
@@ -236,7 +304,13 @@ func RemoveHostByID(hostID string) error {
 	if servercfg.IsUsingTurn() {
 		DeRegisterHostWithTurn(hostID)
 	}
-	return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
+
+	err := database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
+	if err != nil {
+		return err
+	}
+	DeleteHostFromCache(hostID)
+	return nil
 }
 
 // UpdateHostNetwork - adds/deletes host from a network

+ 2 - 161
logic/networks.go

@@ -115,24 +115,8 @@ func CreateNetwork(network models.Network) (models.Network, error) {
 
 // GetNetworkNonServerNodeCount - get number of network non server nodes
 func GetNetworkNonServerNodeCount(networkName string) (int, error) {
-
-	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
-	count := 0
-	if err != nil && !database.IsEmptyRecord(err) {
-		return count, err
-	}
-	for _, value := range collection {
-		var node models.Node
-		if err = json.Unmarshal([]byte(value), &node); err != nil {
-			return count, err
-		} else {
-			if node.Network == networkName {
-				count++
-			}
-		}
-	}
-
-	return count, nil
+	nodes, err := GetNetworkNodes(networkName)
+	return len(nodes), err
 }
 
 // GetParentNetwork - get parent network
@@ -298,149 +282,6 @@ func UniqueAddress6(networkName string, reverse bool) (net.IP, error) {
 	return add, errors.New("ERROR: No unique IPv6 addresses available. Check network subnet")
 }
 
-// UpdateNetworkLocalAddresses - updates network localaddresses
-func UpdateNetworkLocalAddresses(networkName string) error {
-
-	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
-
-	if err != nil {
-		return err
-	}
-
-	for _, value := range collection {
-
-		var node models.Node
-
-		err := json.Unmarshal([]byte(value), &node)
-		if err != nil {
-			fmt.Println("error in node address assignment!")
-			return err
-		}
-		if node.Network == networkName {
-			var ipaddr net.IP
-			var iperr error
-			ipaddr, iperr = UniqueAddress(networkName, false)
-			if iperr != nil {
-				fmt.Println("error in node  address assignment!")
-				return iperr
-			}
-
-			node.Address.IP = ipaddr
-			newNodeData, err := json.Marshal(&node)
-			if err != nil {
-				logger.Log(1, "error in node  address assignment!")
-				return err
-			}
-			database.Insert(node.ID.String(), string(newNodeData), database.NODES_TABLE_NAME)
-		}
-	}
-
-	return nil
-}
-
-// RemoveNetworkNodeIPv6Addresses - removes network node IPv6 addresses
-func RemoveNetworkNodeIPv6Addresses(networkName string) error {
-
-	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
-	if err != nil {
-		return err
-	}
-
-	for _, value := range collections {
-
-		var node models.Node
-		err := json.Unmarshal([]byte(value), &node)
-		if err != nil {
-			fmt.Println("error in node address assignment!")
-			return err
-		}
-		if node.Network == networkName {
-			node.Address6.IP = nil
-			data, err := json.Marshal(&node)
-			if err != nil {
-				return err
-			}
-			database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
-		}
-	}
-
-	return nil
-}
-
-// UpdateNetworkNodeAddresses - updates network node addresses
-func UpdateNetworkNodeAddresses(networkName string) error {
-
-	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
-	if err != nil {
-		return err
-	}
-
-	for _, value := range collections {
-
-		var node models.Node
-		err := json.Unmarshal([]byte(value), &node)
-		if err != nil {
-			logger.Log(1, "error in node ipv4 address assignment!")
-			return err
-		}
-		if node.Network == networkName {
-			var ipaddr net.IP
-			var iperr error
-			ipaddr, iperr = UniqueAddress(networkName, false)
-			if iperr != nil {
-				logger.Log(1, "error in node ipv4 address assignment!")
-				return iperr
-			}
-
-			node.Address.IP = ipaddr
-			data, err := json.Marshal(&node)
-			if err != nil {
-				return err
-			}
-			database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
-		}
-	}
-
-	return nil
-}
-
-// UpdateNetworkNodeAddresses6 - updates network node addresses
-func UpdateNetworkNodeAddresses6(networkName string) error {
-
-	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
-	if err != nil {
-		return err
-	}
-
-	for _, value := range collections {
-
-		var node models.Node
-		err := json.Unmarshal([]byte(value), &node)
-		if err != nil {
-			logger.Log(1, "error in node ipv6 address assignment!")
-			return err
-		}
-		if node.Network == networkName {
-			var ipaddr net.IP
-			var iperr error
-			ipaddr, iperr = UniqueAddress6(networkName, false)
-			if iperr != nil {
-				logger.Log(1, "error in node ipv6 address assignment!")
-				return iperr
-			}
-
-			node.Address6.IP = ipaddr
-			data, err := json.Marshal(&node)
-			if err != nil {
-				return err
-			}
-			database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
-		}
-	}
-
-	return nil
-}
-
 // IsNetworkNameUnique - checks to see if any other networks have the same name (id)
 func IsNetworkNameUnique(network *models.Network) (bool, error) {
 

+ 76 - 45
logic/nodes.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"net"
 	"sort"
+	"sync"
 	"time"
 
 	validator "github.com/go-playground/validator/v10"
@@ -17,11 +18,51 @@ import (
 	"github.com/gravitl/netmaker/logic/pro"
 	"github.com/gravitl/netmaker/logic/pro/proacls"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/validation"
 )
 
+var (
+	NodeCacheMutex = &sync.RWMutex{}
+	NodesCacheMap  = make(map[string]models.Node)
+)
+
+func GetNodeFromCache(nodeID string) (node models.Node, ok bool) {
+	NodeCacheMutex.RLock()
+	node, ok = NodesCacheMap[nodeID]
+	NodeCacheMutex.RUnlock()
+	return
+}
+func GetNodesFromCache() (nMap map[string]models.Node) {
+	NodeCacheMutex.RLock()
+	nMap = NodesCacheMap
+	NodeCacheMutex.RUnlock()
+	return
+}
+
+func DeleteNodeFromCache(nodeID string) {
+	NodeCacheMutex.Lock()
+	delete(NodesCacheMap, nodeID)
+	NodeCacheMutex.Unlock()
+}
+
+func StoreNodeInCache(node models.Node) {
+	NodeCacheMutex.Lock()
+	NodesCacheMap[node.ID.String()] = node
+	NodeCacheMutex.Unlock()
+}
+
+func LoadNodesIntoCache(nMap map[string]models.Node) {
+	NodeCacheMutex.Lock()
+	NodesCacheMap = nMap
+	NodeCacheMutex.Unlock()
+}
+func ClearNodeCache() {
+	NodeCacheMutex.Lock()
+	NodesCacheMap = make(map[string]models.Node)
+	NodeCacheMutex.Unlock()
+}
+
 const (
 	// RELAY_NODE_ERR - error to return if relay node is unfound
 	RELAY_NODE_ERR = "could not find relay for node"
@@ -72,7 +113,12 @@ func UpdateNodeCheckin(node *models.Node) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
+	err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
+	if err != nil {
+		return err
+	}
+	StoreNodeInCache(*node)
+	return nil
 }
 
 // UpsertNode - updates node in the DB
@@ -82,7 +128,12 @@ func UpsertNode(newNode *models.Node) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
+	err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
+	if err != nil {
+		return err
+	}
+	StoreNodeInCache(*newNode)
+	return nil
 }
 
 // UpdateNode - takes a node and updates another node with it's values
@@ -114,7 +165,12 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
 		if data, err := json.Marshal(newNode); err != nil {
 			return err
 		} else {
-			return database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
+			err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
+			if err != nil {
+				return err
+			}
+			StoreNodeInCache(*newNode)
+			return nil
 		}
 	}
 
@@ -172,6 +228,7 @@ func deleteNodeByID(node *models.Node) error {
 			return err
 		}
 	}
+	DeleteNodeFromCache(node.ID.String())
 	if servercfg.IsDNSMode() {
 		SetDNS()
 	}
@@ -237,7 +294,15 @@ func IsFailoverPresent(network string) bool {
 // GetAllNodes - returns all nodes in the DB
 func GetAllNodes() ([]models.Node, error) {
 	var nodes []models.Node
-
+	nodesMap := GetNodesFromCache()
+	if len(nodesMap) != 0 {
+		for _, node := range nodesMap {
+			nodes = append(nodes, node)
+		}
+		return nodes, nil
+	}
+	nodesMap = make(map[string]models.Node)
+	defer LoadNodesIntoCache(nodesMap)
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 	if err != nil {
 		if database.IsEmptyRecord(err) {
@@ -255,6 +320,7 @@ func GetAllNodes() ([]models.Node, error) {
 		}
 		// add node to our array
 		nodes = append(nodes, node)
+		nodesMap[node.ID.String()] = node
 	}
 
 	return nodes, nil
@@ -309,46 +375,10 @@ func GetRecordKey(id string, network string) (string, error) {
 	return id + "###" + network, nil
 }
 
-// GetNodesByAddress - gets a node by mac address
-func GetNodesByAddress(network string, addresses []string) ([]models.Node, error) {
-	var nodes []models.Node
-	allnodes, err := GetAllNodes()
-	if err != nil {
-		return []models.Node{}, err
-	}
-	for _, node := range allnodes {
-		if node.Network == network && ncutils.StringSliceContains(addresses, node.Address.String()) {
-			nodes = append(nodes, node)
-		}
-	}
-	return nodes, nil
-}
-
-// GetDeletedNodeByMacAddress - get a deleted node
-func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node, error) {
-
-	var node models.Node
-
-	key, err := GetRecordKey(macaddress, network)
-	if err != nil {
-		return node, err
-	}
-
-	record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
-	if err != nil {
-		return models.Node{}, err
-	}
-
-	if err = json.Unmarshal([]byte(record), &node); err != nil {
-		return models.Node{}, err
-	}
-
-	SetNodeDefaults(&node)
-
-	return node, nil
-}
-
 func GetNodeByID(uuid string) (models.Node, error) {
+	if node, ok := GetNodeFromCache(uuid); ok {
+		return node, nil
+	}
 	var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid)
 	if err != nil {
 		return models.Node{}, err
@@ -357,6 +387,7 @@ func GetNodeByID(uuid string) (models.Node, error) {
 	if err = json.Unmarshal([]byte(record), &node); err != nil {
 		return models.Node{}, err
 	}
+	StoreNodeInCache(node)
 	return node, nil
 }
 
@@ -506,7 +537,7 @@ func createNode(node *models.Node) error {
 	if err != nil {
 		return err
 	}
-
+	StoreNodeInCache(*node)
 	_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), defaultACLVal)
 	if err != nil {
 		logger.Log(1, "failed to create node ACL for node,", node.ID.String(), "err:", err.Error())

+ 3 - 28
logic/relay.go

@@ -1,12 +1,10 @@
 package logic
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"net"
 
-	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
 )
@@ -33,25 +31,11 @@ func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error)
 	node.IsRelay = true
 	node.RelayedNodes = relay.RelayedNodes
 	node.SetLastModified()
-	nodeData, err := json.Marshal(&node)
+	err = UpsertNode(&node)
 	if err != nil {
 		return returnnodes, node, err
 	}
-	if err = database.Insert(node.ID.String(), string(nodeData), database.NODES_TABLE_NAME); err != nil {
-		return returnnodes, models.Node{}, err
-	}
 	returnnodes = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes)
-	for _, relayedNode := range returnnodes {
-		data, err := json.Marshal(&relayedNode)
-		if err != nil {
-			logger.Log(0, "marshalling relayed node", err.Error())
-			continue
-		}
-		if err := database.Insert(relayedNode.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil {
-			logger.Log(0, "inserting relayed node", err.Error())
-			continue
-		}
-	}
 	return returnnodes, node, nil
 }
 
@@ -71,12 +55,7 @@ func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.N
 			node.RelayedBy = ""
 		}
 		node.SetLastModified()
-		data, err := json.Marshal(&node)
-		if err != nil {
-			logger.Log(0, "setRelayedNodes.Marshal", err.Error())
-			continue
-		}
-		if err := database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil {
+		if err := UpsertNode(&node); err != nil {
 			logger.Log(0, "setRelayedNodes.Insert", err.Error())
 			continue
 		}
@@ -145,11 +124,7 @@ func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
 	node.IsRelay = false
 	node.RelayedNodes = []string{}
 	node.SetLastModified()
-	data, err := json.Marshal(&node)
-	if err != nil {
-		return returnnodes, models.Node{}, err
-	}
-	if err = database.Insert(nodeid, string(data), database.NODES_TABLE_NAME); err != nil {
+	if err = UpsertNode(&node); err != nil {
 		return returnnodes, models.Node{}, err
 	}
 	return returnnodes, node, nil