В настоящее время я занимаюсь разработкой игрового приложения (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 секунды.
Итак, мне нужно, чтобы задания были сериализованы, например, если у меня есть 8 из 10 очков энергии, должно пройти ровно 10 минут, пока все очки энергии не будут восполнены.
В связи с этим: пользователи имеют разные уровни и получают опыт за выполнение задач после достижения определенного порога. Их уровень повышается, и все очки энергии восполняются, независимо от того, сколько из них было использовано на предыдущем уровне, поэтому некоторые задания могут устареть к моменту их выполнения.
Учитывая несколько тысяч пользователей, работа может быть не идеальным выбором, поэтому, если у кого-то есть идея, как реализовать описанный сценарий, я буду рад любой помощи!