feat(resend): Re-send process improvements

This commit is contained in:
Damian Mee 2014-10-01 01:54:11 +02:00
parent f7f98d986e
commit 9ea8af28f8
3 changed files with 79 additions and 65 deletions

View file

@ -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);
};