func (m *Master) Start() { context = m if !m.Agent { log.TraceInfo("master", "start") tcpListener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", m.Host, m.Port)) if err != nil { log.LogError(err) log.LogFatalf(err) } m.tcpListener = tcpListener tcpserver := &tcp_server{} m.waitGroup.Wrap(func() { util.TCPServer(m.tcpListener, tcpserver) }) } if !m.Agent && m.ConsolePort != 0 { StartConsoleServer(m) log.LogMessage("console start at:", m.ConsolePort) } if m.Agent { log.TraceInfo("master agent", "start") m.agent = &Agent{} m.agent.Connect(m.Host, m.Port, true, m.ConnectToMaster) } else { m.agentlist = NewAgentList() m.waitfor = true if m.WaitAgents == 0 { m.waitfor = false StartApp(m) } } }
func (s *Sync) SyncDB(path string, drop bool, role string) { defer func() { if e := recover(); e != nil { fmt.Println(e) } s.conn.Close() }() if drop { s.conn.DropDB(s.db) l.TraceInfo("sync", "drop db ", s.db) } s.conn.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", s.db)) s.conn.UseDB(s.db) s.syncSysDb() for k, t := range userTables { s.syncTable(k, t, 0) } LoadAllDef(path) for _, obj := range Defs { if obj.Name == role || obj.Persistent == "true" { s.syncObject(obj) l.TraceInfo("sync", "process ", obj.Name, " complete") } } l.TraceInfo("sync", "all complete") }
func Start(startapp string, name string, appuid int32, typ string, startargs string) error { ferr, err := os.Create(fmt.Sprintf("log/%s_err.log", name)) if err != nil { log.LogError(err) return err } fout, err := os.Create(fmt.Sprintf("log/%s_trace.log", name)) if err != nil { log.LogError(err) return err } cmd := exec.Command(startapp, "-m", fmt.Sprintf("%s:%d", context.Host, context.Port), "-l", context.LocalIP, "-o", context.OuterIP, "-d", strconv.Itoa(int(appuid)), "-t", typ, "-s", startargs) cmd.Stdout = fout cmd.Stderr = ferr err = cmd.Start() if err != nil { log.LogFatalf(err) return err } log.TraceInfo("master", "app start ", typ, ",", strconv.Itoa(int(appuid))) atomic.AddInt32(&Load, 1) context.waitGroup.Wrap(func() { cmd.Wait() ferr.Close() fout.Close() log.LogMessage(name, " is quit") atomic.AddInt32(&Load, -1) }) return nil }
//主循环 func (svr *Server) Wait() { go Run(svr) log.LogMessage("server debug:", svr.Debug) //启动调试 if svr.Debug { go func() { log.LogMessage("pprof start at:", svr.PProfPort) if err := http.ListenAndServe(fmt.Sprintf("localhost:%d", svr.PProfPort), nil); err != nil { log.LogMessage("pprof start failed:", err) } }() } <-svr.exitChannel log.TraceInfo(svr.Name, "is shutdown") if svr.globaldataserver { //保存global data log.TraceInfo(svr.Name, "save global data") if err := svr.SaveGlobalData(true, true); err != nil { log.LogError(err) } log.TraceInfo(svr.Name, "save global data, ok") } //通知app进程即将退出 if svr.apper.OnShutdown() { svr.Shutdown() } <-svr.shutdown if svr.noder != nil { svr.noder.Close() } if svr.clientListener != nil { svr.clientListener.Close() } if svr.rpcListener != nil { svr.rpcListener.Close() } svr.WaitGroup.Wait() log.TraceInfo(svr.Name, " stopped") //等待日志写入完毕 <-time.After(time.Second) log.CloseLogger() }
func (l *LoginMgr) OnPrepare() bool { log.TraceInfo(l.Name, "init link") listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", l.ClientHost, l.ClientPort)) if err != nil { panic(err) } l.listener = listener log.TraceInfo("sockettype:", l.Sockettype) switch l.Sockettype { case "websocket": l.WaitGroup.Wrap(func() { util.WSServer(listener, &wshandler{}) }) default: l.WaitGroup.Wrap(func() { util.TCPServer(listener, &handler{}) }) } log.TraceInfo(l.Name, "start link complete") return true }
func checkDb(path string, role string) bool { if !checkSysDb() { l.TraceInfo("dbmgr", ` system table need sync, you need use "-sync" to sync the database`) return false } LoadAllDef(path) for k, obj := range Defs { if obj.Name == role || obj.Persistent == "true" { if !checkObject(obj) { l.TraceInfo("dbmgr", k, ` is changed, you need use "-sync" to sync the database `) return false } } } /* dir, _ := os.Open(path) files, _ := dir.Readdir(0) for _, f := range files { if !f.IsDir() { obj := ParseEntity(path + "/" + f.Name()) if obj.Name == role { if !checkObject(obj) { l.TraceInfo("dbmgr", f.Name(), ` is changed, you need use "-sync" to sync the database `) return false } } } } */ r, _ := db.sql.Query("SELECT * FROM `sys_uid` LIMIT 1 ") if !r.Next() { db.sql.GetUid("userid") } r.Close() l.TraceInfo("dbmgr", "check db complete") return true }
func TCPServer(listener net.Listener, handler TCPHandler) { log.TraceInfo("TCP", "listening on ", listener.Addr().String()) for { clientConn, err := listener.Accept() if err != nil { if nerr, ok := err.(net.Error); ok && nerr.Temporary() { log.LogWarning("TCP", "temporary Accept() failure - ", err.Error()) runtime.Gosched() continue } // theres no direct way to detect this error because it is not exposed if !strings.Contains(err.Error(), "use of closed network connection") { log.LogError("listener.Accept() - ", err.Error()) } break } go handler.Handle(clientConn) } log.TraceInfo("TCP", "closing ", listener.Addr().String()) }
func CreateSyncDB(db string, datasource string) *Sync { s := &Sync{} conn, err := NewMysqlConn(datasource) if err != nil { l.TraceInfo("dbmgr", err) panic(err) } s.conn = conn s.db = db s.datasrouce = datasource return s }
/* 创建一个新的mysql连接 */ func NewMysqlConn(datasource string) (conn *MySql, err error) { db, e := sql.Open("mysql", datasource) if e != nil { err = e return } if e := db.Ping(); e != nil { err = e return } conn = &MySql{} conn.Conn = db conn.Type = "mysql" log.TraceInfo("mysql", "connected") return }
func createEntity(obj *parser.Object, outfile string) { t, err := template.New("object.tpl").Funcs(template.FuncMap{"tolower": strings.ToLower, "toupper": strings.ToUpper, "ispublic": IsPublic, "isprivate": IsPrivate, "updatename": GetDbUpdateName, "insertname": GetDbInsertName, "placehold": GetPlaceHold, "valuestr": GetDbValueStr}).ParseFiles(*tpl + "/object.tpl") if err != nil { fmt.Println("writer", err) return } //save file file, err := os.Create(outfile) if err != nil { fmt.Println("writer", err) return } defer file.Close() writer := bufio.NewWriter(file) err = t.Execute(writer, obj) if err != nil { fmt.Println("writer", err) } writer.Flush() cmd := exec.Command("gofmt", "--w", outfile) cmd.Run() log.TraceInfo("entity", "create file:", outfile) }
func (m *Master) Exit() { log.TraceInfo("master", "stop") if m.Agent { m.agent.Close() } else { m.agentlist.CloseAll() } for _, a := range m.app { a.Close() } if m.tcpListener != nil { m.tcpListener.Close() } log.LogInfo("wait all app quit") for len(m.app) != 0 { time.Sleep(time.Second) } m.waitGroup.Wait() }
func WSServer(l net.Listener, handler WSHandler) { log.TraceInfo("TCP", "listening on ", l.Addr().String()) http.Handle("/socket.io", websocket.Handler(handler.Handle)) http.Serve(l, nil) log.TraceInfo("TCP", "closing ", l.Addr().String()) }
func main() { flag.Parse() if *path == "" || *output == "" || *tpl == "" { fmt.Println("usage:data -t ./tpl -p ./entity -o ../src/data/entity [-c]") flag.PrintDefaults() return } if *clear { outdir, _ := os.Open(*output) outfiles, _ := outdir.Readdir(0) for _, f := range outfiles { if !f.IsDir() { err := os.Remove(*output + "/" + f.Name()) if err != nil { fmt.Println(err) return } log.TraceInfo("entity", "delete file:", *output+"/"+f.Name()) } } } parser.LoadAllDef(*path) reg := make([]map[string]string, len(parser.Defs)) idx := 0 for k, obj := range parser.Defs { createEntity(obj, *output+"/"+strings.ToLower(k)+".go") reg[idx] = map[string]string{"Name": obj.Name, "Type": strings.ToUpper(obj.Type)} idx++ } /*dir, _ := os.Open(*path) files, _ := dir.Readdir(0) reg := make([]map[string]string, len(files)) for idx, f := range files { if !f.IsDir() { obj := parser.ParseEntity(*path + "/" + f.Name()) createEntity(obj, *output+"/"+strings.Replace(f.Name(), ".xml", ".go", -1)) reg[idx] = map[string]string{"Name": obj.Name, "Type": strings.ToUpper(obj.Type)} } }*/ file, err := os.Create(*output + "/" + "entity.go") if err != nil { fmt.Println("writer", err) return } defer file.Close() writer := bufio.NewWriter(file) t1, err1 := template.ParseFiles(*tpl + "/reg.tpl") if err1 != nil { fmt.Println("writer", err1) return } t1.Execute(writer, reg) writer.Flush() log.TraceInfo("entity", "create file:", *output+"/"+"entity.go") cmd := exec.Command("gofmt", "--w", *output+"/"+"entity.go") cmd.Run() reader := bufio.NewReader(os.Stdin) log.TraceInfo("entity", "press any key to quit") reader.ReadString('\n') }
/* 关闭数据库连接 */ func (conn *MySql) Close() { conn.Conn.Close() log.TraceInfo("mysql", "closed") }
func (svr *Server) Start(master string, localip string, outerip string, typ string, argstr string) bool { svr.startTime = time.Now() defer func() { if e := recover(); e != nil { log.LogFatalf(e) } }() args, err := simplejson.NewJson([]byte(argstr)) if err != nil { panic(err) } svr.Type = typ svr.StartArgs = args if name, ok := args.CheckGet("name"); ok { v, err := name.String() if err != nil { panic(err) } svr.Name = v } else { panic("app id not defined") } svr.MailBox = rpc.NewMailBox(0, 0, svr.AppId) //now := time.Now() //log.WriteToFile(fmt.Sprintf("log/%s_%d_%d_%d_%d_%d_%d.log", svr.Name, now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())) log.LogMessage("id:", svr.AppId, ", name:", svr.Name) svr.Host = localip if svr.Host == "" { if host, ok := args.CheckGet("host"); ok { v, err := host.String() if err != nil { panic(err) } svr.Host = v } else { panic(svr.Name + " host not defined") } } if port, ok := args.CheckGet("port"); ok { v, err := port.Int() if err != nil { panic(err) } svr.Port = v } else { panic(svr.Name + "port not defined") } svr.ClientHost = outerip if svr.ClientHost == "" { if clienthost, ok := args.CheckGet("clienthost"); ok { v, err := clienthost.String() if err != nil { panic(err) } svr.ClientHost = v } } if clientport, ok := args.CheckGet("clientport"); ok { v, err := clientport.Int() if err != nil { panic(err) } svr.ClientPort = v } if fronted, ok := args.CheckGet("fronted"); ok { v, err := fronted.Bool() if err != nil { panic(err) } svr.Fronted = v } svr.Sockettype = "native" if Sockettype, ok := args.CheckGet("sockettype"); ok { v, err := Sockettype.String() if err != nil { panic(err) } svr.Sockettype = v } //rpc端口 r, err := net.Listen("tcp", fmt.Sprintf("%s:%d", svr.Host, svr.Port)) if err != nil { panic(err) } svr.rpcListener = r if svr.Port == 0 { svr.Port = r.Addr().(*net.TCPAddr).Port } if svr.Fronted && !svr.apper.RawSock() { log.TraceInfo(svr.Name, "init link") listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", svr.ClientHost, svr.ClientPort)) if err != nil { panic(err) } svr.clientListener = listener if svr.ClientPort == 0 { svr.ClientPort = listener.Addr().(*net.TCPAddr).Port } switch svr.Sockettype { case "websocket": svr.WaitGroup.Wrap(func() { util.WSServer(svr.clientListener, &WSClientHandler{}) }) default: svr.WaitGroup.Wrap(func() { util.TCPServer(svr.clientListener, &ClientHandler{}) }) } log.TraceInfo(svr.Name, "start link complete") } master_peer := &master_peer{} peer := &peer{addr: master, h: master_peer} if err := peer.Connect(); err != nil { panic(err) } svr.noder = peer signalChan := make(chan os.Signal, 1) go func() { for { if _, ok := <-signalChan; !ok { return } } }() signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) if debug, ok := args.CheckGet("debug"); ok { v, err := debug.Bool() if err == nil { svr.Debug = v } } if pfport, ok := args.CheckGet("pprof"); ok { v, err := pfport.Int() if err == nil { svr.PProfPort = v } } if assets, ok := args.CheckGet("assets"); ok { v, err := assets.String() if err == nil { svr.AssetPath = v } } if loglevel, ok := args.CheckGet("loglevel"); ok { v, err := loglevel.Int() if err == nil { log.SetLogLevel("stdout", v) } } svr.globalset = "GlobalSet" if gs, ok := args.CheckGet("globalset"); ok { v, err := gs.String() if err == nil { svr.globalset = v } } svr.globaldataserver = false if enable, ok := args.CheckGet("globaldataserver"); ok { v, err := enable.Bool() if err == nil { svr.globaldataserver = v } } svr.enableglobaldata = false if enable, ok := args.CheckGet("enableglobaldata"); ok { v, err := enable.Bool() if err == nil { svr.enableglobaldata = v } } svr.maxglobalentry = 10 if max, ok := args.CheckGet("maxglobalentry"); ok { v, err := max.Int() if err == nil { svr.maxglobalentry = v } } log.LogMessage("global data status is ", svr.enableglobaldata) if svr.globaldataserver { svr.globalHelper.SetServer() log.LogMessage("promote to global data server") } serial := (uint64(time.Now().Unix()%0x80000000) << 32) | (uint64(svr.AppId) << 24) svr.setSerial(serial) log.LogMessage("start serial:", fmt.Sprintf("%X", serial)) if !svr.apper.OnPrepare() { return false } svr.CurrentInBase(svr.apper.IsBase()) if svr.AssetPath != "" { helper.LoadAllConfig(svr.AssetPath) } //内部rpc注册 svr.rpcCh = make(chan *rpc.RpcCall, RPCBUFFER) svr.rpcServer = createRpc(svr.rpcCh) svr.WaitGroup.Wrap(func() { rpc.CreateService(svr.rpcServer, svr.rpcListener) }) svr.rpcProto = codec if svr.rpcProto == nil { panic("proto not set") } log.LogMessage("client proto:", svr.rpcProto.GetCodecInfo()) svr.Ready() return true }
func (s *Sync) syncTable(tbl_name string, tblinfo TblField, incNum int) error { if oldfield, empty, _ := s.conn.QueryTblInfo(s.db, tbl_name); empty { err := s.conn.CreateTable(tbl_name, tblinfo, incNum) if err != nil { panic(err) } l.TraceInfo("sync", "create table ", tbl_name, " ok") } else { alert := make([]Field, 0, 10) add := make([]Field, 0, 10) for _, newf := range tblinfo.FieldList { find := false for _, oldf := range oldfield.FieldList { if strings.ToLower(newf.Name) == strings.ToLower(oldf.Name) { if strings.ToLower(oldf.Type) != strings.ToLower(newf.Type) { alert = append(alert, newf) } find = true break } } if !find { add = append(add, newf) } } del := make([]Field, 0, 10) for _, oldf := range oldfield.FieldList { find := false for _, newf := range tblinfo.FieldList { if strings.ToLower(newf.Name) == strings.ToLower(oldf.Name) { find = true break } } if !find { del = append(del, oldf) } } for _, f := range alert { var nulltype string if !f.IsNull { nulltype = "NOT NULL" } else { nulltype = "DEFAULT NULL" } autoinc := "" if f.AutoInc { autoinc = " AUTO_INCREMENT" } sql := fmt.Sprintf("ALTER TABLE `%s` CHANGE `%s` `%s` %s %s %s;", tbl_name, f.Name, f.Name, f.Type, nulltype, autoinc) _, err := s.conn.Exec(sql) if err != nil { panic(err) } l.TraceInfo("sync", sql, " ok") } for _, f := range add { var nulltype string if !f.IsNull { nulltype = "NOT NULL" } else { nulltype = "DEFAULT NULL" } autoinc := "" if f.AutoInc { autoinc = " AUTO_INCREMENT" } /*if len(del) > 0 { sql := fmt.Sprintf("ALTER TABLE `%s` CHANGE `%s` `%s` %s %s %s;", tbl_name, del[0].Name, f.Name, f.Type, nulltype, autoinc) _, err := s.conn.Exec(sql) if err != nil { panic(err) } l.TraceInfo("sync", sql, " ok") del = del[1:] break } */ sql := fmt.Sprintf("ALTER TABLE `%s` ADD `%s` %s %s %s;", tbl_name, f.Name, f.Type, nulltype, autoinc) _, err := s.conn.Exec(sql) if err != nil { panic(err) } l.TraceInfo("sync", sql, "ok") } for _, f := range del { sql := fmt.Sprintf("ALTER TABLE `%s` DROP `%s` ;", tbl_name, f.Name) _, err := s.conn.Exec(sql) if err != nil { panic(err) } l.TraceInfo("sync", sql, " ok") } } return nil }