1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-06-10 18:00:43 +00:00

generalized event handler

This commit is contained in:
Darien Raymond 2017-11-28 23:41:20 +01:00
parent 973ce07db9
commit fd8db49dc9
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
16 changed files with 80 additions and 32 deletions

View File

@ -39,7 +39,7 @@ func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*Defa
return nil, newError("no space in context")
}
d := &DefaultDispatcher{}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
if d.ohm == nil {
return newError("OutboundHandlerManager is not found in the space")

View File

@ -52,7 +52,7 @@ func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, erro
servers: make([]NameServer, len(config.NameServers)),
hosts: config.GetInternalHosts(),
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
disp := dispatcher.FromSpace(space)
if disp == nil {
return newError("dispatcher is not found in the space")

View File

@ -37,6 +37,7 @@ func global() policy.Policy {
}
}
// GetPolicy implements policy.Manager.
func (m *Instance) GetPolicy(level uint32) policy.Policy {
if p, ok := m.levels[level]; ok {
return *p
@ -44,13 +45,16 @@ func (m *Instance) GetPolicy(level uint32) policy.Policy {
return global()
}
// Start implements app.Application.Start().
func (m *Instance) Start() error {
return nil
}
// Close implements app.Application.Close().
func (m *Instance) Close() {
}
// Interface implement app.Application.Interface().
func (m *Instance) Interface() interface{} {
return (*policy.Manager)(nil)
}

View File

@ -274,7 +274,7 @@ type Server struct {
func NewServer(ctx context.Context) *Server {
s := &Server{}
space := app.SpaceFromContext(ctx)
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
d := dispatcher.FromSpace(space)
if d == nil {
return newError("no dispatcher in space")

View File

@ -33,7 +33,7 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
if space == nil {
return nil, newError("no space in context")
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
ohm := proxyman.OutboundHandlerManagerFromSpace(space)
if ohm == nil {
return newError("no OutboundManager in space")

View File

@ -33,7 +33,7 @@ func NewRouter(ctx context.Context, config *Config) (*Router, error) {
rules: make([]Rule, len(config.Rule)),
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
for idx, rule := range config.Rule {
r.rules[idx].Tag = rule.Tag
cond, err := rule.BuildCondition()

View File

@ -5,6 +5,7 @@ import (
"reflect"
"v2ray.com/core/common"
"v2ray.com/core/common/event"
)
type Application interface {
@ -13,8 +14,6 @@ type Application interface {
Close()
}
type InitializationCallback func() error
func CreateAppFromConfig(ctx context.Context, config interface{}) (Application, error) {
application, err := common.CreateObject(ctx, config)
if err != nil {
@ -29,46 +28,45 @@ func CreateAppFromConfig(ctx context.Context, config interface{}) (Application,
}
// A Space contains all apps that may be available in a V2Ray runtime.
// Caller must check the availability of an app by calling HasXXX before getting its instance.
type Space interface {
event.Registry
GetApplication(appInterface interface{}) Application
AddApplication(application Application) error
Initialize() error
OnInitialize(InitializationCallback)
Start() error
Close()
}
const (
SpaceInitializing event.Event = iota
)
type spaceImpl struct {
initialized bool
event.Listener
cache map[reflect.Type]Application
appInit []InitializationCallback
initialized bool
}
func NewSpace() Space {
return &spaceImpl{
cache: make(map[reflect.Type]Application),
appInit: make([]InitializationCallback, 0, 32),
cache: make(map[reflect.Type]Application),
}
}
func (s *spaceImpl) OnInitialize(f InitializationCallback) {
if s.initialized {
f()
} else {
s.appInit = append(s.appInit, f)
func (s *spaceImpl) On(e event.Event, h event.Handler) {
if e == SpaceInitializing && s.initialized {
_ = h(nil) // Ignore error
return
}
s.Listener.On(e, h)
}
func (s *spaceImpl) Initialize() error {
for _, f := range s.appInit {
if err := f(); err != nil {
return err
}
if s.initialized {
return nil
}
s.appInit = nil
s.initialized = true
return nil
return s.Fire(SpaceInitializing, nil)
}
func (s *spaceImpl) GetApplication(appInterface interface{}) Application {

46
common/event/event.go Normal file
View File

@ -0,0 +1,46 @@
package event
import "sync"
type Event uint16
type Handler func(data interface{}) error
type Registry interface {
On(Event, Handler)
}
type Listener struct {
sync.RWMutex
events map[Event][]Handler
}
func (l *Listener) On(e Event, h Handler) {
l.Lock()
defer l.Unlock()
if l.events == nil {
l.events = make(map[Event][]Handler)
}
handlers := l.events[e]
handlers = append(handlers, h)
l.events[e] = handlers
}
func (l *Listener) Fire(e Event, data interface{}) error {
l.RLock()
defer l.RUnlock()
if l.events == nil {
return nil
}
for _, h := range l.events[e] {
if err := h(data); err != nil {
return err
}
}
return nil
}

View File

@ -38,7 +38,7 @@ func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
address: config.GetPredefinedAddress(),
port: net.Port(config.Port),
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")

View File

@ -40,7 +40,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
timeout: config.Timeout,
destOverride: config.DestinationOverride,
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
if config.DomainStrategy == Config_USE_IP {
f.dns = dns.FromSpace(space)
if f.dns == nil {

View File

@ -37,7 +37,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{
config: config,
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")

View File

@ -39,7 +39,7 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
if space == nil {
return nil, newError("Space not found.")
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")

View File

@ -47,7 +47,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
account: account,
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")

View File

@ -34,7 +34,7 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
s := &Server{
config: config,
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy not found in space.")

View File

@ -103,7 +103,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
sessionHistory: encoding.NewSessionHistory(ctx),
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil {
return newError("InboundHandlerManager is not found is space.")

View File

@ -44,7 +44,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
}
space.OnInitialize(func() error {
space.On(app.SpaceInitializing, func(interface{}) error {
pm := policy.FromSpace(space)
if pm == nil {
return newError("Policy is not found in space.")