I have about 50-60 outbound calls to make once an hour. I have a Serverless function calling a flow API. The flow api calls a Function. And the function looks like this:
const makeCalls = (arr, callbackHandler) => {
const client = context.getTwilioClient();
let itemsProcessed = 0;
arr.forEach(item => {
client.calls.create({
url: 'https://channels.autopilot.twilio.com/v1/XXX/XXX/twilio-voice',
to: item.phone,
from: 'XXX',
}, function(err, result) {
itemsProcessed++;
if (err) { console.error(err); return; }
console.log('New phone call started...', result);
});
});
if(itemsProcessed === arr.length) { callbackHandler(); }
};
Every time I execute the script, the phone calls go out just fine, but I get a runtime application timed out error. How do I fix the issue? What am I missing? (I apologize for the janky async handling).
I figured it out. I put my janky async test in the wrong place. It should have been in the function call that returns the result.
Related
I just watched James Snell's excellent talk on Promises in Node: https://www.youtube.com/watch?v=XV-u_Ow47s0
This got me thinking about a piece of code I have that calls a web service, supplying a webhook URL, which I'm sure is suboptimal. But I don't know how I should write this correctly. To paraphrase my code:
const activeRequests = new Map();
function makeRequest(id:string) {
return new Promise(resolve => {
fetch(`http://external.com/someComplexCalculation`,
{
method:"POST",
body: { webhook:`http://myservice.com/webhook/${id}` }
})
.then(res => {
activeRequests.set(id, resolve);
});
});
}
expressApp.post('/webhook/:id', (req, res) => {
const active = activeRequests.get(req.params.id);
if (active) {
active();
}
res.sendStatus(200);
});
I've skipped all the error handling for clarity, but you get the idea. Is this the best way to do this? The end goal is for the caller of makeRequest to receive a promise that will resolve when the webhook is called.
The expected flow is that my application calls await makeRequest(xx) which calls some external service - that service then calls back to my application via the /webhook/xx URL when it is done with its processing, at which point the original makeRequest promise resolves.
I currently store the resolve function from the new Promise in a Map since I can't call that resolve function until the webhook is invoked, but that is the crux of my question: is there a better way to achieve this that doesn't involve this odd arrangement?
So I have created a Hapi.js restful application. The backend is connected to a SQlite3 database. When the user throws a GET request to any arbitrary endpoint, in this case '/employees,' I am having trouble returning the information obtained from the SQL query to the user with my current callback situation.
Here is my current code:
server.route({
method: 'GET',
path: '/employees',
handler: function(request, h) {
var employees = [];
db.all('SELECT * from Employee;',[], function (err, rows) {
if (err) {
console.log(err);
}
if (rows) {
rows.forEach(elt => {
employees.push(elt);
});
}
}, () => {
return employees.toString();
});
}
// hapi requires me to return a value or promise here
});
Right now the above code is failing because I am not returning anything at the end of the handler function. I am getting rows from my sql query but am having trouble figuring out how to return that information in the response due to my callback structure. Any help would be greatly appreciated.
It seems to me that you are not using db.all() the right way…
According to the documentation here, it seems that db.all take a callback and not two like you do…
Pretty sure your code is failing because you return in a callback that is never used...
You should try something like that:
server.route({
method: 'GET',
path: '/employees',
handler: function(request, h) {
db.all('SELECT * from Employee;',[], function (err, rows) {
if (err) {
console.log(err);
return err;
}
return rows;
});
}
});
This is a wild guess, I have never used Sqlite3 nor Hapi17 but I am pretty confident. Can you please confirm that it is working and keep my mind at peace ?
I am trying to prototype a load testing scenario on socket interactions using Mocha and should.js. I have an array of user details which I want to authenticate using socket communication and wish to verify their responses. It works fine for a single user, however when I try to loop for multiple users - I end up with issues. Had gathered some inputs based on the post:Tests from looping through async JavaScript (Mocha) .
Below is the code snippet:
var users = [{name:'A',password:'password',expected:'success'},{name:'B',password:'badPass',expected:'failure'}];
describe('socket Interaction test' , function() {
function socketInteraction(users, done) {
client.emit('userAuthentication', {'name':users.name,'password':users.password}, function(callback) {
console.log('Emit' + users.name);
});
client.on('userAuthenticationResponse', function(response) {
console.log('Resp' + response.status + 'Expected' + users.expected);
response.status.should.equal(users.expected);
done();
});
}
it('Dummy', function(done) {
describe('Mutiple login Test Async', function() {
it('User Login Test', function(done) {
users.forEach(function(users, callback) {
console.log(users.name);
socketInteraction(users, function(err) {
if (err) {
return;
}
done();
});
});
});
});
});
});
The response I get upon running the test is:
socket Interaction test
✓ Dummy
Mutiple login Test Async
A
B
RespsuccessExpectedsuccess
✓ User Login Test
RespsuccessExpectedfailure
2 passing (43ms)
The second test has to fail. Not sure where I have messed up the code. Appreciate some pointers to fix this. Thanks.
The done Parma should be called in the second param of the async.forEach. The done you call in the loop function should be callback(), to tell async that just that user is finished.
You don't have the async finished callback yet at all.
Would have posted code but am on my phone. I can add later if it's not clear.
I'm trying to write tests for my npm module, which takes care of communicating with my backend api. this module will sit inside a cordova android app, and will take care of any api calls. the issue that i'm having seems to be an understanding of mocha, but i've had a good look around the internet and can't find a solution so i turn to the masses. As an example, i have a function like
test: function() {
request.get({
url: defaultHost,
headers: {
}
}, function(err, httpResponse, body) {
if(err) {
return err;
} else {
console.log(body);
return body;
}
});
}
this works will. i'm now trying to create the test for it in mocha. the problem that i'm getting is that i have no idea how to get the return function from the .get call into the mocha test. the api returns json, so i know that i'm going to have to be doing an is equal comparison, but at the moment i can't even get it to print the results. i think the problem with is that with my other mocha tests that i can get working, they all have an argument that you pass in where as this doesn't. my current code for the test looks like this.
describe('#test', function() {
it('tests api reachability;', function() {
var test = new test();
});
});
if someone can explain what is required afterwards or even just point me in the right direction on google, that would be awesome. i'm normally pretty good at the google, but failing to find direction on this one.
I think nock will solve this issue. Let's assume you sending get request to some resource (http://domain.com/resource.json) and the tests would be like this:
var nock = require('nock');
// ...
describe('#test', function() {
beforeEach(function () {
nock('http://domain.com')
.get('resource.json')
.reply(200, {
message: 'some message'
});
});
it('tests api reachability;', function() {
var test = new test();
});
});
I have been playing with Node.js for some time.
I have the following piece of script in my server:
socket.on('auth', function(uid, key) {
client.hgetall(uid, function (err, data) {
console.log(data);
if(key != data['key']) {
socket.disconnect();
}
this.user = data;
});
});
socket.on('loginGame', function(gameId) {
checkAuth();
console.log(user);
if(!games[gameId]) {
games[gameId] = {};
}
games[gameId][uid] = uid;
});
In my client;
socket.on('connect', function(){
socket.emit('auth', 1, 1);
socket.emit('loginGame', 1);
});
When I run this code, loginGame function finishes before auth function as I am doing I/O (using redis). I know this a feature of node.js, but I think I am missing something. How can I overcome this issue as auth function needs to finish before running any function. (I have a couple of more functions which need to run in serial)
I have found a node.js module: https://github.com/creationix/step . However, is this the only option? I think this is something most node.js developer might need. I am not that good at JS either.
What is the best and most elegant way of solving this issue?
Thanks,
Have the server send back an acknowledgement when auth is successful, and send loginGame in the handler for that message.