Heroku app is asleep even when receiving traffic and not waking up

Viewed 1460

I have an app (Telegram Bot actually) deployed to heroku using web dynos.

I found this information in official heroku website:

If an app has a free web dyno, and that dyno receives no web traffic in a 30-minute period, it will sleep.

If a sleeping web dyno receives web traffic, it will become active again after a short delay (assuming your account has free dyno hours available

But this case doesn't work for me. My application works only 25-35 minutes and goes to 'asleep mode' and(!) doesn't want to wake up. Only heroku restart helps.

I tested it like this:

  • Start app
  • Keep sending messages to my Telegram bot every 5 minutes (so traffic incoming)
  • App is running and keep responding
  • I fall into the gap in which the application stops responding
  • Keep sending messages but app is still silent

After this I went to my Heroku Dashboard and noticed that app is on 'asleep mode' (with zzz icon). Okay, let's check logs heroku logs --source app.

What can I see there? Almost nothing. No errors, no crashes, successful logged last message. Also my app is using MongoDB, and last log message is:

2020-07-03T14:49:20 [extShutdownHook] org.mongodb.driver.connection: Closed connection [
connectionId{localValue:4, serverValue:129573}] to botcluster-shard-00-01-aeqgg.mongodb.net:27017 because the pool has been closed.

So my connection to database was closed before the application stopped.

In addition I decided to write service class which will ping Google's webpage every 5 minutes.

public class PingTaskService {

    @Value("${pingtask.url}")
    private String url;

    @Scheduled(fixedRateString = "${pingtask.period}")
    public void keepAlive() {
        try {
            URL url = new URL(getUrl());
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            connection.disconnect();
            log.info("Ping {}, OK: response code {}", url.getHost(), connection.getResponseCode());
        } catch (IOException e) {
            log.error("Ping FAILED");
        }
    }
}

Logs:

2020-07-03T14:46:47 [scheduling-1] ru.miroha.service.PingTaskService: Ping www.google.com, OK: response code 200

3 minutes between last ping and hibernation.

I conclude that heroku just does not consider all of the above actions as web traffic.

What should I do to keep my app alive?

1 Answers

I found the solution.

I had 2 options:

  1. Switch from LongPolling (getUpdates method) to WebHook and configure Controller.
  2. Rewrite my ping task service.

I chose 2nd option because didn't want to rewrite my bot business logic.

Instead of ping google I started to ping url for my app provided by heroku. https://example.herokuapp.com/ Now my app doesn't go into sleep mode, because every 10 minutes I literally send request "from my app to my app".

Related