forked from ortuman/jackal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
component.go
97 lines (86 loc) · 2.22 KB
/
component.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
/*
* Copyright (c) 2018 Miguel Ángel Ortuño.
* See the LICENSE file for more information.
*/
package component
import (
"context"
"fmt"
"github.com/ortuman/jackal/log"
"github.com/ortuman/jackal/module/xep0030"
"github.com/ortuman/jackal/stream"
"github.com/ortuman/jackal/xmpp"
)
// Component represents a generic component interface.
type Component interface {
Host() string
ProcessStanza(stanza xmpp.Stanza, stm stream.C2S)
}
// Components represents a set of preconfigured components.
type Components struct {
comps map[string]Component
shutdownChs []chan<- chan bool
}
// New returns a set of components derived from a concrete configuration.
func New(config *Config, discoInfo *xep0030.DiscoInfo) *Components {
comps := &Components{
comps: make(map[string]Component),
}
cs, shutdownChs := loadComponents(config, discoInfo)
for _, c := range cs {
host := c.Host()
if _, ok := comps.comps[host]; ok {
log.Fatal(fmt.Errorf("component host name conflict: %s", host))
}
comps.comps[host] = c
}
comps.shutdownChs = shutdownChs
return comps
}
// Get returns a specific component associated to host name.
func (cs *Components) Get(host string) Component {
return cs.comps[host]
}
// GetAll returns all initialized components.
func (cs *Components) GetAll() []Component {
var ret []Component
for _, comp := range cs.comps {
ret = append(ret, comp)
}
return ret
}
func (cs *Components) Shutdown(ctx context.Context) error {
select {
case <-cs.shutdown():
return nil
case <-ctx.Done():
return ctx.Err()
}
}
func (cs *Components) shutdown() <-chan bool {
c := make(chan bool)
go func() {
// shutdown components in reverse order
for i := len(cs.shutdownChs) - 1; i >= 0; i-- {
shutdownCh := cs.shutdownChs[i]
wc := make(chan bool, 1)
shutdownCh <- wc
<-wc
}
close(c)
}()
return c
}
func loadComponents(_ *Config, _ *xep0030.DiscoInfo) ([]Component, []chan<- chan bool) {
var comps []Component
var shutdownChs []chan<- chan bool
/*
discoInfo := module.Modules().DiscoInfo
if cfg.HttpUpload != nil {
comp, shutdownCh := httpupload.New(cfg.HttpUpload, discoInfo)
comps = append(comps, comp)
shutdownChs = append(shutdownChs, shutdownCh)
}
*/
return comps, shutdownChs
}