func main() { runtime.LockOSThread() var width uint = 800 var height uint = 600 var thrustWindow *window.Window if runtime.GOOS == "darwin" { height = 578 } if utils.Desktop() && (winVer() >= 6 || winVer() == 0) { thrust.Start() thrustWindow = thrust.NewWindow(thrust.WindowOptions{ RootUrl: "http://localhost:8989/loader.html", HasFrame: true, Title: "Dcoin", Size: commands.SizeHW{Width: width, Height: height}, }) thrust.NewEventHandler("*", func(cr commands.CommandResponse) { //fmt.Println(fmt.Sprintf("======Event(%s %d) - Signaled by Command (%s)", cr.TargetID, cr.Type)) if cr.TargetID > 1 && cr.Type == "closed" { if utils.DB != nil && utils.DB.DB != nil { utils.DB.ExecSql(`INSERT INTO stop_daemons(stop_time) VALUES (?)`, utils.Time()) } else { thrust.Exit() os.Exit(0) } } }) thrustWindow.Show() thrustWindow.Focus() go func() { http.HandleFunc("/static/img/main_loader.gif", main_loader) http.HandleFunc("/loader.html", main_loader_html) http.ListenAndServe(":8989", nil) }() } tray() go dcoin.Start("", thrustWindow) enterLoop() }
func Start(dir string, thrustWindowLoder *window.Window) { var err error IosLog("start") defer func() { if r := recover(); r != nil { log.Error("Recovered", r) panic(r) } }() if dir != "" { fmt.Println("dir", dir) *utils.Dir = dir } IosLog("dir:" + dir) fmt.Println("utils.Dir", *utils.Dir) fmt.Println("dcVersion:", consts.VERSION) log.Debug("dcVersion: %v", consts.VERSION) // читаем config.ini configIni := make(map[string]string) configIni_, err := config.NewConfig("ini", *utils.Dir+"/config.ini") if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) } else { configIni, err = configIni_.GetSection("default") } // убьем ранее запущенный Dcoin if !utils.Mobile() { fmt.Println("kill dcoin.pid") if _, err := os.Stat(*utils.Dir + "/dcoin.pid"); err == nil { dat, err := ioutil.ReadFile(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } var pidMap map[string]string err = json.Unmarshal(dat, &pidMap) if err != nil { log.Error("%v", utils.ErrInfo(err)) } fmt.Println("old PID ("+*utils.Dir+"/dcoin.pid"+"):", pidMap["pid"]) utils.DB, err = utils.NewDbConnect(configIni) err = KillPid(pidMap["pid"]) if nil != err { fmt.Println(err) log.Error("KillPid %v", utils.ErrInfo(err)) } if fmt.Sprintf("%s", err) != "null" { fmt.Println(fmt.Sprintf("%s", err)) // даем 15 сек, чтобы завершиться предыдущему процессу for i := 0; i < 15; i++ { log.Debug("waiting killer %d", i) if _, err := os.Stat(*utils.Dir + "/dcoin.pid"); err == nil { fmt.Println("waiting killer") utils.Sleep(1) } else { // если dcoin.pid нет, значит завершился break } } } } } // сохраним текущий pid и версию if !utils.Mobile() { pid := os.Getpid() PidAndVer, err := json.Marshal(map[string]string{"pid": utils.IntToStr(pid), "version": consts.VERSION}) if err != nil { log.Error("%v", utils.ErrInfo(err)) } err = ioutil.WriteFile(*utils.Dir+"/dcoin.pid", PidAndVer, 0644) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) } } controllers.SessInit() controllers.ConfigInit() daemons.ConfigInit() go func() { utils.DB, err = utils.NewDbConnect(configIni) log.Debug("%v", utils.DB) IosLog("utils.DB:" + fmt.Sprintf("%v", utils.DB)) if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } }() f, err := os.OpenFile(*utils.Dir+"/dclog.txt", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0777) if err != nil { IosLog("err:" + fmt.Sprintf("%s", utils.ErrInfo(err))) log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } defer f.Close() IosLog("configIni:" + fmt.Sprintf("%v", configIni)) var backend *logging.LogBackend switch configIni["log_output"] { case "file": backend = logging.NewLogBackend(f, "", 0) case "console": backend = logging.NewLogBackend(os.Stderr, "", 0) case "file_console": //backend = logging.NewLogBackend(io.MultiWriter(f, os.Stderr), "", 0) default: backend = logging.NewLogBackend(f, "", 0) } backendFormatter := logging.NewBackendFormatter(backend, format) backendLeveled := logging.AddModuleLevel(backendFormatter) logLevel_ := "DEBUG" if *utils.LogLevel == "" { logLevel_ = configIni["log_level"] } else { logLevel_ = *utils.LogLevel } logLevel, err := logging.LogLevel(logLevel_) if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("logLevel: %v", logLevel) backendLeveled.SetLevel(logLevel, "") logging.SetBackend(backendLeveled) rand.Seed(time.Now().UTC().UnixNano()) // если есть OldFileName, значит работаем под именем tmp_dc и нужно перезапуститься под нормальным именем log.Error("OldFileName %v", *utils.OldFileName) if *utils.OldFileName != "" { // вначале нужно обновить БД в зависимости от версии dat, err := ioutil.ReadFile(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } var pidMap map[string]string err = json.Unmarshal(dat, &pidMap) if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("OldFileName %v", *utils.OldFileName) err = utils.CopyFileContents(*utils.Dir+`/dc.tmp`, *utils.OldFileName) if err != nil { log.Debug("%v", os.Stderr) log.Debug("%v", utils.ErrInfo(err)) } // ждем подключения к БД for { if utils.DB == nil || utils.DB.DB == nil { utils.Sleep(1) continue } break } if len(pidMap["version"]) > 0 { if utils.VersionOrdinal(pidMap["version"]) < utils.VersionOrdinal("1.0.2b5") { log.Debug("%v", "ALTER TABLE config ADD COLUMN analytics_disabled smallint") err = utils.DB.ExecSql(`ALTER TABLE config ADD COLUMN analytics_disabled smallint`) if err != nil { log.Error("%v", utils.ErrInfo(err)) } } if utils.VersionOrdinal(pidMap["version"]) < utils.VersionOrdinal("2.0.1b2") { log.Debug("%v", "ALTER TABLE config ADD COLUMN sqlite_db_url varchar(255)") err = utils.DB.ExecSql(`ALTER TABLE config ADD COLUMN sqlite_db_url varchar(255)`) if err != nil { log.Error("%v", utils.ErrInfo(err)) } } } err = utils.DB.Close() if err != nil { log.Error("%v", utils.ErrInfo(err)) } fmt.Println("DB Closed") err = os.Remove(*utils.Dir + "/dcoin.pid") if err != nil { log.Error("%v", utils.ErrInfo(err)) } log.Debug("dc.tmp %v", *utils.Dir+`/dc.tmp`) err = exec.Command(*utils.OldFileName, "-dir", *utils.Dir).Start() if err != nil { log.Debug("%v", os.Stderr) log.Debug("%v", utils.ErrInfo(err)) } log.Debug("OldFileName %v", *utils.OldFileName) os.Exit(1) } // откат БД до указанного блока if *utils.RollbackToBlockId > 0 { utils.DB, err = utils.NewDbConnect(configIni) parser := new(dcparser.Parser) parser.DCDB = utils.DB err = parser.RollbackToBlockId(*utils.RollbackToBlockId) if err != nil { fmt.Println(err) panic(err) } fmt.Print("complete") os.Exit(0) } log.Debug("public") IosLog("public") if _, err := os.Stat(*utils.Dir + "/public"); os.IsNotExist(err) { err = os.Mkdir(*utils.Dir+"/public", 0755) if err != nil { log.Error("%v", utils.ErrInfo(err)) panic(err) os.Exit(1) } } log.Debug("daemonsStart") IosLog("daemonsStart") daemons.StartDaemons() IosLog("MonitorDaemons") // мониторинг демонов daemonsTable := make(map[string]string) go func() { for { daemonNameAndTime := <-daemons.MonitorDaemonCh daemonsTable[daemonNameAndTime[0]] = daemonNameAndTime[1] if utils.Time()%10 == 0 { log.Debug("daemonsTable: %v\n", daemonsTable) } } }() // сигналы демонам для выхода IosLog("signals") stopdaemons.Signals() utils.Sleep(1) // мониторим сигнал из БД о том, что демонам надо завершаться go stopdaemons.WaitStopTime() BrowserHttpHost := "http://localhost:8089" HandleHttpHost := "" ListenHttpHost := ":" + *utils.ListenHttpHost go func() { // уже прошли процесс инсталяции, где юзер указал БД и был перезапуск кошелька if len(configIni["db_type"]) > 0 && !utils.Mobile() { for { // ждем, пока произойдет подключение к БД в другой гоурутине if utils.DB == nil || utils.DB.DB == nil { utils.Sleep(1) fmt.Println("wait DB") } else { break } } fmt.Println("GET http host") BrowserHttpHost, HandleHttpHost, ListenHttpHost = GetHttpHost() // для биржы нужен хост или каталог, поэтому нужно подключение к БД exhangeHttpListener(HandleHttpHost) // для ноды тоже нужна БД tcpListener() } IosLog(fmt.Sprintf("BrowserHttpHost: %v, HandleHttpHost: %v, ListenHttpHost: %v", BrowserHttpHost, HandleHttpHost, ListenHttpHost)) fmt.Printf("BrowserHttpHost: %v, HandleHttpHost: %v, ListenHttpHost: %v\n", BrowserHttpHost, HandleHttpHost, ListenHttpHost) // включаем листинг веб-сервером для клиентской части http.HandleFunc(HandleHttpHost+"/", controllers.Index) http.HandleFunc(HandleHttpHost+"/content", controllers.Content) http.HandleFunc(HandleHttpHost+"/ajax", controllers.Ajax) http.HandleFunc(HandleHttpHost+"/tools", controllers.Tools) http.HandleFunc(HandleHttpHost+"/cf/", controllers.IndexCf) http.HandleFunc(HandleHttpHost+"/cf/content", controllers.ContentCf) http.Handle(HandleHttpHost+"/public/", noDirListing(http.FileServer(http.Dir(*utils.Dir)))) http.Handle(HandleHttpHost+"/static/", http.FileServer(&assetfs.AssetFS{Asset: static.Asset, AssetDir: static.AssetDir, Prefix: ""})) log.Debug("ListenHttpHost", ListenHttpHost) IosLog(fmt.Sprintf("ListenHttpHost: %v", ListenHttpHost)) fmt.Println("ListenHttpHost", ListenHttpHost) httpListener(ListenHttpHost, BrowserHttpHost) if *utils.Console == 0 && !utils.Mobile() { utils.Sleep(1) if thrustWindowLoder != nil { thrustWindowLoder.Close() thrustWindow := thrust.NewWindow(thrust.WindowOptions{ RootUrl: BrowserHttpHost, Size: commands.SizeHW{Width: 1024, Height: 600}, }) thrustWindow.HandleEvent("*", func(cr commands.EventResult) { fmt.Println("HandleEvent", cr) }) thrustWindow.HandleRemote(func(er commands.EventResult, this *window.Window) { fmt.Println("RemoteMessage Recieved:", er.Message.Payload) openBrowser(er.Message.Payload) // Keep in mind once we have the message, lets say its json of some new type we made, // We can unmarshal it to that type. // Same goes for the other way around. this.SendRemoteMessage("boop") }) thrustWindow.Show() thrustWindow.Focus() } else { openBrowser(BrowserHttpHost) } } }() // ожидает появления свежих записей в чате, затем ждет появления коннектов // (заносятся из демеона connections и от тех, кто сам подключился к ноде) go utils.ChatOutput(utils.ChatNewTx) log.Debug("ALL RIGHT") IosLog("ALL RIGHT") fmt.Println("ALL RIGHT") utils.Sleep(3600 * 24 * 90) log.Debug("EXIT") }