Kicking off a Netlify function from within a Netlify function

Hello!

In order to split up a time-consuming task into smaller bits that can safely execute within the time limit, I’m trying to invoke a Netlify function from within a Netlify function like so:

export const handler = async (event, context) => {
  let { thingIds } = context

  // If there aren't things, get them from the DB
  if (thingIds === undefined) {
    const things = await db.thing.findMany({
      where: { isExcellent: true },
    })
    thingIds = things.map((thing) => thing.id)
  }

  // Pick a random index
  const randomIndex = Math.floor(Math.random() * thingIds.length)
  const chosenThingId = thingIds[randomIndex]

  // Get the thing
  const thing = await db.thing.findOne({
    where: { id: chosenThingId },
  })

  // Do stuff
  await doStuffToThings(thing)

  // Remove the chosen thing
  thingIds.splice(randomIndex, 1)

  // If there are still things
  if (thingIds.length) {
    // Recursively kick off a new function to do more stuff
    handler({}, { thingIds: thingIds })
  }

  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
    },
    body: thingIds,
  }
}

This works just fine in development, but I can’t seem to get it to work when deploying to Netlify. Does anyone know how I might invoke a Netlify function from within a Netlify function? Or perhaps have a recommendation for which docs I should take a closer look at? I unfortunately didn’t have much luck with initial google searches.

Thank you!

I see what you are trying to do because I thought I could do the same thing to somehow extended a 10 second function effectively N more times but chaining it.

Doesn’t really work though – but there are ways!

Or there is something like:

But that won’t really help.

First off, what you are describing is effectively a task queue and normally this “fan out” of task would be done on some queue like Sidekiq or others.

Unless you totally do not want to wait for the response of “each of your smaller tasks” you have to then wait for all of them to complete and thus you’ve made moot the point of trying to save time. You still are hanging out for the full time.

Once you return from the function with a response code - the function is done - so you cannot really do a 202 accepted and have it still run.

How I did a fan out was to use Repeater.dev and schedule out each job.

That said - it all got super easier now. Just just Netlify’s background functions:

You get an async function with up to 15 mins of runtime.

You make any function a background one by just adding “-background.js” to it.

That’s it!

It will actually be better because Netlify counts the number of function invocations so by fanning out to 1 to 100 that’s 100 calls vs a long running job function is 1.

Some tips:

1 Like

Thank you for the detailed response @dthyresson – this gives me a clear path forward!