From 007b63d10eb1a5d51b2ace3f5d35ce44e02c0c74 Mon Sep 17 00:00:00 2001 From: miraclesu Date: Wed, 10 May 2017 20:04:11 +0800 Subject: [PATCH] =?UTF-8?q?pkg:=20=E6=9B=BF=E6=8D=A2=20event=20=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/node/server.go | 2 +- bin/web/server.go | 3 +- conf/conf.go | 2 +- event/event.go | 94 +++++++++++++++++++++++++++++++++++++++++++++ event/event_test.go | 48 +++++++++++++++++++++++ 5 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 event/event.go create mode 100644 event/event_test.go diff --git a/bin/node/server.go b/bin/node/server.go index e1ae7ef..8b0d9dc 100644 --- a/bin/node/server.go +++ b/bin/node/server.go @@ -6,10 +6,10 @@ import ( "flag" "runtime" - "sunteng/commons/event" "sunteng/commons/log" "github.com/shunfei/cronsun/conf" + "github.com/shunfei/cronsun/event" "github.com/shunfei/cronsun/models" "github.com/shunfei/cronsun/node" ) diff --git a/bin/web/server.go b/bin/web/server.go index c023578..a36cee7 100644 --- a/bin/web/server.go +++ b/bin/web/server.go @@ -6,9 +6,10 @@ import ( "github.com/cockroachdb/cmux" - "sunteng/commons/event" "sunteng/commons/log" + "github.com/shunfei/cronsun/conf" + "github.com/shunfei/cronsun/event" "github.com/shunfei/cronsun/models" "github.com/shunfei/cronsun/web" ) diff --git a/conf/conf.go b/conf/conf.go index a59daa5..19c2068 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -10,9 +10,9 @@ import ( "github.com/go-gomail/gomail" "sunteng/commons/db/imgo" - "sunteng/commons/event" "sunteng/commons/log" + "github.com/shunfei/cronsun/event" "github.com/shunfei/cronsun/utils" ) diff --git a/event/event.go b/event/event.go new file mode 100644 index 0000000..bfc554b --- /dev/null +++ b/event/event.go @@ -0,0 +1,94 @@ +package event + +import ( + "fmt" + "os" + "os/signal" + "reflect" + "syscall" +) + +const ( + EXIT = "exit" + WAIT = "wait" +) + +var ( + Events = make(map[string][]func(interface{}), 2) +) + +func On(name string, fs ...func(interface{})) error { + evs, ok := Events[name] + if !ok { + evs = make([]func(interface{}), 0, len(fs)) + } + + for _, f := range fs { + fp := reflect.ValueOf(f).Pointer() + for i := 0; i < len(evs); i++ { + if reflect.ValueOf(evs[i]).Pointer() == fp { + return fmt.Errorf("func[%v] already exists in event[%s]", fp, name) + } + } + evs = append(evs, f) + } + Events[name] = evs + return nil +} + +func Emit(name string, arg interface{}) { + evs, ok := Events[name] + if !ok { + return + } + + for _, f := range evs { + f(arg) + } +} + +func EmitAll(arg interface{}) { + for _, fs := range Events { + for _, f := range fs { + f(arg) + } + } + return +} + +func Off(name string, f func(interface{})) error { + evs, ok := Events[name] + if !ok || len(evs) == 0 { + return fmt.Errorf("envet[%s] doesn't have any funcs", name) + } + + fp := reflect.ValueOf(f).Pointer() + for i := 0; i < len(evs); i++ { + if reflect.ValueOf(evs[i]).Pointer() == fp { + evs = append(evs[:i], evs[i+1:]...) + Events[name] = evs + return nil + } + } + + return fmt.Errorf("%v func dones't exist in event[%s]", fp, name) +} + +func OffAll(name string) error { + Events[name] = nil + return nil +} + +// 等待信号 +// 如果信号参数为空,则会等待常见的终止信号 +// SIGINT 2 A 键盘中断(如break键被按下) +// SIGTERM 15 A 终止信号 +func Wait(sig ...os.Signal) os.Signal { + c := make(chan os.Signal, 1) + if len(sig) == 0 { + signal.Notify(c, syscall.SIGINT, syscall.SIGTERM) + } else { + signal.Notify(c, sig...) + } + return <-c +} diff --git a/event/event_test.go b/event/event_test.go new file mode 100644 index 0000000..e6d6bd7 --- /dev/null +++ b/event/event_test.go @@ -0,0 +1,48 @@ +package event + +import ( + "testing" + + . "github.com/smartystreets/goconvey/convey" +) + +func TestEvent(t *testing.T) { + i := []int{} + f := func(s interface{}) { + i = append(i, 1) + } + f2 := func(s interface{}) { + i = append(i, 2) + i = append(i, 3) + } + + Convey("events package test", t, func() { + Convey("init events package should be success", func() { + So(len(i), ShouldEqual, 0) + So(len(Events[EXIT]), ShouldEqual, 0) + }) + + Convey("empty events execute Off function should not be success", func() { + So(Off(EXIT, f), ShouldNotBeNil) + }) + + Convey("multi execute On function for a function should not be success", func() { + So(On(EXIT, f), ShouldBeNil) + So(On(EXIT, f), ShouldNotBeNil) + }) + + Convey("execute Emit function should be success", func() { + Emit(EXIT, nil) + So(len(i), ShouldEqual, 1) + }) + + Convey("events package should be work", func() { + So(On(EXIT, f2), ShouldBeNil) + So(len(Events[EXIT]), ShouldEqual, 2) + So(len(i), ShouldEqual, 1) + + So(Off(EXIT, f), ShouldBeNil) + So(len(Events[EXIT]), ShouldEqual, 1) + }) + }) +}