如何以编程方式启动/停止rails中的heroku worker?

时间:2017-07-09 16:57:13

标签: ruby-on-rails heroku worker

大约6年前,有一个铁轨宝石瞄准了HireFire,它可以根据需要开展和停止工作,因此工作人员并不总是在跑步并且总是在收费。

HireFire似乎已经不复存在(作为一个宝石),我想知道如何像这样自动调整这样的heroku工作者?

我对为此付费服务不感兴趣。

我环顾四周,很惊讶解决方案似乎并不明显。

Heroku是否实现了这种类型的自动缩放,还是有另一个rails gem会为我做这个吗?感谢

3 个答案:

答案 0 :(得分:3)

更新:我无法找到一个现有的库/ gem /插件为我这样做,所以我决定尝试自己解决它。

在我提出解决方案之后,我决定回复此处。也许这会对其他人有所帮助。

DelayedJob有一个插件系统(我必须将我的宝石版本升级到最新版本)

这是我写的插件。我不认为它会赢得美女奖,但它似乎可以解决问题。如果我做了些蠢事,请发表评论。

我也是这样做的,它检查生产/开发环境并在开发时运行本地的DelayedJob脚本。

class HerokuWorkerDelayedJobPlugin < Delayed::Plugin
  callbacks do |lifecycle|
    lifecycle.before(:enqueue) do |job, *args, &block|
      Rails.logger.info "----before enqueue -----"
      self.start
    end

    lifecycle.after(:enqueue) do |job, *args, &block|
      Rails.logger.info "----after enqueue -----"
    end

    lifecycle.after(:invoke_job) do |job, *args, &block|
      Rails.logger.info "----after invoke_job -----"
    end

    lifecycle.after(:perform) do |worker, job, *args, &block|
      Rails.logger.info "----after perform-----"
      self.stop
    end

    def self.start
      if Rails.env.production?
        self.set_heroku_workers 1
      else
        `script/delayed_job start`
      end
    end

    def self.stop
      if Rails.env.production?
        self.set_heroku_workers 0
      else
        `script/delayed_job stop`
      end
    end

    def self.set_heroku_workers(num)
      heroku = PlatformAPI.connect_oauth(ENV['PLATFORM_API_OAUTH_TOKEN'])  #https://github.com/heroku/platform-api
      heroku.formation.update('my-app', 'worker', {quantity:   num}) #https://devcenter.heroku.com/articles/platform-api-reference#formation
    end
  end
end

您希望在初始化程序中将插件添加到DelayedJob中:

Delayed::Worker.plugins << HerokuWorkerDelayedJobPlugin

答案 1 :(得分:0)

您可以使用CLI扩展Heroku dynos,因此构建您自己的服务可以非常简单。

创建另一个使用调度程序每小时运行的应用程序,使用unix shell脚本下载并安装CLI,并使用存储为ENV变量的凭据将scale命令发送到其他应用程序。

以下是代码库作为该技术的示例:https://github.com/kbaum/heroku-database-backups

答案 2 :(得分:0)

截至2019年,Heroku的宝石是日落。因此,请改用网络API。就我而言,我使用rest-client。可以使用

从heroku cli中检索授权凭证

heroku授权:创建

          if Rails.env.production?
            response = RestClient::Request.execute(
            method: :delete,
            url: 'https://api.heroku.com/apps/yourappname/dynos/worker.1',
            headers: {Authorization: 'Bearer xxxx-xxx-xxx-xxx-xxxxx',accept:'application/vnd.heroku+json; version=3'}
            )   
          end