1

我目前正在开发一个游戏驱动(v. 1.2.4)应用程序,用户可以在其中执行某些任务并获得奖励。这些任务需要一些能量,这些能量会随着时间的推移而补充。基本设置如下:

public class User extends Model {
    public Long energy;
    public Long maxenergy;
    public Long cooldown = Long.valueOf(300);
}

public class Task extends Controller {
    public static void perform(Long id) {
        User user = User.findById(id).first();

        // do some complex task here...

        user.energy--;
        user.save();
        Task.list();
    }
}

现在我想在冷却时间(5 分钟)后补充用户的能量。假设用户有 10/10 能量点,我想在使用 5 分钟后重新填充点,我可以轻松地为此使用工作:

public class EnergyHealer extends Job {
    public Long id;

    public EnergyHealer(Long id) {
        this.id = id;
    }

    public void doJob() throws Exception {
        User user = User.findById(id);
        user.energy++;
        if (user.energy > user.maxenergy) {
            user.energy = user.maxenergy;
        }
        user.save()
    }
}

...并在任务完成后立即在我的控制器中调用它:

new EnergyHealer(user.id).in(user.cooldown);

我的问题是,在这种情况下,作业是同时安排的,因此如果用户在执行前一个任务后 2 秒执行任务,则第一个能量点会在 5 分钟后重新填充,而后续点仅在 2 秒后重新填充。

因此,我需要对作业进行序列化,例如,假设我有 10 个能量点中的 8 个,那么重新填充所有能量点应该需要 10 分钟

相关说明:一旦达到某个阈值,用户就有不同的级别并获得完成任务的经验。他们的等级增加,所有能量点都被重新填充,无论之前的等级使用了多少能量点,因此一些工作可能在执行时已经过时。

考虑到几千个用户,工作可能根本不是完美的选择,所以如果有人对如何实现所描述的场景有想法,我很高兴提供任何帮助!

4

1 回答 1

1

我认为你只是把你的工作安排错了。与其在每次他们执行一个动作时都开始你的工作,你应该简单地拥有一个外观或者只有在用户不存在的情况下才会开始工作的东西。

  1. 如果作业尚不存在,则创建它,否则不执行任何操作

  2. 那么这应该增加1能量,

  3. 检查能量是否已满,如果是,结束

  4. 如果没有,请暂停 5 分钟

  5. 回到 2

于 2012-05-01T06:11:51.127 回答