~whereswaldon/sprout-go

82082f28f57efe7cc0463756a54d94ec6b9a3dd1 — Chris Waldon 9 months ago eb08eb3 relay
Implement list verb in example relay
4 files changed, 107 insertions(+), 59 deletions(-)

M cmd/relay/message_store.go
M cmd/relay/worker.go
M go.mod
M go.sum
M cmd/relay/message_store.go => cmd/relay/message_store.go +43 -1
@@ 1,7 1,7 @@
package main

import (
	"git.sr.ht/~whereswaldon/forest-go"
	forest "git.sr.ht/~whereswaldon/forest-go"
	"git.sr.ht/~whereswaldon/forest-go/fields"
)



@@ 67,6 67,48 @@ func (m *MessageStore) Get(id *fields.QualifiedHash) (node forest.Node, present 
	return
}

func (m *MessageStore) GetIdentity(id *fields.QualifiedHash) (node forest.Node, present bool, err error) {
	m.requests <- func() {
		node, present, err = m.store.GetIdentity(id)
	}
	return
}

func (m *MessageStore) GetCommunity(id *fields.QualifiedHash) (node forest.Node, present bool, err error) {
	m.requests <- func() {
		node, present, err = m.store.GetCommunity(id)
	}
	return
}

func (m *MessageStore) GetConversation(communityID, conversationID *fields.QualifiedHash) (node forest.Node, present bool, err error) {
	m.requests <- func() {
		node, present, err = m.store.GetConversation(communityID, conversationID)
	}
	return
}

func (m *MessageStore) GetReply(communityID, conversationID, replyID *fields.QualifiedHash) (node forest.Node, present bool, err error) {
	m.requests <- func() {
		node, present, err = m.store.GetReply(communityID, conversationID, replyID)
	}
	return
}

func (m *MessageStore) Children(parent *fields.QualifiedHash) (children []*fields.QualifiedHash, err error) {
	m.requests <- func() {
		children, err = m.store.Children(parent)
	}
	return
}

func (m *MessageStore) Recent(nodeType fields.NodeType, quantity int) (recentNodes []forest.Node, err error) {
	m.requests <- func() {
		recentNodes, err = m.store.Recent(nodeType, quantity)
	}
	return
}

func (m *MessageStore) Add(node forest.Node, addedByID int) (err error) {
	m.requests <- func() {
		err = m.store.Add(node)

M cmd/relay/worker.go => cmd/relay/worker.go +60 -56
@@ 5,7 5,7 @@ import (
	"log"
	"net"

	"git.sr.ht/~whereswaldon/forest-go"
	forest "git.sr.ht/~whereswaldon/forest-go"
	"git.sr.ht/~whereswaldon/forest-go/fields"
	sprout "git.sr.ht/~whereswaldon/sprout-go"
)


@@ 72,9 72,9 @@ func (c *Worker) HandleNewNode(node forest.Node) {
	log.Printf("Got new node: %v", node)
	switch n := node.(type) {
	case *forest.Identity:
    	// shouldn't just announce random user ids unsolicted
		// shouldn't just announce random user ids unsolicted
	case *forest.Community:
    	// maybe we should announce new communities?
		// maybe we should announce new communities?
	case *forest.Reply:
		if c.IsSubscribed(&n.CommunityID) {
			if _, err := c.SendAnnounce([]forest.Node{n}); err != nil {


@@ 108,7 108,11 @@ func (c *Worker) OnVersion(s *sprout.Conn, messageID sprout.MessageID, major, mi

func (c *Worker) OnList(s *sprout.Conn, messageID sprout.MessageID, nodeType fields.NodeType, quantity int) error {
	// requires better iteration on Store types
	return nil
	recentNodes, err := c.MessageStore.Recent(nodeType, quantity)
	if err != nil {
		return fmt.Errorf("error listing recent nodes of type %d: %w", nodeType, err)
	}
	return s.SendResponse(messageID, recentNodes)
}

func (c *Worker) OnQuery(s *sprout.Conn, messageID sprout.MessageID, nodeIds []*fields.QualifiedHash) error {


@@ 125,65 129,65 @@ func (c *Worker) OnQuery(s *sprout.Conn, messageID sprout.MessageID, nodeIds []*
}

func (c *Worker) OnAncestry(s *sprout.Conn, messageID sprout.MessageID, nodeID *fields.QualifiedHash, levels int) error {
    ancestors := make([]forest.Node,0,1024)
    currentNode, known, err := c.MessageStore.Get(nodeID)
    if err != nil {
        return fmt.Errorf("failed looking for node %v: %w", nodeID, err)
    } else if !known {
        return fmt.Errorf("asked for ancestry of unknown node %v", nodeID)
    }
    for i := 0; i < levels; i++ {
        if currentNode.ParentID().Equals(fields.NullHash()) {
            // no parent, we're done
            break
        }
        parentNode, known, err := c.MessageStore.Get(currentNode.ParentID())
        if err != nil {
            return fmt.Errorf("couldn't look up node with id %v (parent of %v): %w", currentNode.ParentID(), currentNode.ID(), err)
        } else if !known {
            // we don't know any more ancestry, so we're done
            break
        }
        ancestors=append(ancestors,parentNode)
        currentNode = parentNode
    }
	ancestors := make([]forest.Node, 0, 1024)
	currentNode, known, err := c.MessageStore.Get(nodeID)
	if err != nil {
		return fmt.Errorf("failed looking for node %v: %w", nodeID, err)
	} else if !known {
		return fmt.Errorf("asked for ancestry of unknown node %v", nodeID)
	}
	for i := 0; i < levels; i++ {
		if currentNode.ParentID().Equals(fields.NullHash()) {
			// no parent, we're done
			break
		}
		parentNode, known, err := c.MessageStore.Get(currentNode.ParentID())
		if err != nil {
			return fmt.Errorf("couldn't look up node with id %v (parent of %v): %w", currentNode.ParentID(), currentNode.ID(), err)
		} else if !known {
			// we don't know any more ancestry, so we're done
			break
		}
		ancestors = append(ancestors, parentNode)
		currentNode = parentNode
	}
	return s.SendResponse(messageID, ancestors)
}

func (c *Worker) OnLeavesOf(s *sprout.Conn, messageID sprout.MessageID, nodeID *fields.QualifiedHash, quantity int) error {
    descendants := make([]*fields.QualifiedHash,0,1024)
    descendants = append(descendants, nodeID)
    leaves := make([]forest.Node,0,1024)
    for len(descendants) > 0 {
        children, err := c.MessageStore.store.Children(descendants[0])
        if err != nil {
        return fmt.Errorf("failed fetching children for %v: %w", descendants[0], err)
        }
        if len(children) == 0 {
            node, has, err := c.MessageStore.Get(descendants[0])
            if err != nil {
                return fmt.Errorf("failed fetching node for %v: %w", descendants[0], err)
            } else if !has {
                // not sure what to do here
                continue
            }
            leaves = append(leaves, node)
            continue
        }
        descendants = descendants[1:]
        for _, child := range children {
            descendants = append(descendants, child)
        }
    }
    return s.SendResponse(messageID, leaves)
	descendants := make([]*fields.QualifiedHash, 0, 1024)
	descendants = append(descendants, nodeID)
	leaves := make([]forest.Node, 0, 1024)
	for len(descendants) > 0 {
		children, err := c.MessageStore.store.Children(descendants[0])
		if err != nil {
			return fmt.Errorf("failed fetching children for %v: %w", descendants[0], err)
		}
		if len(children) == 0 {
			node, has, err := c.MessageStore.Get(descendants[0])
			if err != nil {
				return fmt.Errorf("failed fetching node for %v: %w", descendants[0], err)
			} else if !has {
				// not sure what to do here
				continue
			}
			leaves = append(leaves, node)
			continue
		}
		descendants = descendants[1:]
		for _, child := range children {
			descendants = append(descendants, child)
		}
	}
	return s.SendResponse(messageID, leaves)
}

func (c *Worker) OnResponse(s *sprout.Conn, target sprout.MessageID, nodes []forest.Node) error {
    for _, node := range nodes {
        if err := c.MessageStore.Add(node,c.subscriptionID); err != nil {
            return fmt.Errorf("failed to add node to store: %w", err)
        }
    }
	for _, node := range nodes {
		if err := c.MessageStore.Add(node, c.subscriptionID); err != nil {
			return fmt.Errorf("failed to add node to store: %w", err)
		}
	}
	return nil
}


M go.mod => go.mod +2 -2
@@ 1,5 1,5 @@
module git.sr.ht/~whereswaldon/sprout-go

go 1.12
go 1.13

require git.sr.ht/~whereswaldon/forest-go v0.0.0-20191005232937-c236655ede0e
require git.sr.ht/~whereswaldon/forest-go v0.0.0-20191010022817-d91d674e5b16

M go.sum => go.sum +2 -0
@@ 6,6 6,8 @@ git.sr.ht/~whereswaldon/forest-go v0.0.0-20190914003741-060f85264c6b h1:hrpdlY/6
git.sr.ht/~whereswaldon/forest-go v0.0.0-20190914003741-060f85264c6b/go.mod h1:7cXupoNBCJSMi+x/cFvyxDfpAE9p0Zy0/s2/zsboB8o=
git.sr.ht/~whereswaldon/forest-go v0.0.0-20191005232937-c236655ede0e h1:5f5RkI8aMSLdGq1QY04HvoLuSmcxtzVBgoDoGg90Jb4=
git.sr.ht/~whereswaldon/forest-go v0.0.0-20191005232937-c236655ede0e/go.mod h1:7cXupoNBCJSMi+x/cFvyxDfpAE9p0Zy0/s2/zsboB8o=
git.sr.ht/~whereswaldon/forest-go v0.0.0-20191010022817-d91d674e5b16 h1:n9g0rj4RDx7rnjjmVpfufmSyPC9eABKtaVdXNEbM1oY=
git.sr.ht/~whereswaldon/forest-go v0.0.0-20191010022817-d91d674e5b16/go.mod h1:7cXupoNBCJSMi+x/cFvyxDfpAE9p0Zy0/s2/zsboB8o=
github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21/go.mod h1:NtXa9WwQsukMHZpjNakTTz0LArxvGYdPA9CjIcUSZ6s=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=