refactor: async/await rewards

v1.18.x
Barış Soner Uşaklı 6 years ago
parent 8b7f6566cc
commit b110aec6ed

@ -1,143 +1,80 @@
'use strict'; 'use strict';
var async = require('async'); const plugins = require('../plugins');
var plugins = require('../plugins'); const db = require('../database');
var db = require('../database'); const utils = require('../utils');
var rewards = module.exports; const rewards = module.exports;
rewards.save = function (data, callback) { rewards.save = async function (data) {
async.each(data, function save(data, next) { async function save(data) {
if (!Object.keys(data.rewards).length) { if (!Object.keys(data.rewards).length) {
return next(); return;
} }
const rewardsData = data.rewards;
var rewardsData = data.rewards;
delete data.rewards; delete data.rewards;
if (!parseInt(data.id, 10)) {
async.waterfall([ data.id = await db.incrObjectField('global', 'rewards:id');
function (next) {
if (!parseInt(data.id, 10)) {
db.incrObjectField('global', 'rewards:id', next);
} else {
next(null, data.id);
}
},
function (rid, next) {
data.id = rid;
async.series([
function (next) {
rewards.delete(data, next);
},
function (next) {
db.setAdd('rewards:list', data.id, next);
},
function (next) {
db.setObject('rewards:id:' + data.id, data, next);
},
function (next) {
db.setObject('rewards:id:' + data.id + ':rewards', rewardsData, next);
},
], next);
},
], next);
}, function (err) {
if (err) {
return callback(err);
} }
await rewards.delete(data);
await db.setAdd('rewards:list', data.id);
await db.setObject('rewards:id:' + data.id, data);
await db.setObject('rewards:id:' + data.id + ':rewards', rewardsData);
}
saveConditions(data, callback); await Promise.all(data.map(data => save(data)));
}); await saveConditions(data);
}; };
rewards.delete = function (data, callback) { rewards.delete = async function (data) {
async.parallel([ await Promise.all([
function (next) { db.setRemove('rewards:list', data.id),
db.setRemove('rewards:list', data.id, next); db.delete('rewards:id:' + data.id),
}, db.delete('rewards:id:' + data.id + ':rewards'),
function (next) { ]);
db.delete('rewards:id:' + data.id, next);
},
function (next) {
db.delete('rewards:id:' + data.id + ':rewards', next);
},
], callback);
}; };
rewards.get = function (callback) { rewards.get = async function () {
async.parallel({ return await utils.promiseParallel({
active: getActiveRewards, active: getActiveRewards,
conditions: function (next) { conditions: plugins.fireHook('filter:rewards.conditions', []),
plugins.fireHook('filter:rewards.conditions', [], next); conditionals: plugins.fireHook('filter:rewards.conditionals', []),
}, rewards: plugins.fireHook('filter:rewards.rewards', []),
conditionals: function (next) { });
plugins.fireHook('filter:rewards.conditionals', [], next);
},
rewards: function (next) {
plugins.fireHook('filter:rewards.rewards', [], next);
},
}, callback);
}; };
function saveConditions(data, callback) { async function saveConditions(data) {
var rewardsPerCondition = {}; const rewardsPerCondition = {};
async.waterfall([ await db.delete('conditions:active');
function (next) { const conditions = [];
db.delete('conditions:active', next);
},
function (next) {
var conditions = [];
data.forEach(function (reward) {
conditions.push(reward.condition);
rewardsPerCondition[reward.condition] = rewardsPerCondition[reward.condition] || [];
rewardsPerCondition[reward.condition].push(reward.id);
});
db.setAdd('conditions:active', conditions, next); data.forEach(function (reward) {
}, conditions.push(reward.condition);
function (next) { rewardsPerCondition[reward.condition] = rewardsPerCondition[reward.condition] || [];
async.each(Object.keys(rewardsPerCondition), function (condition, next) { rewardsPerCondition[reward.condition].push(reward.id);
db.setAdd('condition:' + condition + ':rewards', rewardsPerCondition[condition], next);
}, next);
},
], function (err) {
callback(err);
}); });
}
function getActiveRewards(callback) {
var activeRewards = [];
function load(id, next) { await db.setAdd('conditions:active', conditions);
async.parallel({
main: function (next) {
db.getObject('rewards:id:' + id, next);
},
rewards: function (next) {
db.getObject('rewards:id:' + id + ':rewards', next);
},
}, function (err, data) {
if (data.main) {
data.main.disabled = data.main.disabled === 'true';
data.main.rewards = data.rewards;
activeRewards.push(data.main);
}
next(err); await Promise.all(Object.keys(rewardsPerCondition).map(c => db.setAdd('condition:' + c + ':rewards', rewardsPerCondition[c])));
}); }
}
db.getSetMembers('rewards:list', function (err, rewards) { async function getActiveRewards() {
if (err) { async function load(id) {
return callback(err); const [main, rewards] = await Promise.all([
db.getObject('rewards:id:' + id),
db.getObject('rewards:id:' + id + ':rewards'),
]);
if (main) {
main.disabled = main.disabled === 'true';
main.rewards = rewards;
} }
return main;
}
async.eachSeries(rewards, load, function (err) { const rewardsList = await db.getSetMembers('rewards:list');
callback(err, activeRewards); const rewardData = await Promise.all(rewardsList.map(id => load(id)));
}); return rewardData.filter(Boolean);
});
} }
require('../promisify')(rewards); require('../promisify')(rewards);

