Stop Heroku Dyno from cycling - heroku

I have a Hobby Dyno that hosts an application in Heroku in which users can upload images.
What I've noticed is the Dyno restarts during his cycle causing all images to be gone.
2018-07-27T16:23:09.914767+00:00 heroku[web.1]: Cycling
2018-07-27T16:23:09.915421+00:00 heroku[web.1]: State changed from up to starting
I am aware of solutions that involve a third-party storage or host the app in another platform altogheter.
I am wondering if there is a way to stop a dyno cycle and never make it restart such as is always in the up state?
Thank you.

There is no way to prevent dyno cycling. Heroku does this automatically at least once per day.
Heroku's entire design is based on The 12-Factor App, which states that your app's processes are disposable. Heroku accomplishes this (in part) with its ephemeral file system, which is why you must persist files using an external service.

Related

How exactly do dynos/memory/processes work?

For anyone who has used Heroku (and perhaps anyone else who has deployed to an PaaS before and has experience):
I'm confused on what Heroku means by "dynos", how dynos handle memory, and how users scale. I read that they define dynos as "app containers", which means that the memory/file system of dyno1 can't be accessed by dyno2. Makes sense in theory.
The containers used at Heroku are called “dynos.” Dynos are isolated, virtualized Linux containers that are designed to execute code based on a user-specified command. (https://www.heroku.com/dynos)
Also, users can define how many dynos, or "app containers", are instantiated, if i understand correctly, through commands like heroku ps:scale web=1, etc etc.
I recently created a webapp (a Flask/gunicorn app, if that even matters), where I declare a variable that keeps track of how many users visited a certain route (I know, not the best approach, but irrelevant anyways). In local testing, it appeared to be working properly (even for multiple clients)
When I deployed to Heroku, with only a single web dyno (heroku ps:scale web=1), I found this was not the case, and that the variable appeared to have multiple instances and updated differently. I understand that memory isn't shared between different dynos, but I have only one dyno which runs the server. So I thought that there should only be a single instance of this variable/web app? Is the dyno running my server on single/multiple processes? If so, how can I limit it?
Note, this web app does save files on disk, and through each API request, I check to see if the file does exist. Because it does, this tells me that I am requesting from the same dyno.
Perhaps someone can enlighten me? I'm a beginner to deployment, but willing to learn/understand more!
Is the dyno running my server on single/multiple processes?
Yes, probably:
Gunicorn forks multiple system processes within each dyno to allow a Python app to support multiple concurrent requests without requiring them to be thread-safe. In Gunicorn terminology, these are referred to as worker processes (not to be confused with Heroku worker processes, which run in their own dynos).
We recommend setting a configuration variable for this setting. Gunicorn automatically honors the WEB_CONCURRENCY environment variable, if set.
heroku config:set WEB_CONCURRENCY=3
The WEB_CONCURRENCY environment variable is automatically set by Heroku, based on the processes’ Dyno size. This feature is intended to be a sane starting point for your application. We recommend knowing the memory requirements of your processes and setting this configuration variable accordingly.
The solution isn't to limit your processes, but to fix your application. Global variables shouldn't be used to store data across processes. Instead, store data in a database or in-memory data store.
Note, this web app does save files on disk, and through each API request, I check to see if the file does exist. Because it does, this tells me that I am requesting from the same dyno.
If you're just trying to check which dyno you're on, fine. But you probably don't want to be saving actual data to the dyno's filesystem because it is ephemeral. You'll lose all changes made to the filesystem whenever your dyno restarts. This happens frequently (at least once per day).

Is there a way to set dyno restart time in heroku?

I deployed a to-do web service in heroku.
But I didn't know that saving file is only ephemeral.
It's still fine because my to-do is only for a day.
But I want it to be reset on 4 am to maintain the data for a day
Is there anyways to manually set dyno restarting time?
Or is there some free service which provides saving besides heroku?
It is not possible to schedule the restart time.
Using the Heroku CLI I guess you can script it (meaning your computer needs to be on all the times).
Be aware that a free Dyno goes to sleep after 30 min inactivity (no incoming traffic). Once asleep the first request will make it start again.
You should look at storing the file somewhere else (save it on Google docs or Amazon S3) so you don't lose your data if the Dyno restarts.

How to keep only the worker alive on Heroku free tier from within the app?

I'm testing an app with a worker and a web dyno on Heroku free tier and I'd like to keep the worker alive to be able to execute background tasks while letting the web dyno idle. By default they both go idle in 30 mins even if I have things queued on the worker.
I understand there're ways to keep the web dyno alive (and with that the worker as well), and there're ways to keep the web alive while scaling down the worker. However I'd need the worker alive and the web in idle.
I tried running a recurring job on the worker which would
Restart the dyno.
Scale the dyno down and then back up.
Both approaches worked (as in they restarted and scaled the dyno correctly) but the worker dyno would still idle after 30 mins (as if it's dependent on the web dyno). Edit: yep, that's pretty much the case as explained here: https://devcenter.heroku.com/articles/free-dyno-hours#dyno-sleeping
I could do this form the outside but it seems I'd have to constantly check for the state since a new restart doesn't seem to give me 30 mins headway. I'd also have to expose the API key which I'd like to avoid.
If I've gotten you right, you're trying to stop the web dyno and leave the worker dyno alive.
You could do that by going to the Resources tab:
And then in the 'web' section:
Press the pencil, toggle it off and press 'Confirm'.
As a workaround I currently remove the web dyno and explicitly enable it when I need it. As explained here:
Worker-only Free dynos do not sleep since they do not respond to web
requests.
My workaround was to just create two apps that deploy automatically from the same repository. Then, all you would need to do is enable the worker dyno for one and the web dyno for the other.

Confirming Heroku Preboot

My Question:
If I see these lines in heroku logs, does that imply that preboot is disabled? If not, why not?
2015-02-04T14:48:00.674205+00:00 heroku[web.1]: State changed from up to starting
2015-02-04T14:48:00.720515+00:00 heroku[web.2]: State changed from up to starting
My understanding is that preboot should fire up brand new dynos, get them ready to serve requests, start routing requests to them, then shut down the old dynos. Nowhere in that process would I imagine dynos changing from up to starting.
The Background:
I'm working on a deploy script that automatically toggles preboot depending on whether any database changes will be made. In testing the script, I'm watching the logs hoping to determine whether preboot is actually being used when it should. I see preboot turning on in the console output of my script:
Enabling preboot for <snip>... done
Yet in the logs I am seeing what I pasted at the top. I'm trying to reconcile these facts.
One way to verify this is to watch the dyno ID number change. You can see the dyno ID by adding log-runtime-metrics to your app.
source=web.1 dyno=heroku.2808254.d97d0ea7-cf3d-411b-b453-d2943a50b456 sample#load_avg_1m=2.46 sample#load_avg_5m=1.06 sample#load_avg_15m=0.99
You can watch for that "dyno" value to change once the new dynos are accepting requests.

Heroku suitable for app based on long running processes?

I have an app which requires long running processes - typically over 2 hours (recording streaming media). Based on Heroku's website, my worker server running these processes will be restarted randomly, at least once per day.
Is there anyway to control/avoid these restarts, so as not to interrupt my long running processes?
Do other paas providers avoid this issue?
I don't know, How to control/avoid these restarts. I was also going through their documentation, They clearly state that "Dynos are also cycled at least once per day, in addition to being restarted as needed for the overall health of the system and your app."
I think, Dynos restart should only take placed when system behaves unexpected or Dynos are found in crashed state OR In month or week to clear cache memories.
You can try App42 PaaS which monitors your Apps continuously to make sure that they are up and running. If any kontena is found in crashed state, Health Monitor try to bring it back to working state. if unable than that particular kontena is deleted & replaced with a new one.
Disclaimer: I work for App42 PaaS.

Resources