瀏覽代碼

上传文件至 ''

zpzp366499 7 月之前
父節點
當前提交
8236b43d15
共有 5 個文件被更改,包括 603 次插入0 次删除
  1. 47 0
      Makefile
  2. 330 0
      application.go
  3. 41 0
      go.mod
  4. 117 0
      go.sum
  5. 68 0
      mhaya.go

+ 47 - 0
Makefile

@@ -0,0 +1,47 @@
+default: help
+
+help:
+	@echo "COMMAND:"
+	@echo "	make init"
+	@echo "	make protoc"
+	@echo "	make tag"
+	@echo " make modtidy"
+
+init:
+	@echo "[INIT] install protoc-gen-go"
+	go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+
+protoc:
+	@echo "[PROTOC] build proto files"
+	cd net && \
+	cd proto && \
+	protoc --go_out=. --go_opt=paths=source_relative proto.proto
+
+tag:
+	./tag.sh
+
+modtidy:
+	@echo "[MODTIDY] rebuild"
+	rm -rf  \
+	go.sum \
+	go.work.sum \
+	examples/go.sum \
+	components/cron/go.sum \
+	components/data-config/go.sum \
+	components/etcd/go.sum \
+	components/gin/go.sum \
+	components/gops/go.sum \
+	components/gorm/go.sum \
+	components/mongo/go.sum \
+	examples/go.sum
+
+	go mod tidy
+	cd components/cron/ && go mod tidy && cd ../../
+	cd components/data-config/ && go mod tidy && cd ../../
+	cd components/etcd/ && go mod tidy && cd ../../
+	cd components/gin/ && go mod tidy && cd ../../
+	cd components/gops/ && go mod tidy && cd ../../
+	cd components/gorm/ && go mod tidy && cd ../../
+	cd components/mongo/ && go mod tidy && cd ../../
+	cd examples/ && go mod tidy && cd ../../
+

+ 330 - 0
application.go

