Some facts we know:
- Experience notifications can only be sent within a game experience in server side.
- The current API does not support scheduled notification.
We want to schedule some notifications for daily rewards, maybe the function call looks like this:
ScheduleDailyRewardNotification(player, 1, os.time() + 1*24*60*60) -- day '1' reward, one day later
...
Suppose there are a bunch of such notifications scheduled in the past already, we want to process a bunch of them up to now os.time()
. So we naturally want to sort by the scheduled time.
In the following, I choose to use the OrderedDataStore.
local scheduledDataStore = DataStoreService:GetOrderedDataStore("ScheduledNotificationDailyReward")
local ascending = true
local pageSize = 1
local minValue = nil
local maxValue = os.time()
local pages = scheduledDataStore:GetSortedAsync(ascending, pageSize, minValue, maxValue)
while true do
for _, item in pages:GetCurrentPage() do
if not item or not item.key or not item.value then
-- in case it is processed and removed by other servers
continue
end
local success, removedValue = scheduledDataStore:RemoveAsync(item.key)
if success and removedValue then
local playerUserId, day = ParseDailyRewardFromKey(item.key)
CreateNotificationDailyReward(playerUserId, day)
end
end
if pages.IsFinished then break end
pages:AdvanceToNextPageAsync()
end
Notice that OrderedDataStore can only store a number as value, and it cannot have meta-data. we will shove other data into the key. so we can now implement ScheduleDailyRewardNotification
as follow:
function ScheduleDailyRewardNotification(player, day, scheduledTime)
local key = player.UserId .. "/" .. day
scheduledDataStore:SetAsync(key, scheduledTime)
end
And the corresponding ParseDailyRewardFromKey
:
function ParseDailyRewardFromKey(key)
local chunks = key:split("/")
local playerUserId = chunks[1]
local day = chunks[2]
return playerUserId, day
end
This theoretically works. but I am not sure how it will behave when multiple servers do the consuming at the same time, whether they would remove and consume the data in sequence and not repeat each other