Skip to content

Commit aea7b87

Browse files
author
Dan Perron
committed
Only return a promise if send is called without a callback.
Additionally, revert all of the other internal promise conversions.
1 parent 3353578 commit aea7b87

File tree

1 file changed

+83
-86
lines changed

1 file changed

+83
-86
lines changed

lib/sender.js

Lines changed: 83 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,33 @@ function Sender(key, options) {
2121
}
2222

2323
Sender.prototype.send = function(message, recipient, options, callback) {
24+
var rVal;
2425
if(typeof options == "function") {
2526
callback = options;
2627
options = null;
2728
}
28-
options = cleanOptions(options);
29-
30-
return getRequestBody(message, recipient)
31-
.then(function(body) {
32-
if(options.retries == 0) {
33-
return sendMessage(this.requestOptions, body);
34-
}
35-
return sendMessageWithRetries(this.requestOptions, body, options);
36-
}.bind(this))
37-
.then(function(output) {
38-
// output is in the form of [response, tokens].
39-
if (callback) {
40-
// Need to prepend output with a null for the 'err' argument.
41-
var cbArgs = Array.from(output);
42-
cbArgs.unshift(null);
43-
process.nextTick(function() {
44-
callback.apply(this, cbArgs);
45-
}.bind(this));
46-
}
47-
// Just return the response.
48-
return output[0];
49-
}, function(err) {
50-
if (callback) {
51-
process.nextTick(callback, err);
52-
} else {
53-
return Promise.reject(err);
29+
else if(!callback) {
30+
rVal = new Promise(function(resolve, reject) {
31+
callback = function(err, response) {
32+
if (err) {
33+
return reject(err);
34+
}
35+
return resolve(response);
5436
}
5537
});
38+
}
39+
options = cleanOptions(options);
40+
41+
getRequestBody(message, recipient, function(err, body) {
42+
if(err) {
43+
return callback(err);
44+
}
45+
if(options.retries == 0) {
46+
return sendMessage(this.requestOptions, body, callback);
47+
}
48+
sendMessageWithRetries(this.requestOptions, body, options, callback);
49+
}.bind(this));
50+
return rVal;
5651
};
5752

5853
function cleanOptions(options) {
@@ -80,23 +75,21 @@ function cleanOptions(options) {
8075
return options;
8176
}
8277

83-
function getRequestBody(message, recipient) {
78+
function getRequestBody(message, recipient, callback) {
8479
var body = cleanParams(message);
8580

8681
if(typeof recipient == "string") {
8782
body.to = recipient;
88-
return Promise.resolve(body);
83+
return nextTick(callback, null, body);
8984
}
9085
if(Array.isArray(recipient)) {
9186
if(recipient.length < 1) {
92-
return Promise.reject(new Error('Empty recipient array passed!'));
87+
return nextTick(callback, new Error('Empty recipient array passed!'));
9388
}
9489
body.registration_ids = recipient;
95-
return Promise.resolve(body);
90+
return nextTick(callback, null, body);
9691
}
97-
return Promise.reject(
98-
new Error('Invalid recipient (' + recipient + ', type ' + typeof recipient +
99-
') provided (must be array or string)!'));
92+
return nextTick(callback, new Error('Invalid recipient (' + recipient + ', type ' + typeof recipient + ') provided (must be array or string)!'));
10093
}
10194

10295
function cleanParams(raw) {
@@ -114,51 +107,57 @@ function cleanParams(raw) {
114107
return params;
115108
}
116109

117-
function sendMessageWithRetries(requestOptions, body, messageOptions) {
118-
return sendMessage(requestOptions, body)
119-
.then(function(output) {
120-
var response = output[0];
121-
var attemptedRegTokens = output[1];
122-
var badTokenInfo = checkForBadTokens(response.results, attemptedRegTokens);
123-
if (badTokenInfo.unsentRegTokens.length == 0) {
124-
return [response];
125-
}
110+
function nextTick(func) {
111+
var args = Array.prototype.slice.call(arguments, 1);
112+
process.nextTick(function() {
113+
func.apply(this, args);
114+
}.bind(this));
115+
}
126116

127-
debug("Retrying " + badTokenInfo.unsentRegTokens.length + " unsent registration tokens");
128-
129-
body.registration_ids = badTokenInfo.unsentRegTokens;
130-
return retry(requestOptions, body, messageOptions)
131-
.then(function(output) {
132-
var retriedResponse = output[0];
133-
response = updateResponse(response, retriedResponse, badTokenInfo.regTokenPositionMap, badTokenInfo.unsentRegTokens);
134-
return [response];
135-
}, function() {
136-
return [response];
137-
});
138-
}, function(err) {
117+
function sendMessageWithRetries(requestOptions, body, messageOptions, callback) {
118+
sendMessage(requestOptions, body, function(err, response, attemptedRegTokens) {
119+
if (err) {
139120
if (typeof err === 'number' && err > 399 && err < 500) {
140121
debug("Error 4xx -- no use retrying. Something is wrong with the request (probably authentication?)");
141-
return Promise.reject(err);
122+
return callback(err);
123+
}
124+
return retry(requestOptions, body, messageOptions, callback);
125+
}
126+
checkForBadTokens(response.results, attemptedRegTokens, function(err, unsentRegTokens, regTokenPositionMap) {
127+
if(err) {
128+
return callback(err);
129+
}
130+
if (unsentRegTokens.length == 0) {
131+
return callback(null, response);
142132
}
143-
return retry(requestOptions, body, messageOptions);
133+
134+
debug("Retrying " + unsentRegTokens.length + " unsent registration tokens");
135+
136+
body.registration_ids = unsentRegTokens;
137+
retry(requestOptions, body, messageOptions, function(err, retriedResponse) {
138+
if(err) {
139+
return callback(null, response);
140+
}
141+
response = updateResponse(response, retriedResponse, regTokenPositionMap, unsentRegTokens);
142+
callback(null, response);
143+
});
144144
});
145+
});
145146
}
146147

147-
function retry(requestOptions, body, messageOptions) {
148-
return new Promise(function(resolve) {
149-
setTimeout(resolve, messageOptions.backoff);
150-
}).then(function() {
148+
function retry(requestOptions, body, messageOptions, callback) {
149+
setTimeout(function() {
151150
if(messageOptions.retries <= 1) {
152-
return sendMessage(requestOptions, body);
151+
return sendMessage(requestOptions, body, callback);
153152
}
154-
return sendMessageWithRetries(requestOptions, body, {
153+
sendMessageWithRetries(requestOptions, body, {
155154
retries: messageOptions.retries - 1,
156155
backoff: messageOptions.backoff * 2
157-
});
158-
});
156+
}, callback);
157+
}, messageOptions.backoff);
159158
}
160159

161-
function checkForBadTokens(results, originalRecipients) {
160+
function checkForBadTokens(results, originalRecipients, callback) {
162161
var unsentRegTokens = [];
163162
var regTokenPositionMap = [];
164163
for (var i = 0; i < results.length; i++) {
@@ -167,7 +166,7 @@ function checkForBadTokens(results, originalRecipients) {
167166
unsentRegTokens.push(originalRecipients[i]);
168167
}
169168
}
170-
return {unsentRegTokens: unsentRegTokens, regTokenPositionMap: regTokenPositionMap};
169+
nextTick(callback, null, unsentRegTokens, regTokenPositionMap);
171170
}
172171

173172
function updateResponse(response, retriedResponse, regTokenPositionMap, unsentRegTokens) {
@@ -188,27 +187,25 @@ function updateResponseMetaData(response, retriedResponse, unsentRegTokens) {
188187
response.failure -= unsentRegTokens.length - retriedResponse.failure;
189188
}
190189

191-
function sendMessage(requestOptions, body) {
190+
function sendMessage(requestOptions, body, callback) {
192191
requestOptions.json = body;
193-
return new Promise(function (resolve, reject) {
194-
request(requestOptions, function (err, res, resBodyJSON) {
195-
if (err) {
196-
return reject(err);
197-
}
198-
if (res.statusCode >= 500) {
199-
debug('GCM service is unavailable (500)');
200-
return reject(res.statusCode);
201-
}
202-
if (res.statusCode === 401) {
203-
debug('Unauthorized (401). Check that your API token is correct.');
204-
return reject(res.statusCode);
205-
}
206-
if (res.statusCode !== 200) {
207-
debug('Invalid request (' + res.statusCode + '): ' + resBodyJSON);
208-
return reject(res.statusCode);
209-
}
210-
resolve([resBodyJSON, body.registration_ids || [ body.to ]]);
211-
});
192+
request(requestOptions, function (err, res, resBodyJSON) {
193+
if (err) {
194+
return callback(err);
195+
}
196+
if (res.statusCode >= 500) {
197+
debug('GCM service is unavailable (500)');
198+
return callback(res.statusCode);
199+
}
200+
if (res.statusCode === 401) {
201+
debug('Unauthorized (401). Check that your API token is correct.');
202+
return callback(res.statusCode);
203+
}
204+
if (res.statusCode !== 200) {
205+
debug('Invalid request (' + res.statusCode + '): ' + resBodyJSON);
206+
return callback(res.statusCode);
207+
}
208+
callback(null, resBodyJSON, body.registration_ids || [ body.to ]);
212209
});
213210
}
214211

0 commit comments

Comments
 (0)