@@ -0,0 +1,330 @@
+package mhaya
+
+import (
+	"os"
+	"os/signal"
+	"sync/atomic"
+	"syscall"
+
+	cconst "github.com/mhaya/const"
+	ctime "github.com/mhaya/extend/time"
+	cutils "github.com/mhaya/extend/utils"
+	cfacade "github.com/mhaya/facade"
+	clog "github.com/mhaya/logger"
+	cactor "github.com/mhaya/net/actor"
+	cserializer "github.com/mhaya/net/serializer"
+	cprofile "github.com/mhaya/profile"
+)
+
+const (
+	Cluster    NodeMode = 1 // 集群模式
+	Standalone NodeMode = 2 // 单机模式
+)
+
+type (
+	NodeMode byte
+
+	Application struct {
+		cfacade.INode
+		isFrontend   bool
+		nodeMode     NodeMode
+		startTime    ctime.MhayaTime      // application start time
+		running      int32                // is running
+		dieChan      chan bool            // wait for end application
+		onShutdownFn []func()             // on shutdown execute functions
+		components   []cfacade.IComponent // all components
+		serializer   cfacade.ISerializer  // serializer
+		discovery    cfacade.IDiscovery   // discovery component
+		cluster      cfacade.ICluster     // cluster component
+		actorSystem  *cactor.Component    // actor system
+		netParser    cfacade.INetParser   // net packet parser
+	}
+)
+
+// NewApp create new application instance
+func NewApp(profileFilePath, nodeId string, isFrontend bool, mode NodeMode) *Application {
+	node, err := cprofile.Init(profileFilePath, nodeId)
+	if err != nil {
+		panic(err)
+	}
+
+	return NewAppNode(node, isFrontend, mode)
+}
+
+func NewAppNode(node cfacade.INode, isFrontend bool, mode NodeMode) *Application {
+	// set logger
+	clog.SetNodeLogger(node)
+
+	// print version info
+	clog.Info(cconst.GetLOGO())
+
+	app := &Application{
+		INode:       node,
+		serializer:  cserializer.NewJSON(),
+		isFrontend:  isFrontend,
+		nodeMode:    mode,
+		startTime:   ctime.Now(),
+		running:     0,
+		dieChan:     make(chan bool),
+		actorSystem: cactor.New(),
+	}
+
+	return app
+}
+
+func (a *Application) IsFrontend() bool {
+	return a.isFrontend
+}
+
+func (a *Application) NodeMode() NodeMode {
+	return a.nodeMode
+}
+
+func (a *Application) Running() bool {
+	return a.running > 0
+}
+
+func (a *Application) DieChan() chan bool {
+	return a.dieChan
+}
+
+func (a *Application) Register(components ...cfacade.IComponent) {
+	if a.Running() {
+		return
+	}
+
+	for _, c := range components {
+		if c == nil || c.Name() == "" {
+			clog.Errorf("[component = %T] name is nil", c)
+			return
+		}
+
+		result := a.Find(c.Name())
+		if result != nil {
+			clog.Errorf("[component name = %s] is duplicate.", c.Name())
+			return
+		}
+
+		a.components = append(a.components, c)
+	}
+}
+
+func (a *Application) Find(name string) cfacade.IComponent {
+	if name == "" {
+		return nil
+	}
+
+	for _, component := range a.components {
+		if component.Name() == name {
+			return component
+		}
+	}
+	return nil
+}
+
+// Remove component by name
+func (a *Application) Remove(name string) cfacade.IComponent {
+	if name == "" {
+		return nil
+	}
+
+	var removeComponent cfacade.IComponent
+	for i := 0; i < len(a.components); i++ {
+		if a.components[i].Name() == name {
+			removeComponent = a.components[i]
+			a.components = append(a.components[:i], a.components[i+1:]...)
+			i--
+		}
+	}
+	return removeComponent
+}
+
+func (a *Application) All() []cfacade.IComponent {
+	return a.components
+}
+
+func (a *Application) OnShutdown(fn ...func()) {
+	a.onShutdownFn = append(a.onShutdownFn, fn...)
+}
+
+// Startup load components before startup
+func (a *Application) Startup() {
+	defer func() {
+		if r := recover(); r != nil {
+			clog.Error(r)
+		}
+	}()
+
+	if a.Running() {
+		clog.Error("Application has running.")
+		return
+	}
+
+	defer func() {
+		clog.Flush()
+	}()
+
+	// register actor system
+	a.Register(a.actorSystem)
+
+	// add connector component
+	if a.netParser != nil {
+		for _, connector := range a.netParser.Connectors() {
+			a.Register(connector)
+		}
+	}
+
+	clog.Info("-------------------------------------------------")
+	clog.Infof("[nodeId      = %s] application is starting...", a.NodeId())
+	clog.Infof("[nodeType    = %s]", a.NodeType())
+	clog.Infof("[pid         = %d]", os.Getpid())
+	clog.Infof("[startTime   = %s]", a.StartTime())
+	clog.Infof("[profilePath = %s]", cprofile.Path())
+	clog.Infof("[profileName = %s]", cprofile.Name())
+	clog.Infof("[env         = %s]", cprofile.Env())
+	clog.Infof("[debug       = %v]", cprofile.Debug())
+	clog.Infof("[printLevel  = %s]", cprofile.PrintLevel())
+	clog.Infof("[logLevel    = %s]", clog.DefaultLogger.LogLevel)
+	clog.Infof("[stackLevel  = %s]", clog.DefaultLogger.StackLevel)
+	clog.Infof("[writeFile   = %v]", clog.DefaultLogger.EnableWriteFile)
+	clog.Infof("[serializer  = %s]", a.serializer.Name())
+	clog.Info("-------------------------------------------------")
+
+	// component list
+	for _, c := range a.components {
+		c.Set(a)
+		clog.Infof("[component = %s] is added.", c.Name())
+	}
+	clog.Info("-------------------------------------------------")
+
+	// execute Init()
+	for _, c := range a.components {
+		clog.Infof("[component = %s] -> OnInit().", c.Name())
+		c.Init()
+	}
+	clog.Info("-------------------------------------------------")
+
+	// execute OnAfterInit()
+	for _, c := range a.components {
+		clog.Infof("[component = %s] -> OnAfterInit().", c.Name())
+		c.OnAfterInit()
+	}
+
+	// load net packet parser
+	if a.isFrontend {
+		if a.netParser == nil {
+			clog.Panic("net packet parser is nil.")
+		}
+		a.netParser.Load(a)
+	}
+
+	clog.Info("-------------------------------------------------")
+	spendTime := a.startTime.DiffInMillisecond(ctime.Now())
+	clog.Infof("[spend time = %dms] application is running.", spendTime)
+	clog.Info("-------------------------------------------------")
+
+	// set application is running
+	atomic.AddInt32(&a.running, 1)
+
+	sg := make(chan os.Signal, 1)
+	signal.Notify(sg, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
+
+	select {
+	case <-a.dieChan:
+		clog.Info("invoke shutdown().")
+	case s := <-sg:
+		clog.Infof("receive shutdown signal = %v.", s)
+	}
+
+	// stop status
+	atomic.StoreInt32(&a.running, 0)
+
+	clog.Info("------- application will shutdown -------")
+
+	if a.onShutdownFn != nil {
+		for _, f := range a.onShutdownFn {
+			cutils.Try(func() {
+				f()
+			}, func(errString string) {
+				clog.Warnf("[onShutdownFn] error = %s", errString)
+			})
+		}
+	}
+
+	//all components in reverse order
+	for i := len(a.components) - 1; i >= 0; i-- {
+		cutils.Try(func() {
+			clog.Infof("[component = %s] -> OnBeforeStop().", a.components[i].Name())
+			a.components[i].OnBeforeStop()
+		}, func(errString string) {
+			clog.Warnf("[component = %s] -> OnBeforeStop(). error = %s", a.components[i].Name(), errString)
+		})
+	}
+
+	for i := len(a.components) - 1; i >= 0; i-- {
+		cutils.Try(func() {
+			clog.Infof("[component = %s] -> OnStop().", a.components[i].Name())
+			a.components[i].OnStop()
+		}, func(errString string) {
+			clog.Warnf("[component = %s] -> OnStop(). error = %s", a.components[i].Name(), errString)
+		})
+	}
+
+	clog.Info("------- application has been shutdown... -------")
+}
+
+func (a *Application) Shutdown() {
+	a.dieChan <- true
+}
+
+func (a *Application) Serializer() cfacade.ISerializer {
+	return a.serializer
+}
+
+func (a *Application) Discovery() cfacade.IDiscovery {
+	return a.discovery
+}
+
+func (a *Application) Cluster() cfacade.ICluster {
+	return a.cluster
+}
+
+func (a *Application) ActorSystem() cfacade.IActorSystem {
+	return a.actorSystem
+}
+
+func (a *Application) StartTime() string {
+	return a.startTime.ToDateTimeFormat()
+}
+
+func (a *Application) SetSerializer(serializer cfacade.ISerializer) {
+	if a.Running() || serializer == nil {
+		return
+	}
+
+	a.serializer = serializer
+}
+
+func (a *Application) SetDiscovery(discovery cfacade.IDiscovery) {
+	if a.Running() || discovery == nil {
+		return
+	}
+
+	a.discovery = discovery
+}
+
+func (a *Application) SetCluster(cluster cfacade.ICluster) {
+	if a.Running() || cluster == nil {
+		return
+	}
+
+	a.cluster = cluster
+}
+
+func (a *Application) SetNetParser(netParser cfacade.INetParser) {
+	if a.Running() || netParser == nil {
+		return
+	}
+
+	a.netParser = netParser
+}

+ 41 - 0
go.mod

@@ -0,0 +1,41 @@
+module github.com/mhaya
+
+go 1.22
+
+toolchain go1.22.4
+
+require (
+	github.com/gorilla/websocket v1.5.0
+	github.com/json-iterator/go v1.1.12
+	github.com/lestrrat-go/strftime v1.0.6
+	github.com/nats-io/nats.go v1.30.2
+	github.com/nats-io/nuid v1.0.1
+	github.com/shopspring/decimal v1.4.0
+	go.etcd.io/etcd/api/v3 v3.5.16
+	go.etcd.io/etcd/client/v3 v3.5.16
+	go.uber.org/zap v1.26.0
+	google.golang.org/protobuf v1.33.0
+)
+
+require (
+	github.com/coreos/go-semver v0.3.0 // indirect
+	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
+	github.com/gogo/protobuf v1.3.2 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/klauspost/compress v1.17.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/nats-io/nats-server/v2 v2.10.3 // indirect
+	github.com/nats-io/nkeys v0.4.5 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
+	go.uber.org/multierr v1.10.0 // indirect
+	golang.org/x/crypto v0.21.0 // indirect
+	golang.org/x/net v0.23.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/text v0.14.0 // indirect
+	google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
+	google.golang.org/grpc v1.59.0 // indirect
+)

+ 117 - 0
go.sum

@@ -0,0 +1,117 @@
+github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
+github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
+github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
+github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
+github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
+github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/nats-io/jwt/v2 v2.5.2 h1:DhGH+nKt+wIkDxM6qnVSKjokq5t59AZV5HRcFW0zJwU=
+github.com/nats-io/jwt/v2 v2.5.2/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=
+github.com/nats-io/nats-server/v2 v2.10.3 h1:nk2QVLpJUh3/AhZCJlQdTfj2oeLDvWnn1Z6XzGlNFm0=
+github.com/nats-io/nats-server/v2 v2.10.3/go.mod h1:lzrskZ/4gyMAh+/66cCd+q74c6v7muBypzfWhP/MAaM=
+github.com/nats-io/nats.go v1.30.2 h1:aloM0TGpPorZKQhbAkdCzYDj+ZmsJDyeo3Gkbr72NuY=
+github.com/nats-io/nats.go v1.30.2/go.mod h1:dcfhUgmQNN4GJEfIb2f9R7Fow+gzBF4emzDHrVBd5qM=
+github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk=
+github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
+github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0=
+go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28=
+go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q=
+go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E=
+go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE=
+go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
+go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
+go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
+go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
+go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
+golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
+golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
+google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
+google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 68 - 0
mhaya.go

@@ -0,0 +1,68 @@
+package mhaya
+
+import (
+	cfacade "github.com/mhaya/facade"
+	ccluster "github.com/mhaya/net/cluster"
+	cdiscovery "github.com/mhaya/net/discovery"
+)
+
+type (
+	AppBuilder struct {
+		*Application
+		components []cfacade.IComponent
+	}
+)
+
+func Configure(profileFilePath, nodeId string, isFrontend bool, mode NodeMode) *AppBuilder {
+	appBuilder := &AppBuilder{
+		Application: NewApp(profileFilePath, nodeId, isFrontend, mode),
+		components:  make([]cfacade.IComponent, 0),
+	}
+
+	return appBuilder
+}
+
+func ConfigureNode(node cfacade.INode, isFrontend bool, mode NodeMode) *AppBuilder {
+	appBuilder := &AppBuilder{
+		Application: NewAppNode(node, isFrontend, mode),
+		components:  make([]cfacade.IComponent, 0),
+	}
+
+	return appBuilder
+}
+
+func (p *AppBuilder) Startup() {
+	app := p.Application
+
+	if app.NodeMode() == Cluster {
+		cluster := ccluster.New()
+		app.SetCluster(cluster)
+		app.Register(cluster)
+
+		discovery := cdiscovery.New()
+		app.SetDiscovery(discovery)
+		app.Register(discovery)
+	}
+
+	// Register custom components
+	app.Register(p.components...)
+
+	// startup
+	app.Startup()
+}
+
+func (p *AppBuilder) Register(component ...cfacade.IComponent) {
+	p.components = append(p.components, component...)
+}
+
+func (p *AppBuilder) AddActors(actors ...cfacade.IActorHandler) {
+	p.actorSystem.Add(actors...)
+}
+
+func (p *AppBuilder) NetParser() cfacade.INetParser {
+	return p.netParser
+}
+
+func (p *AppBuilder) SetNetParser(parser cfacade.INetParser) {
+	p.netParser = parser
+}