-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhaystack.go
76 lines (65 loc) · 2.12 KB
/
haystack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package haystack
import (
"bufio"
"errors"
"net"
"github.com/nomasters/haystack/needle"
)
// some more thought needs to go into this, we most likely need:
// - a connection pool, this connection pool should "self heal", allow for timeouts, and support the pooling feature to be well behaved
// - logger primitives, this most likely needs to carry over from server implementation
// - a way to process responses in a scalable way. This might be best to keep a local storage buffer keyed by the hash. more thought needs to go into this.
var (
// ErrTimestampExceedsThreshold is an error returned with the timestamp exceeds the acceptable threshold
ErrTimestampExceedsThreshold = errors.New("Timestamp exceeds threshold")
)
type options struct {
}
type option func(*options)
// Client represents a haystack client with a UDP connection
type Client struct {
raddr string
conn net.Conn
}
// Close implements the UDPConn.Close() method
func (c *Client) Close() error {
return c.conn.Close()
}
// Set takes a needle and returns
func (c *Client) Set(n *needle.Needle) error {
conn, err := net.Dial("udp", c.raddr)
if err != nil {
return err
}
defer conn.Close()
_, err = conn.Write(n.Bytes())
return err
}
// Get takes a needle hash and returns a Needle
func (c *Client) Get(h *needle.Hash) (*needle.Needle, error) {
p := make([]byte, needle.NeedleLength)
conn, err := net.Dial("udp", c.raddr)
if err != nil {
return nil, err
}
defer conn.Close()
conn.Write(h[:])
if _, err := bufio.NewReader(conn).Read(p); err != nil {
return nil, err
}
// TODO: Because this is connectionless, we should create a readbuffer for conn that writes to client storage interface
// and then read from that client storage interface. This will make reading async calls that go really fast... faster.
return needle.FromBytes(p)
}
// NewClient creates a new haystack client. It requires an address
// but can also take an arbitrary number of options
func NewClient(address string, opts ...option) (*Client, error) {
c := new(Client)
c.raddr = address
conn, err := net.Dial("udp", address)
if err != nil {
return c, err
}
c.conn = conn
return c, nil
}