标签: concurrent-ruby

Rails中的多线程:在自动加载常量时检测到循环依赖性

我有一个Rails应用程序,其中我有一个Rake任务,它使用concurrent-ruby gem提供的多线程函数.

我不时会遇到Circular dependency detected while autoloading constant错误.

在谷歌搜索了一下后,我发现这与使用线程结合加载Rails常量有关.

我偶然发现了以下GitHub问题:https://github.com/ruby-concurrency/concurrent-ruby/issues/585https://github.com/rails/rails/issues/26847

正如这里所解释的,你需要包装从一个Rails.application.reloader.wrap do或一个Rails.application.executor.wrap do块中的新线程调用的任何代码,这就是我所做的.但是,这会导致死锁.

然后建议ActiveSupport::Dependencies.interlock.permit_concurrent_loads用于在主线程上包装另一个阻塞调用.但是,我不确定应该用哪个代码包装.

这是我尝试过的,但这仍然会导致死锁:

@beanstalk = Beaneater.new("#{ENV.fetch("HOST", "host")}:#{ENV.fetch("BEANSTALK_PORT", "11300")}")
tube_name = ENV.fetch("BEANSTALK_QUEUE_NAME", "queue")

pool = Concurrent::FixedThreadPool.new(Concurrent.processor_count * 2)

# Process jobs from tube, the body of this block gets executed on each message received
@beanstalk.jobs.register(tube_name) do |job|
    ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
      @logger.info "Received job: #{job.id}"
      Concurrent::Future.execute(executor: pool) do
        Rails.application.reloader.wrap do
          # Stuff that references Rails constants etc
          process_beanstalk_message(job.body) …
Run Code Online (Sandbox Code Playgroud)

ruby multithreading ruby-on-rails concurrent-ruby

14
推荐指数
3
解决办法
3788
查看次数

Rails 资产期间的分段错误:在 Docker 中使用 Ruby 3.3.0 在 Apple Silicon (M3) 上预编译(使用 Kamal)

当我尝试在配备 Apple Silicon (M3) 的 MacBook Pro 上为新的 Rails 应用程序构建 Docker 映像时,遇到了分段错误问题。该错误具体发生在RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompileDocker构建过程中的步骤。

一些关键点:

这个问题发生在我配备 Apple Silicon (M3) 的 MacBook 上;我无法再使用 Intel Apple 机器了。

仅构建图像amd64工作正常,表明该问题可能与 ARM 架构有关。

从 Gemfile 和代码库中删除 bootsnap 并没有解决问题。

我看到一些段错误问题表明旧版本的 Docker (4.18) 可以解决该问题,但事实并非如此。

同样,在关闭虚拟化框架的情况下切换到 gRPC FUSE 并不能解决问题。

然而,切换到 Ruby 3.2.2 解决了这个问题

Rails 应用程序非常简单,使用rails new ohanami -a propshaft -c tailwind. 您可以在此处查看失败的应用程序:https://github.com/miharekar/ohanami/tree/d2170a657a8e6e3d591436b9371e7b1f444220d5

我猜测问题出在 Ruby 3.3.0 或并发 ruby​​ 或 propshaft 中。不知道如何进一步调查,或者向哪里举报。

你建议我做什么?

这是回溯:

#16 [build 5/5] RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails …
Run Code Online (Sandbox Code Playgroud)

ruby ruby-on-rails concurrent-ruby propshaft

12
推荐指数
1
解决办法
2656
查看次数

处理并发ruby线程池中的异常

如何处理并发ruby线程池中的异常(http://ruby-concurrency.github.io/concurrent-ruby/file.thread_pools.html)?

例:

pool = Concurrent::FixedThreadPool.new(5) 
pool.post do
  raise 'something goes wrong'
end

# how to rescue this exception here
Run Code Online (Sandbox Code Playgroud)

更新:

这是我的代码的简化版本:

def process
  pool = Concurrent::FixedThreadPool.new(5)

  products.each do |product|
    new_product = generate_new_product

    pool.post do
      store_in_db(new_product) # here exception is raised, e.g. connection to db failed
    end
  end

  pool.shutdown
  pool.wait_for_terminaton
end
Run Code Online (Sandbox Code Playgroud)

所以我想要实现的是在任何异常的情况下停止处理(中断循环).

此异常也在更高级别的应用程序中获救,并且执行了一些清理作业(例如将模型状态设置为失败并发送一些通知).

ruby concurrency multithreading concurrent-ruby

8
推荐指数
1
解决办法
2146
查看次数

我应该如何使用Concurrent-Ruby限制线程创建?

我有一个进程,它使用concurrent-ruby gem来同时处理大量的API调用Concurrent::Future.execute,并且在一段时间后它会死掉:

ERROR -- : can't create Thread (11) (ThreadError)
/current/vendor/bundler_gems/ruby/2.0.0/bundler/gems/concurrent-ruby-cba3702c4e1e/lib/concurrent/executor/ruby_thread_pool_executor.rb:280:in `initialize'
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法可以告诉Concurrent它限制它产生的线程数,因为我无法预先知道它需要进行多少次API调用?

或者这是我需要在我的应用程序中明确编码的东西?

我正在使用Ruby 2.0.0(唉目前没有选择改变它)

ruby concurrency multithreading concurrent-ruby

1
推荐指数
1
解决办法
1196
查看次数