How to restart Heroku worker using heroku gem - heroku

I'm struggling to find how to call the equivalent of (taken from this article):
heroku restart worker.1
using the heroku gem. I see there are restart and ps_restart methods but don't see where I can specify to only restart this 1 worker and not the whole app.

Here is the command to restart any particular process
heroku ps:restart worker.1 --app APP_NAME

I'm doing specific worker restarts from within the app using a cron. Like this:
heroku = Heroku::Client.new(ENV['APP_USERNAME'], ENV['APP_PASSWORD'])
heroku.ps_restart(ENV['APP_NAME'], :ps =>'worker.1')
From the Heroku API Doc

Use the "heroku-api" gem, NOT the "heroku" gem. Using the "heroku" gem this way still works (as of today), but is deprecated. It's meant to be used via the console.
https://github.com/heroku/heroku.rb
The api gem looks very easy to use. Grab you API key from the heroku website, put it in your app config variables, and call:
require 'heroku-api'
heroku.post_ps_restart('app', 'ps' => 'web.1') # restart 'web.1' process for 'app' app

Currently, you have to take the "platform-api" gem (documentation here) from heroku because the "heroku" gem is not working anymore and the "heroku-api" gem is used to interact with the Heroku Legacy API. The Legacy API will be sunset on April 15th, 2017.
First you have to create an oAuth token via the heroku toolbelt command line tool:
$ heroku plugins:install heroku-cli-oauth
$ heroku authorizations:create -d "Platform API example token"
Created OAuth authorization.
ID: 2f01aac0-e9d3-4773-af4e-3e510aa006ca
Description: Platform API example token
Scope: global
Token: e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2
Use the Token value when instantiating a client:
require 'platform-api'
heroku = PlatformAPI.connect_oauth('e7dd6ad7-3c6a-411e-a2be-c9fe52ac7ed2')
restart a specific dyno with this command:
heroku.dyno.restart(app_id_or_app_name, dyno_id_or_dyno_name)
or restart all with this command:
heroku.dyno.restart_all(app_id_or_app_name)
You can get the ids of all your apps with
heroku.app.list
And the ids of the app's dynos via
heroku.dyno.list(app_id_or_app_name)

To expand on coderuby's answer a bit:
heroku = PlatformAPI.connect_oauth(ENV['PLATFORM_API_TOKEN'])
worker_ids = heroku.dyno
.list(ENV['HEROKU_APP_NAME'])
.select { |dyno| dyno['type'] == 'worker' }
.map { |dyno| dyno['id'] }
worker_ids.each do |id|
heroku.dyno.restart(ENV['HEROKU_APP_NAME'], id)
end
Having set the appropriate environment variables. You could include this in a rake task then have Heroku's scheduler run it when you see fit.

Related

Running "heroku ps:restart" with Heroku Scheduler or in web interface console says "heroku: command not found"

I'm trying to have my dynos restarted every 2 hours or so. I don't have a CLI connection installed or anything like that, I'd like to do this directly in the web interface with Heroku Scheduler.
The web interface has a "Run console" option in the "More" menu.
If I try to run the heroku ps:restart command there, it says:
bash: heroku: command not found
It's the same result if I try to run just ps:restart.
And the same result if I put either of those in the Heroku Scheduler.
Is there a way for me to achieve this with Heroku Scheduler?
Without setting up extra scripts and authorizations etc. as described here: Schedule Heroku to restart dynos every 10 or so minutes
The default dyno image doesn't have the Heroku CLI installed. But there is a buildpack you can add on top of your current language buildpack, and you'll have the heroku command in your app.

How to back up Heroku pg database from app itself?

From a remote shell, using the Heroku toolbelt, it's pretty easy to trigger a db backup with:
heroku pg:backups:capture --app my-app
But how can I do that from a script running on the app itself? Something triggered from the heroku scheduler or manually like:
heroku run node myScript.js --app my-app
I have psql available so maybe that's an option although I don't know where to write to.
I don't see a way to do this via API here: https://devcenter.heroku.com/articles/platform-api-reference