@ -1,123 +1,78 @@
'use strict'; 'use strict';
const util = require('util');
var async = require('async');
var db = require('../database'); const db = require('../database');
var plugins = require('../plugins'); const plugins = require('../plugins');
var rewards = module.exports; const rewards = module.exports;
rewards.checkConditionAndRewardUser = function (uid, condition, method, callback) { rewards.checkConditionAndRewardUser = async function (uid, condition, method) {
callback = callback || function () {}; const isActive = await isConditionActive(condition);
if (!isActive) {
async.waterfall([ return;
function (next) { }
isConditionActive(condition, next); const ids = await getIDsByCondition(condition);
}, let rewardData = await getRewardDataByIDs(ids);
function (isActive, next) { rewardData = await filterCompletedRewards(uid, rewardData);
if (!isActive) { rewardData = rewardData.filter(Boolean);
return callback(); if (!rewardData || !rewardData.length) {
} return;
getIDsByCondition(condition, next); }
}, const eligible = await Promise.all(rewardData.map(reward => checkCondition(reward, method)));
function (ids, next) { const eligibleRewards = rewardData.filter((reward, index) => eligible[index]);
getRewardDataByIDs(ids, next); await giveRewards(uid, eligibleRewards);
},
function (rewards, next) {
filterCompletedRewards(uid, rewards, next);
},
function (rewards, next) {
if (!rewards || !rewards.length) {
return callback();
}
async.filter(rewards, function (reward, next) {
if (!reward) {
return next(null, false);
}
checkCondition(reward, method, next);
}, function (err, eligible) {
if (err || !eligible) {
return next(false);
}
giveRewards(uid, eligible, next);
});
},
], callback);
}; };
function isConditionActive(condition, callback) { async function isConditionActive(condition) {
db.isSetMember('conditions:active', condition, callback); return await db.isSetMember('conditions:active', condition);
} }
function getIDsByCondition(condition, callback) { async function getIDsByCondition(condition) {
db.getSetMembers('condition:' + condition + ':rewards', callback); return await db.getSetMembers('condition:' + condition + ':rewards');
} }
function filterCompletedRewards(uid, rewards, callback) { async function filterCompletedRewards(uid, rewards) {
async.waterfall([ const data = await db.getSortedSetRangeByScoreWithScores('uid:' + uid + ':rewards', 0, -1, 1, '+inf');
function (next) { const userRewards = {};
db.getSortedSetRangeByScoreWithScores('uid:' + uid + ':rewards', 0, -1, 1, '+inf', next);
},
function (data, next) {
var userRewards = {};
data.forEach(function (obj) { data.forEach(function (obj) {
userRewards[obj.value] = parseInt(obj.score, 10); userRewards[obj.value] = parseInt(obj.score, 10);
}); });
rewards = rewards.filter(function (reward) { return rewards.filter(function (reward) {
if (!reward) { if (!reward) {
return false; return false;
} }
var claimable = parseInt(reward.claimable, 10); const claimable = parseInt(reward.claimable, 10);
return claimable === 0 || (!userRewards[reward.id] || userRewards[reward.id] < reward.claimable); return claimable === 0 || (!userRewards[reward.id] || userRewards[reward.id] < reward.claimable);
}); });
next(null, rewards);
},
], callback);
} }
function getRewardDataByIDs(ids, callback) { async function getRewardDataByIDs(ids) {
db.getObjects(ids.map(function (id) { return await db.getObjects(ids.map(id => 'rewards:id:' + id));
return 'rewards:id:' + id;
}), callback);
} }
function getRewardsByRewardData(rewards, callback) { async function getRewardsByRewardData(rewards) {
db.getObjects(rewards.map(function (reward) { return await db.getObjects(rewards.map(reward => 'rewards:id:' + reward.id + ':rewards'));
return 'rewards:id:' + reward.id + ':rewards';
}), callback);
} }
function checkCondition(reward, method, callback) { async function checkCondition(reward, method) {
async.waterfall([ if (method.constructor && method.constructor.name !== 'AsyncFunction') {
function (next) { method = util.promisify(method);
method(next); }
}, const value = await method();
function (value, next) { const bool = await plugins.fireHook('filter:rewards.checkConditional:' + reward.conditional, { left: value, right: reward.value });
plugins.fireHook('filter:rewards.checkConditional:' + reward.conditional, { left: value, right: reward.value }, next); return bool;
},
function (bool, next) {
next(null, bool);
},
], callback);
} }
function giveRewards(uid, rewards, callback) { async function giveRewards(uid, rewards) {
async.waterfall([ const rewardData = await getRewardsByRewardData(rewards);
function (next) { await Promise.all(rewards.map(async function (reward) {
getRewardsByRewardData(rewards, next); plugins.fireHook('action:rewards.award:' + reward.rid, { uid: uid, reward: rewardData[rewards.indexOf(reward)] });
}, await db.sortedSetIncrBy('uid:' + uid + ':rewards', 1, reward.id);
function (rewardData, next) { }));
async.each(rewards, function (reward, next) {
plugins.fireHook('action:rewards.award:' + reward.rid, { uid: uid, reward: rewardData[rewards.indexOf(reward)] });
db.sortedSetIncrBy('uid:' + uid + ':rewards', 1, reward.id, next);
}, next);
},
], callback);
} }
require('../promisify')(rewards);

Loading…
Cancel
Save