func Migrate(dataDir string) { if !server.FileExists(dataDir) { logger.Printf("Data directory '%v' doesn't appear to exist, so aborting migration.", dataDir) return } logger.Printf("Migrating data in %v to version %v", dataDir, DATA_VERSION) deployedDataVersion := readDataVersion(dataDir) if deployedDataVersion == DATA_VERSION { logger.Printf("Actually, data format was already up-to-date, so skipping migration.") return } migrateEntityGraph(dataDir, "person") migrateEntityGraph(dataDir, "org") migrateEntityGraph(dataDir, "place") server.Must(os.Remove(filepath.Join(dataDir, "personGraph.dat"))) server.Must(os.Remove(filepath.Join(dataDir, "orgGraph.dat"))) server.Must(os.Remove(filepath.Join(dataDir, "placeGraph.dat"))) server.Must(os.Rename(filepath.Join(dataDir, "personGraph.dat.tmp"), filepath.Join(dataDir, "personGraph.dat"))) server.Must(os.Rename(filepath.Join(dataDir, "orgGraph.dat.tmp"), filepath.Join(dataDir, "orgGraph.dat"))) server.Must(os.Rename(filepath.Join(dataDir, "placeGraph.dat.tmp"), filepath.Join(dataDir, "placeGraph.dat"))) WriteDataVersion(dataDir) logger.Printf("Data in %v successfully migrated to version %v", dataDir, DATA_VERSION) }
func createDataDirIfNotExists(dataDir string) { if !server.FileExists(dataDir) { logger.Printf("%v doesn't exist, so creating it and creating data version file.", dataDir) server.Must(os.MkdirAll(dataDir, 0755)) migrate.WriteDataVersion(dataDir) } }
// Fires up the EntityManager service. Once started, the service will pull // the latest content (documents and entities) from the configured ContentSource // calculate some aggreate stats on them, and then make the stats available to // this web app. func startEntityManager(cfg AppConfig, contentSource server.ContentSource) *server.EntityManager { // Create and configure a new EntityManager object. entityManager := server.NewEntityManager(server.EntityManagerConfig{ TimeRanges: cfg.TimeRanges, ContentSource: contentSource, }) now := unixtime.Now() // If it exists, load global content saved prior to previous app shutdown. dataDir := cfg.DataDir if server.FileExists(dataDir) { logger.Printf("Loading saved content from %v", dataDir) entityManager.LoadState(dataDir, now) entityManager.ContentDAO.Load(dataDir) } else { logger.Printf("Loading recent content directly from content source into content buffer.") entityManager.PreFill(now.Subtract(cfg.DataPreFetchWindow), now) } logger.Printf("Calculating entity stats for the first time...") entityManager.RefreshStats(now) refreshStatsLock = &sync.Mutex{} logger.Printf("Starting MemDb content polling loop.") go func() { // The show must go on. Trap any panics, log them as an error, and then // continue to attempt to get more data from MemDb service. for { func() { defer func() { if r := recover(); r != nil { logger.Printf("ERROR: unexpected application error: \n%v\n\n", r) debug.PrintStack() } }() ticker := time.NewTicker(cfg.RefreshInterval) for _ = range ticker.C { refreshStatsLock.Lock() startTime := time.Now() entityManager.FetchMoreContent(unixtime.Now()) logger.Printf("entityManager.FetchMoreContent() took %v", time.Since(startTime)) refreshStatsLock.Unlock() } }() } }() return entityManager }
// Creates an instance of the application user db, which stores all // user-specific data (user's personal info, watchlists, etc.). func createUserDb(dataDir string) (userDb *UserDb) { userDataFilePath := filepath.Join(dataDir, "user_data.json") if server.FileExists(userDataFilePath) { userDb = LoadUserDb(userDataFilePath) } else { logger.Printf("%v doesn't exist, so loading hardcoded test users", userDataFilePath) userDb = NewUserDb() createHardcodedUsers(userDb) } return userDb }