What is a good way to run a task whenever a Heroku app restarts?

Use case is to bust the cache.
What is a good way to run given code (or rake task) whenever a Ruby Heroku app is restarted (or deployed)?
There's no way to do this via the Heroku API far as I know. The Heroku Platform API doesn't support this.
What you can do (if you're fast, however!) is listen for a SIGTERM message in your code (that's what Heroku sends to your application process when it attempts to restart it) -- you can then fire off your script quickly.
Here's more information on SIGTERM on Heroku: https://devcenter.heroku.com/articles/dynos#graceful-shutdown-with-sigterm
If you're using some sort of CI, you can probably configure it there. Heres how to do it with CircleCI:
deployment:
production:
branch: production
commands:
- git push git#heroku.com:foo-bar-123.git $CIRCLE_SHA1:master
- heroku run rake <your task> --app <your app name>
If you're not using a CI you can still whip together a script that first does the git push to Heroku and then executes your cache busting task through heroku run (the app's bin/ folder would be an obvious place to put it).
Note: you can also use heroku run:detached, which will send output to your logs instead of stdout.
You can use "release" feature that allows you to run any command before a new release is deployed. https://devcenter.heroku.com/articles/release-phase
Define the command that should be run in your Procfile.
release: rake db:migrate
From documentation:
The release command is run immediately after a release is created, but before the release is deployed to the app’s dyno formation. That means it will be run after an event that creates a new release.

How to reach a Heroku deployment within Heroku bash or Heroku Scheduler

I'm trying to invoke a HTTP endpoint in my deployed Heroku app with Heroku Scheduler, which basically runs commands on Heroku bash at a fixed rate.
When I run $ heroku run bash, I can read my port with echo $PORT (let's say 5555). However when I try to access my webpage using curl http://localhost:5555, it does not work.
What is the way to reach to the app within Heroku bash without using the app name?
When you run "heroku run bash" you are actually firing up a one-off dyno which - according to Heroku - is a different process (from the dyno running your "web" process type) running on a different runtime instance. Routing does not exist between processes, so the HTTP requests you're issuing will always fail.
It's seems that there is no pre-configured environment variable.
However you can set it:
heroku config:add HEROKU_URL=http://<your app>.herokuapp.com

Heroku RACK_ENV says "development" on Thin, but "staging" on Unicorn

I came across this behavior and was wondering if anyone else had seen it. I have a workaround so it's not a show-stopper.
I created a new app on Heroku with a Cedar stack. When demonstrating multiple environments I added the following config var:
heroku config:add RACK_ENV=staging --app appname
I visually verified that the environment var was set, then put the following route in my simple Sinatra example:
get '/?' do
ENV['RACK_ENV']
end
When I tested locally on my laptop, I received the expected development.
When I pushed to Heroku and hit the same route on herokuapp.com I got development instead of staging.
I switched the web server from Thin to Unicorn through the Procfile and pushed the changes back up to Heroku.
Now when I hit the route, I get the expected staging.
Has anyone else seen this? My workaround on another project where I was running Thin was to key the environment off of the New Relic app name. (I didn't switch to Unicorn because I need New Relic to work and currently Cedar and New Relic and Unicorn work together).
I had the same problem with sinatra and thin on the cedar stack using heroku's example sinatra app. The RACK_ENV refuses to be set to anything but development. (Heroku seems to think that it's RACK_ENV is set, since running 'heroku config' displays the environment you set, however in the app it's always development).
The same app on the bamboo stack had no problems.
EDIT: I submitted a ticket to heroku about this and got a really quick response which fixed the bug for me:
QUOTE:
It looks like there's a small bug in our default Procfile if you're using thin. Can you create a Procfile with the following in it?
web: bundle exec thin start -R config.ru -e $RACK_ENV -p $PORT
You can also set both your RACK_ENV and RAILS_ENV to staging using the Heroku gem ... then it works as expected. I think it may be a problem with Heroku.

Resources