-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.go
124 lines (101 loc) · 3.1 KB
/
main.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"fmt"
"reflect"
"time"
"github.com/ninjasphere/go-ninja/api"
"github.com/ninjasphere/go-ninja/config"
"github.com/ninjasphere/go-ninja/logger"
"github.com/ninjasphere/go-ninja/rpc"
"github.com/ninjasphere/go-ninja/support"
"github.com/ninjasphere/inject"
"github.com/ninjasphere/redigo/redis"
"github.com/ninjasphere/sphere-go-homecloud/homecloud"
"github.com/ninjasphere/sphere-go-homecloud/models"
"github.com/ninjasphere/sphere-go-homecloud/rest"
"github.com/ninjasphere/sphere-go-homecloud/state"
)
var log = logger.GetLogger("HomeCloud")
type postConstructable interface {
PostConstruct() error
}
const shortForm = "2006-Jan-02"
var epoch, _ = time.Parse(shortForm, "2014-Dec-01")
func waitForNTP() {
for {
if time.Now().After(epoch) {
break
}
time.Sleep(time.Second * 2)
}
}
func main() {
log.Infof("Welcome home, Ninja.")
if config.Bool(true, "homecloud.waitForNTP") {
waitForNTP()
}
// The MQTT Connection
conn, err := ninja.Connect("sphere-go-homecloud")
if err != nil {
log.Fatalf("Failed to connect to sphere: %s", err)
}
// An MQTT Connection used for outbound syncing connections
syncConn := &models.SyncConnection{}
syncConn.Conn, err = ninja.Connect("sphere-go-homecloud.sync")
if err != nil {
log.Fatalf("Failed to connect to sphere (sync): %s", err)
}
// Our redis pool
pool := &redis.Pool{
MaxIdle: config.MustInt("homecloud.redis.maxIdle"),
MaxActive: config.Int(10, "homecloud.redis.maxActive"),
IdleTimeout: config.MustDuration("homecloud.redis.idleTimeout"),
Wait: true,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", config.String("", "homecloud.redis.host"), config.MustInt("homecloud.redis.port")))
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
}
// Not pretty.
rpc.RedisPool = pool
// Wait until we connect to redis successfully.
for {
c := pool.Get()
if c.Err() == nil {
c.Close()
break
}
log.Warningf("Failed to connect to redis: %s", c.Err())
time.Sleep(time.Second)
}
// Build the object graph using dependency injection
injectables := []interface{}{}
injectables = append(injectables, pool, conn, syncConn)
injectables = append(injectables, &homecloud.HomeCloud{}, &homecloud.TimeSeriesManager{}, &homecloud.DeviceManager{}, &homecloud.ModuleManager{})
injectables = append(injectables, state.NewStateManager())
injectables = append(injectables, &rest.RestServer{})
injectables = append(injectables, models.GetInjectables()...)
err = inject.Populate(injectables...)
if err != nil {
log.Fatalf("Failed to construct the object graph: %s", err)
}
// Run PostConstruct on any objects that have it
for _, node := range injectables {
if n, ok := node.(postConstructable); ok {
go func(c postConstructable) {
if err := c.PostConstruct(); err != nil {
log.Fatalf("Failed PostConstruct on object %s: %s", reflect.TypeOf(c).String(), err)
}
}(n)
}
}
support.WaitUntilSignal()
// So long, and thanks for all the fish.
}