feat(resend): Re-send process improvements
This commit is contained in:
parent
f7f98d986e
commit
9ea8af28f8
3 changed files with 79 additions and 65 deletions
|
|
@ -203,12 +203,12 @@ function _sendBitcoins(tx, cb) {
|
|||
);
|
||||
}
|
||||
|
||||
function executeTx(deviceFingerprint, txId, autoTriggered, cb) {
|
||||
function executeTx(deviceFingerprint, txId, triggeredByUser, cb) {
|
||||
cb = typeof cb === 'function' ? cb : function() {};
|
||||
|
||||
clearSession(deviceFingerprint);
|
||||
|
||||
// get remaining amount to be sent
|
||||
// 1. get remaining amount to be sent
|
||||
db.getPendingAmount(txId, function(err, tx) {
|
||||
if (err) {
|
||||
logger.error(err);
|
||||
|
|
@ -217,33 +217,47 @@ function executeTx(deviceFingerprint, txId, autoTriggered, cb) {
|
|||
|
||||
if (!tx) {
|
||||
logger.info('Nothing to send (%s)', txId);
|
||||
return cb(null, {statusCode: 304}); // Not Modified
|
||||
|
||||
// all bills were already sent by a timeout trigger;
|
||||
// now only mark that user's `/send` arrived
|
||||
if (triggeredByUser)
|
||||
db.changeTxStatus(txId, 'completed', {is_completed: true});
|
||||
|
||||
// indicate ACK to machine
|
||||
return cb(null, {
|
||||
statusCode: 204, // No Content
|
||||
txId: txId
|
||||
});
|
||||
}
|
||||
|
||||
db.summonTx(deviceFingerprint, tx, function(err, txInfo) {
|
||||
if (err) return cb(err);
|
||||
// indicate whether this call was initiated by user or timeout
|
||||
if (triggeredByUser)
|
||||
tx.is_completed = true;
|
||||
|
||||
// actual sending
|
||||
if (!txInfo) {
|
||||
return _sendBitcoins(tx, function(err, txHash) {
|
||||
cb(null, {
|
||||
statusCode: 201, // Created
|
||||
txHash: txHash
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Out of bitcoins: special case
|
||||
var txErr = null;
|
||||
if (txInfo.err) {
|
||||
txErr = new Error(txInfo.err);
|
||||
if (txInfo.status === 'insufficientFunds') {
|
||||
txErr.name = 'InsufficientFunds';
|
||||
// 2. BEFORE sending insert tx to a db
|
||||
db.insertTx(deviceFingerprint, tx, function(err) {
|
||||
if (err) {
|
||||
// `getPendingAmount` generated new `partial_id`, so this can occur
|
||||
// only when 2nd executeTx gets called before 1st executes it's insert
|
||||
if (err.name === 'UniqueViolation') {
|
||||
// this will calculate again and then send only "pending" coins
|
||||
return executeTx(deviceFingerprint, txId, triggeredByUser, cb);
|
||||
}
|
||||
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
pollBalance();
|
||||
cb(txErr, txInfo.txHash);
|
||||
// 3. actual sending (of the same amount, that was just inserted to the db)
|
||||
return _sendBitcoins(tx, function(err, txHash) {
|
||||
pollBalance();
|
||||
// TODO: should we indicate error to the machine here?
|
||||
|
||||
// indicate ACK to machine
|
||||
cb(null, {
|
||||
statusCode: 201, // Created
|
||||
txId: txId
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -255,7 +269,7 @@ exports.trade = function trade(rawTrade, deviceFingerprint, cb) {
|
|||
sessions[deviceFingerprint] = {
|
||||
timestamp: Date.now(),
|
||||
reaper: setTimeout(function() {
|
||||
executeTx(deviceFingerprint, rawTrade.txId, true);
|
||||
executeTx(deviceFingerprint, rawTrade.txId, false);
|
||||
}, SESSION_TIMEOUT)
|
||||
};
|
||||
}
|
||||
|
|
@ -273,7 +287,7 @@ exports.trade = function trade(rawTrade, deviceFingerprint, cb) {
|
|||
};
|
||||
|
||||
exports.sendBitcoins = function sendBitcoins(deviceFingerprint, rawTx, cb) {
|
||||
executeTx(deviceFingerprint, rawTx.txId, false, cb);
|
||||
executeTx(deviceFingerprint, rawTx.txId, true, cb);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue