Enha: tx for cron
This commit is contained in:
		| @@ -29,18 +29,36 @@ func (cm *CronManager) Start() { | ||||
| } | ||||
|  | ||||
| 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) | ||||
| 	if err != nil { | ||||
| 		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 | ||||
| 	} | ||||
|  | ||||
| 	for _, room := range rooms { | ||||
| 		players, err := cm.repo.PlayerListByRoom(ctx, room.ID) | ||||
| 		if err != nil { | ||||
| 			cm.log.Error("failed to get players for room", "room_id", room.ID, "err", err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		if len(players) == 0 { | ||||
| 			cm.log.Info("deleting empty room", "room_id", room.ID) | ||||
| 			if err := cm.repo.RoomDeleteByID(ctx, room.ID); err != nil { | ||||
| @@ -48,6 +66,7 @@ func (cm *CronManager) CleanupRooms() { | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		creatorInRoom := false | ||||
| 		for _, player := range players { | ||||
| 			if player.Username == room.CreatorName { | ||||
| @@ -55,6 +74,7 @@ func (cm *CronManager) CleanupRooms() { | ||||
| 				break | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !creatorInRoom { | ||||
| 			cm.log.Info("deleting room because creator left", "room_id", room.ID) | ||||
| 			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 | ||||
| func getFullInfoByCtx(ctx context.Context) (*models.FullInfo, error) { | ||||
| 	resp := &models.FullInfo{} | ||||
| 	// state, err := getStateByCtx(ctx) | ||||
| 	state, err := getPlayerByCtx(ctx) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|   | ||||
| @@ -251,7 +251,7 @@ func HandleStartGame(w http.ResponseWriter, r *http.Request) { | ||||
|  | ||||
| func HandleJoinRoom(w http.ResponseWriter, r *http.Request) { | ||||
| 	roomID := r.URL.Query().Get("id") | ||||
| 	room, err := repo.RoomGetByID(r.Context(), roomID) | ||||
| 	room, err := repo.RoomGetExtended(r.Context(), roomID) | ||||
| 	if err != nil { | ||||
| 		abortWithError(w, err.Error()) | ||||
| 		return | ||||
|   | ||||
							
								
								
									
										4
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								main.go
									
									
									
									
									
								
							| @@ -62,20 +62,16 @@ func main() { | ||||
| 	// Setup graceful shutdown | ||||
| 	stop := make(chan os.Signal, 1) | ||||
| 	signal.Notify(stop, os.Interrupt, syscall.SIGTERM) | ||||
|  | ||||
| 	repo := repos.NewRepoProvider(cfg.DBPath) | ||||
| 	defer repo.Close() | ||||
|  | ||||
| 	cm := crons.NewCronManager(repo, slog.Default()) | ||||
| 	cm.Start() | ||||
|  | ||||
| 	server := ListenToRequests(cfg.ServerConfig.Port) | ||||
| 	go func() { | ||||
| 		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { | ||||
| 			panic(err) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| 	<-stop | ||||
| 	slog.Info("Shutting down server...") | ||||
| 	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package repos | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"gralias/models" | ||||
|  | ||||
| 	"github.com/jmoiron/sqlx" | ||||
| @@ -60,10 +61,17 @@ func (p *RepoProvider) PlayerDelete(ctx context.Context, roomID, username string | ||||
| 	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) | ||||
| 	_, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username) | ||||
| 	return err | ||||
| 	res, err := db.ExecContext(ctx, "UPDATE players SET room_id = ? WHERE username = ?", roomID, username) | ||||
| 	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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Grail Finder
					Grail Finder