-
Notifications
You must be signed in to change notification settings - Fork 0
/
herald.go
170 lines (151 loc) · 3.8 KB
/
herald.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Copyright © 2015 Jason Smith <jasonrichardsmith@gmail.com>.
//
// Use of this source code is governed by the LGPL-3
// license that can be found in the LICENSE file.
package herald
import (
"flag"
"fmt"
"os"
"github.com/duckbunny/service"
)
// PoolTypes are a collection of Pool Interfaces identified by strings
// associated with a pooling mechanism.
var PoolTypes map[string]Pool = make(map[string]Pool)
// DeclarationTypes are a collection of Declaration Interfaces identified by
// strings associated with a declaration mechanism.
var DeclarationTypes map[string]Declaration = make(map[string]Declaration)
// Flags to be parsed for setting pool and declaration interfaces.
var heraldPool string
var heraldDeclare string
var heraldBoth string
func init() {
flag.StringVar(
&heraldPool,
"herald-p",
os.Getenv("HERALD_POOL"),
"Herald to microservice pool.")
flag.StringVar(
&heraldDeclare,
"herald-d",
os.Getenv("HERALD_DECLARE"),
"Herald to microservice declaration.")
flag.StringVar(
&heraldBoth,
"herald",
os.Getenv("HERALD"),
"Herald to handle both declaration and pooling.")
}
// Herald is a wrapper structure of the pooling and declaration interfaces that will be implemented
// based on flags or environement variables.
type Herald struct {
Pool
Declaration
Service *service.Service
}
// Set declared pool and declaration for this instance.
func setFlagEnv() {
if !flag.Parsed() {
flag.Parse()
}
if heraldPool == "" {
heraldPool = heraldBoth
}
if heraldDeclare == "" {
heraldDeclare = heraldBoth
}
return
}
// Helper function to build herald for the currently running microservice.
func This() (*Herald, error) {
setFlagEnv()
h := &Herald{}
if heraldPool != "" {
if _, ok := PoolTypes[heraldPool]; !ok {
err := fmt.Errorf(
"Attempt to utilize unrecognized Pooling mechanism %v",
heraldPool)
return h, err
}
h.Pool = PoolTypes[heraldPool]
}
if heraldDeclare != "" {
if _, ok := DeclarationTypes[heraldDeclare]; !ok {
err := fmt.Errorf(
"Attempt to utilize unrecognized Declaration mechanism %v",
heraldPool)
return h, err
}
h.Declaration = DeclarationTypes[heraldDeclare]
}
s, err := service.This()
h.Service = s
return h, err
}
// Wrapper to init Pool and Declare if they are set. This allows them to
// consume flags if necessary.
func (h *Herald) Init() error {
if h.Pool != nil {
err := h.Pool.Init()
if err != nil {
return err
}
}
if h.Declaration != nil {
if h.Pool != nil {
if h.Declaration.Init() != h.Pool.Init() {
return h.Declaration.Init()
}
} else {
return h.Declaration.Init()
}
}
return nil
}
// Add this service to pool of microservices.
func (h *Herald) StartPool() error {
if h.Pool != nil {
return h.Pool.Start(h.Service)
}
return nil
}
// Remove this service from pool of microservices.
func (h *Herald) StopPool() error {
if h.Pool != nil {
return h.Pool.Stop(h.Service)
}
return nil
}
// Declare this microservice definition.
func (h *Herald) Declare() error {
if h.Declaration != nil {
return h.Declaration.Declare(h.Service)
}
return nil
}
// Get a foreign microservice definition.
func (h *Herald) GetService(s *service.Service) error {
return h.Declaration.GetService(s)
}
// Pool defines an interface that will add and remove a microservice
// to a pool of microservices.
type Pool interface {
Start(*service.Service) error
Stop(*service.Service) error
Init() error
}
// Add a single pool.
func AddPool(key string, p Pool) {
PoolTypes[key] = p
}
// Declaration defines an interface that will broadcast the microservice
// definition, for other services to digest.
type Declaration interface {
Declare(*service.Service) error
GetService(*service.Service) error
Init() error
}
// Add a single declaration.
func AddDeclaration(key string, d Declaration) {
DeclarationTypes[key] = d
}