1

我目前正在開發基於播放的(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個能量點,那麼應該在012分鐘內完成,直到所有能量點重新填充。

在相關說明:用戶有不同的級別,並獲得完成任務的經驗,一旦達到某個閾值。他們的水平會提高,並且所有能量點都會被重新填充,不管其中有多少個已經用在上一級中,因此一些工作可能會在執行時被淘汰。

考慮到一千個用戶,工作可能並不是完美的選擇,所以如果有人對如何實現所描述的場景有想法,我很樂意爲您提供幫助!

回答

1

我想你只是把你的工作安排錯了。每次他們執行某個動作時,都不應該開始工作,而應該只是有一個外觀或者只有在用戶不存在的情況下才會開始工作的東西。

  1. 如果作業不存在,創建它,否則什麼都不做

  2. 那麼這應該加1點能量,

  3. 檢查,如果能量是滿的,如果是,結束

  4. 如果不是,暫停5分鐘

  5. 回到2

+0

韋恩,謝謝你的回答!然而,我擔心我不會理解你的解決方案,也許你可以提供一個簡短的代碼片段:1)外觀的外觀和你描述的算法是如何被觸發的; 2)我在哪裏跟蹤用戶當前的工作,例如,在收到連續的請求後,如何確定是否有作業正在運行(保持有狀態的隊列或某物)? – alexhanschke

+0

所以不是調用一個工作,而是調用一個可以檢查實體上的值的單例對象。此實體將用於確定是否有爲您的用戶運行的活動作業。根據數據庫是否說有工作正在運行,您的單身人員對象可以啓動該工作,或不啓動。 – Codemwnci

+0

明白了,謝謝! – alexhanschke