Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pusher hangs when calling trigger on AWS Lambda (and other serverless environments) #67

Closed
steezeburger opened this issue Oct 2, 2017 · 27 comments

Comments

@steezeburger
Copy link

Are there any caveats to getting Pusher running in AWS Lambda? For some reason, my Lambda methods hang at the trigger call and time out.

@alexvazquez
Copy link

Any clue?

@gcphost
Copy link

gcphost commented Mar 1, 2018

Mine trigger but with the incorrect data.

Pusher is acting really weird for me on Lambda :(

As a test I re-wrote it using the rest api specs and it works just fine using the request package.

@leesio
Copy link
Contributor

leesio commented Apr 26, 2018

Is this still an issue for you all? If so I'll spend some time trying to get to the bottom of it!

@gcphost
Copy link

gcphost commented Apr 26, 2018

AWS has upgraded their node version since I last tested, it may no longer be an issue.

@leesio
Copy link
Contributor

leesio commented Apr 27, 2018

I ran the below on all 3 versions of node available on lambda at the moment (4.3, 6.10 and 8.10) and didn't notice anything unusual.

exports.handler = function(event, context) {
  var Pusher = require('pusher');
  var pusher = new Pusher({
    appId: process.env.APP_ID,
    key: process.env.KEY,
    secret: process.env.SECRET,
    cluster: process.env.CLUSTER,
    encrypted: true,
  });

  var msg = {message: 'hello-world'};
  pusher.trigger('channel', 'my-event', msg);
  pusher.trigger(['channel-1', 'channel-2'], 'my-event', msg);
  pusher.triggerBatch([
    {
      channel: 'batch1',
      name: 'my-event',
      data: msg,
    },
    {
      channel: 'batch1',
      name: 'my-event2',
      data: msg,
    },
  ]);
};

@kristiankyvik
Copy link

Experiencing the same problem!

@gcphost
Copy link

gcphost commented Jul 6, 2018

@kristiankyvik

I published a package that ended up working for me, I was never able to resolve the issue.

https://github.com/Askedio/pusher-lambda-promise

@kristiankyvik
Copy link

@gcphost thanks for your response. I ended up giving your package a go, worked like a charm!

@leesio
Copy link
Contributor

leesio commented Jul 10, 2018

@gcphost great work on the library!

@kristiankyvik I'm still not able to reproduce this issue, are you able to share more information on what you're experiencing? It would be great to resolve it in pusher-http-node too.

@kristiankyvik
Copy link

@Lessio, I tried using the pusher-http-node module to trigger an event in an lambda function running node 10. The trigger worked locally but failed when deployed to AWS. Still not understand why that was the case.

@kristiankyvik
Copy link

kristiankyvik commented Dec 12, 2018

Hi @leesio, I will try to explain my situation again, since the package I started using stopped working. I am running this in node 8. This is the code I have in my lambda:

export const handler = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;

  var pusher = new Pusher({
    appId: process.env.PUSHER_APP_ID,
    key: process.env.PUSHER_APP_KEY,
    secret: process.env.PUSHER_APP_SECRET,
    cluster: process.env.PUSHER_APP_CLUSTER,
    encrypted: true,
  });

  try {
    const notification = {
      type: "lab",
      datetime: moment.utc().format(),
    };
   
   pusher.trigger('channel-name', 'event-name', JSON.stringify({test: "test"}));
  } catch(err) {
    console.log("ERROR", err);
  }

  const response = {
    statusCode: 200,
    headers,
    body: JSON.stringify({
      message: `ok`
    }),
  };

  callback(null, response);
};

This works locally, but once deployed on AWS lambda, stops sending events. What am I missing?

@kristiankyvik
Copy link

So, running pusher.trigger() in an async handler once deployed won't work. I changed the handler to be synchronous and now the event is being sent. Any idea how this can be made to run in an async block?

@leesio
Copy link
Contributor

leesio commented Dec 14, 2018

@kristiankyvik that's interesting.

Does it help if you provide a callback to the trigger function and call the lambda callback inside the trigger callback? I'm imagining something like:

const response = {
  statusCode: 200,
  headers,
  body: JSON.stringify({
    message: `ok`,
  }),
};
pusher.trigger('channel-name', 'event-name', {test: 'test'}, (err, req, res) => {
  callback(null, response);
});

@benjaminbalazs
Copy link

I am going through the same issue, I can't make trigger work on Lambda. The request comes back with ECONNRESET.

@farbodsalimi
Copy link

You just need to promisify your trigger function:

const pusher = new Pusher({
  appId: process.env.PUSHER_APP_ID,
  key: process.env.PUSHER_KEY,
  secret: process.env.PUSHER_SECRET,
  cluster: "us2",
  useTLS: true
});

const asyncTrigger = msg => {
  return new Promise((resolve, reject) => {
    pusher.trigger(
      'channel-name', 
      'event-name',
      msg,
      (err, req, res) => {
        if (err) {
          reject(err);
        }
        resolve(res);
      }
    );
  });
};

const pushNotification = async msg => {
  return await asyncTrigger(msg);
};

Now in your lambda function:

await pushNotification("Hello, World!");

@kristiankyvik
Copy link

@farbodsalimi, yes that is exactly what I did and now it works like a charm!

@benjaminbalazs
Copy link

@farbodsalimi thanks, but promisifying the function also means the original request takes longer to process. That was the reason I was hoping there is a way not to wait for it to fulfill first. Interestingly, it doesn't seem to be possible on Lambda, Lambda somehow cancels the request or freeze the function.

@farbodsalimi
Copy link

farbodsalimi commented Jan 10, 2019

@benjaminbalazs What do you mean by the original request takes longer to process? If you mean you have multiple side effects, and you need to run all of them asynchronous, I don't think AWS Lambda is a good choice for you. Lambda is a simple node process, it executes your code line by line, and when it reaches the last line, it will be killed. Therefore It has no idea you have a side effect in your code and doesn't wait for that.
In general, serverless architecture is not efficient for running long-lived applications; in such cases, containers or EC2 instances are more appropriate.

@alshdavid
Copy link

alshdavid commented Apr 7, 2019

Using TypeScript this worked nicely for me

const triggerAsync = (channel: string, event: string, msg: any) => 
    new Promise((resolve, reject) =>
        pusher.trigger(channel, event, msg, 
            (err, _req, res) => err ? reject(err) : resolve(res)
        ))

@chrisdrackett
Copy link

thanks @alshdavid that worked for me!

@jameshfisher jameshfisher changed the title Pusher hangs when calling trigger on AWS Lambda Pusher hangs when calling trigger on AWS Lambda (and other serverless environments) Sep 12, 2019
@jameshfisher
Copy link
Contributor

The fix here, IMO, is:

  1. pusher.trigger should return a Promise that resolves when the HTTP response is received (i.e. at the same time that the undocumented callback is called)
  2. We should update our relevant examples to encourage people to await pusher.trigger(...), especially in serverless/Lambda examples

@jameshfisher
Copy link
Contributor

@DomVinyard
Copy link

What a weird bug, a nightmare to track down. thanks @alshdavid

owanhunte added a commit to owanhunte/unicorn-zoo that referenced this issue Jun 23, 2020
@lanlin
Copy link

lanlin commented Jun 29, 2020

the same problem, any new release?

@otterji
Copy link

otterji commented Oct 13, 2020

@alshdavid Thanks a lot.......... You made my day ! 🥳

@callum-oakley
Copy link
Contributor

This should be fixed in v4.0.0 since pusher.trigger now returns a promise, so you can

await pusher.trigger(channel, event, data)

@jameshfisher
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests