我目前正在开发一个游戏驱动(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 分钟。
相关说明:一旦达到某个阈值,用户就有不同的级别并获得完成任务的经验。他们的等级增加,所有能量点都被重新填充,无论之前的等级使用了多少能量点,因此一些工作可能在执行时已经过时。
考虑到几千个用户,工作可能根本不是完美的选择,所以如果有人对如何实现所描述的场景有想法,我很高兴提供任何帮助!