Enha: tx for cron
This commit is contained in:
		| @@ -29,18 +29,36 @@ func (cm *CronManager) Start() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (cm *CronManager) CleanupRooms() { | func (cm *CronManager) CleanupRooms() { | ||||||
| 	ctx := context.Background() | 	ctx, tx, err := cm.repo.InitTx(context.Background()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		cm.log.Error("failed to init transaction", "err", err) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	defer func() { | ||||||
|  | 		if r := recover(); r != nil { | ||||||
|  | 			if err := tx.Rollback(); err != nil { | ||||||
|  | 				cm.log.Error("failed to rollback transaction", "err", err) | ||||||
|  | 			} | ||||||
|  | 			panic(r) | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
| 	rooms, err := cm.repo.RoomList(ctx) | 	rooms, err := cm.repo.RoomList(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		cm.log.Error("failed to get rooms list", "err", err) | 		cm.log.Error("failed to get rooms list", "err", err) | ||||||
|  | 		if err := tx.Rollback(); err != nil { | ||||||
|  | 			cm.log.Error("failed to rollback transaction", "err", err) | ||||||
|  | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, room := range rooms { | 	for _, room := range rooms { | ||||||
| 		players, err := cm.repo.PlayerListByRoom(ctx, room.ID) | 		players, err := cm.repo.PlayerListByRoom(ctx, room.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			cm.log.Error("failed to get players for room", "room_id", room.ID, "err", err) | 			cm.log.Error("failed to get players for room", "room_id", room.ID, "err", err) | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if len(players) == 0 { | 		if len(players) == 0 { | ||||||
| 			cm.log.Info("deleting empty room", "room_id", room.ID) | 			cm.log.Info("deleting empty room", "room_id", room.ID) | ||||||
| 			if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil { | 			if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil { | ||||||
| @@ -48,6 +66,7 @@ func (cm *CronManager) CleanupRooms() { | |||||||
| 			} | 			} | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		creatorInRoom := false | 		creatorInRoom := false | ||||||
| 		for _, player := range players { | 		for _, player := range players { | ||||||
| 			if player.Username == room.CreatorName { | 			if player.Username == room.CreatorName { | ||||||
| @@ -55,6 +74,7 @@ func (cm *CronManager) CleanupRooms() { | |||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !creatorInRoom { | 		if !creatorInRoom { | ||||||
| 			cm.log.Info("deleting room because creator left", "room_id", room.ID) | 			cm.log.Info("deleting room because creator left", "room_id", room.ID) | ||||||
| 			for _, player := range players { | 			for _, player := range players { | ||||||
| @@ -73,4 +93,9 @@ func (cm *CronManager) CleanupRooms() { | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if err := tx.Commit(); err != nil { | ||||||
|  | 		cm.log.Error("failed to commit transaction", "err", err) | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -47,41 +47,9 @@ func notifyBotIfNeeded(room *models.Room) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // cache |  | ||||||
|  |  | ||||||
| // func saveState(username string, state *models.UserState) error { |  | ||||||
| // 	key := models.CacheStatePrefix + username |  | ||||||
| // 	data, err := json.Marshal(state) |  | ||||||
| // 	if err != nil { |  | ||||||
| // 		return err |  | ||||||
| // 	} |  | ||||||
| // 	memcache.Set(key, data) |  | ||||||
| // 	return nil |  | ||||||
| // } |  | ||||||
|  |  | ||||||
| // func getAllNames() []string { |  | ||||||
| // 	names := []string{} |  | ||||||
| // 	// will not scale |  | ||||||
| // 	session := &models.Session{} |  | ||||||
| // 	// filter by key size only sessions |  | ||||||
| // 	for _, name := range wholeMemStore { |  | ||||||
| // 		// xid is 20 in len |  | ||||||
| // 		if len(k) != 20 { |  | ||||||
| // 			continue |  | ||||||
| // 		} |  | ||||||
| // 		if err := json.Unmarshal(v, &session); err != nil { |  | ||||||
| // 			log.Error("failed to unmarshal", "error", err) |  | ||||||
| // 			continue |  | ||||||
| // 		} |  | ||||||
| // 		names = append(names, session.Username) |  | ||||||
| // 	} |  | ||||||
| // 	return names |  | ||||||
| // } |  | ||||||
|  |  | ||||||
| // can room exists without state? I think no | // can room exists without state? I think no | ||||||
| func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) { | func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) { | ||||||
| 	resp := &models.FullInfo{} | 	resp := &models.FullInfo{} | ||||||
| 	// state, err := getStateByCtx(ctx) |  | ||||||
| 	state, err := getPlayerByCtx(ctx) | 	state, err := getPlayerByCtx(ctx) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
|   | |||||||
| @@ -251,7 +251,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) { | |||||||
|  |  | ||||||
| func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { | func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { | ||||||
| 	roomID := r.URL.Query().Get("id") | 	roomID := r.URL.Query().Get("id") | ||||||
| 	room, err := repo.RoomGetByID(r.Context(), roomID) | 	room, err := repo.RoomGetExtended(r.Context(), roomID) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		abortWithError(w, err.Error()) | 		abortWithError(w, err.Error()) | ||||||
| 		return | 		return | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								main.go
									
									
									
									
									
								
							| @@ -62,20 +62,16 @@ func main() { | |||||||
| 	// Setup graceful shutdown | 	// Setup graceful shutdown | ||||||
| 	stop := make(chan os.Signal, 1) | 	stop := make(chan os.Signal, 1) | ||||||
| 	signal.Notify(stop, os.Interrupt, syscall.SIGTERM) | 	signal.Notify(stop, os.Interrupt, syscall.SIGTERM) | ||||||
|  |  | ||||||
| 	repo := repos.NewRepoProvider(cfg.DBPath) | 	repo := repos.NewRepoProvider(cfg.DBPath) | ||||||
| 	defer repo.Close() | 	defer repo.Close() | ||||||
|  |  | ||||||
| 	cm := crons.NewCronManager(repo, slog.Default()) | 	cm := crons.NewCronManager(repo, slog.Default()) | ||||||
| 	cm.Start() | 	cm.Start() | ||||||
|  |  | ||||||
| 	server := ListenToRequests(cfg.ServerConfig.Port) | 	server := ListenToRequests(cfg.ServerConfig.Port) | ||||||
| 	go func() { | 	go func() { | ||||||
| 		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { | 		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { | ||||||
| 			panic(err) | 			panic(err) | ||||||
| 		} | 		} | ||||||
| 	}() | 	}() | ||||||
|  |  | ||||||
| 	<-stop | 	<-stop | ||||||
| 	slog.Info("Shutting down server...") | 	slog.Info("Shutting down server...") | ||||||
| 	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | 	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package repos | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"gralias/models" | 	"gralias/models" | ||||||
|  |  | ||||||
| 	"github.com/jmoiron/sqlx" | 	"github.com/jmoiron/sqlx" | ||||||
| @@ -60,10 +61,17 @@ func (p *RepoProvider) PlayerDelete(ctx context.Context, roomID, username string | |||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) PlayerSetRoomID(ctx context.Context, username, roomID string) error { | func (p *RepoProvider) PlayerSetRoomID(ctx context.Context, roomID, username string) error { | ||||||
| 	db := getDB(ctx, p.DB) | 	db := getDB(ctx, p.DB) | ||||||
| 	_, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username) | 	res, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username) | ||||||
| 	return err | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	affected, _ := res.RowsAffected() | ||||||
|  | 	if affected == 0 { | ||||||
|  | 		return fmt.Errorf("failed to set room_id (%s) for player (%s)", roomID, username) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (p *RepoProvider) PlayerExitRoom(ctx context.Context, username string) error { | func (p *RepoProvider) PlayerExitRoom(ctx context.Context, username string) error { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder