Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doing tasks before heroku nodejs server is ready

When deploying a new release, I would like my server to do some tasks before actually being released and listen to http requests.

Let's say that those tasks take around a minute and are setting some variables: until the tasks are done I would like the users to be redirected to the old release.

Basically do some nodejs work before the server is ready.

I tried a naive approach:

doSomeTasks().then(() => {
  app.listen(PORT);
})

But as soon as the new version is released, all https request during the tasks do not work instead of being redirect to old release.

I have read https://devcenter.heroku.com/articles/release-phase but this looks like I can only run an external script which is not good for me since my tasks are setting cache variables.

I know this is possible with /check_readiness on App Engine, but I was wondering for Heroku.

like image 802
httpete Avatar asked Jun 06 '19 16:06

httpete


2 Answers

You have a couple options.

  1. If the work you're doing only changes on release, you can add a task as part of your dyno build stage that will fetch and store data inside of the compiled slug that will be deployed to virtual containers on Heroku and booted as your dyno. For example, you can run a task in your build cycle that fetches data and stores/caches it as a file in your app that you read on-boot.

  2. If this data changes more frequently (e.g. daily), you can utilize “preboot” to capture and cache this data on a per-dyno basis. Depending on the data and architecture of your app you may want to be cautious with this approach when running multiple dynos as each dyno will have data that was fetched independently, thus this data may not match across instances of your application. This can lead to subtle, hard to diagnose bugs.

    This is a great option if you need to, for example, pre-cache a larger chunk of data and then fetch only new data on a per-request basis (e.g. fetch the last 1,000 posts in an RSS feed on-boot, then per request fetch anything newer—which is likely to be fewer than a few new entries—and coalesce the data to return to the client).

Here's the documentation on customizing a build process for Node.js on Heroku.

Here's the documentation for enabling and working with Preboot on Heroku

like image 144
coreyward Avatar answered Nov 15 '22 03:11

coreyward


I don't think it's a good approach to do it this way. you can use an external script ( npm script ) to do this task and then use the release phase. the situation here is very similar to running migrations you can require the needed libraries to the script you can even load all the application to the script without listening to a port let's make it clearer by example

//script file 
var client = require('cache_client');
// and here you can require all the needed libarires to the script 
// then execute your logic using sync apis 
client.setCacheVar('xyz','xyz');

then in packege.json in "scripts" add this script let assume that you named it set_cache

    "scripts": {
    "set_cache": "set_cache",
  },

now you can use npm to run this script as npm set_cache and use this command in Procfile

web: npm start 
release: npm set_cache 
like image 21
M.Elkady Avatar answered Nov 15 '22 03:11

M.Elkady