forked from dropbox/llama
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
94 lines (83 loc) · 2.58 KB
/
util.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package llama
import (
"log"
"net"
"os"
"syscall"
"time"
"github.com/satori/go.uuid"
"golang.org/x/sys/unix"
)
const (
// Listens on any addr to an automatically assigned port number
DefaultAddrStr = "0.0.0.0:0"
DefaultTos = byte(0)
DefaultRcvBuff = 2097600 // 2MiB
DefaultReadTimeout = 200 * time.Millisecond
DefaultCacheTimeout = 2 * time.Second
DefaultCacheCleanRate = 5 * time.Second
ExpireNow = time.Nanosecond
)
// NewID returns 10 bytes of a new UUID4 as a string.
//
// This should be unique enough for short-lived cases, but as it's only a
// partial UUID4.
func NewID() string {
fullUUID := uuid.NewV4()
last10 := fullUUID[len(fullUUID)-10:]
return string(last10)
}
// IDTo10Bytes converts a string to a 10 byte array.
func IDToBytes(id string) [10]byte {
var arr [10]byte
copy(arr[:], id)
return arr
}
// NowUint64 returns the current time in nanoseconds as a uint64.
func NowUint64() uint64 {
return uint64(time.Now().UnixNano())
}
// FileCloseHandler will close an open File and handle the resulting error.
func FileCloseHandler(f *os.File) {
// NOTE: This is required, specifically for sockets/net.Conn because it
// would appear that calls like setting the ToS value or enabling
// timestamps cause this to go into a blocking state. Which then disables
// the functionality of SetReadDeadline, making reads block infinitely.
err := unix.SetNonblock(int(f.Fd()), true)
HandleError(err)
err = f.Close()
HandleError(err)
}
func HandleError(err error) {
HandleFatalError(err)
}
func HandleMinorError(err error) {
if err != nil {
// Could have this logging to Sentry
//log.Printf("ERROR TYPE: %#v\n", err)
// NOTE(dmar): Very annoying downside of this separate method
// approach is that this is the line number which
// appears in logs. Not the actual source.
log.Println("ERROR: ", err)
}
}
// HandleError receives an error, then logs and exits if not nil.
// TODO(dmar): Create additional simple handlers for non-fatal issues
func HandleFatalError(err error) {
if err != nil {
// Could have this logging to Sentry
//log.Printf("ERROR TYPE: %#v\n", err)
log.Fatal("ERROR: ", err)
}
}
// SetRecvBufferSize sets the size of the receive buffer for the conn to the
// provided size in bytes.
// TODO(dmar): Validate and replace this with a simple call to conn.SetReadBuffer
func SetRecvBufferSize(conn *net.UDPConn, size int) {
file, err := conn.File()
defer FileCloseHandler(file)
HandleError(err)
err = syscall.SetsockoptInt(int(file.Fd()), syscall.SOL_SOCKET,
syscall.SO_RCVBUF, size)
HandleError(err)
}