Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Mar 06 21:41
    jcavalieri commented #903
  • Mar 06 20:41
    jcavalieri opened #903
  • Mar 05 16:18
    olleolleolle edited #901
  • Mar 05 16:17
    olleolleolle edited #901
  • Mar 05 16:17
    olleolleolle synchronize #901
  • Mar 04 17:24
    Taher-Ghaleb commented #562
  • Mar 01 09:41
    olleolleolle commented #901
  • Mar 01 09:41
    olleolleolle edited #901
  • Mar 01 09:41
    olleolleolle synchronize #901
  • Feb 15 11:13
    mhenrixon commented #639
  • Feb 11 17:56
    mhenrixon commented #829
  • Feb 08 19:48
    pitr-ch closed #902
  • Feb 08 19:48
    pitr-ch commented #902
  • Feb 08 19:48
    pitr-ch labeled #902
  • Feb 08 08:42
    GildedHonour opened #902
  • Feb 04 21:41
    stouset commented #899
  • Feb 04 19:09
    stouset commented #899
  • Jan 29 17:47
    lmarburger closed #525
  • Jan 29 08:24
    olleolleolle opened #901
  • Jan 27 08:14
    pitr-ch commented #900
Aditya C S
@adityacs
Hi All
How do we close Thread which is started by Channel.go
?
If we have code like below
Concurrent::Channel.go do
  loop do
    Concurrent::Channel.select do |s|
        s.take(somechannel) {
          #do something
         }
        s.take(otherchannel) {
          # dosomething
        }
     end
  end
end
Thread started by Channel.go is always active. Is there any way we can close this thread explicitly?
closing the channels will stop the loop and selection. However, the Channel.go thread will always remain active
Ben Sheldon (he/him)
@bensheldon_twitter
@adityacs hi! I don't have much experience with channels, but I have two questions:
  1. Have you verified the loop is broken? For example, by puts-ing a message after the loop-end. I don't see an block-breaking return or throw in what you posted.
  2. Concurrent ruby typically runs things on a global thread pool that will manage, reuse and recycle threads on its own. So if you're confident that the thread isn't doing any work, it shouldn't need to be actively killed.
Aditya C S
@adityacs
@bensheldon_twitter Yeah, the loop is broken and thread is not doing any work
Tomek Wałkuski
@tomekw
Hi all! Do you recommend any resources on testing Async and TimerTask enabled classes?
Ben Sheldon (he/him)
@bensheldon_twitter
@tomekw hi! I didn't find sources in testing, but I went towards integration testing. You could probably extract and test the task method themselves. Here's what I did with RSpec if your curious:
tuantv-0547
@tuantv-0547

Hi all. I have a problem when converting a js function to ruby, using concurrent-ruby gem.

JS code:

async function test_js(redis) {
  const arrPromises = [];

  arrPromises.push(
    redis.delAsync("key1")
  );
  arrPromises.push(
    redis.delAsync("key2")
  );

  await Promise.all(arrPromisses);
  logger.info('remove success');
}

Ruby code:

promises = []

promises << Concurrent::Promise.new do
  redis.del("key1")
end
promises << Concurrent::Promise.new do
  redis.del("key2")
end

promises.each { |j| j.execute }
Concurrent::Promise.all?(*promises).
  then{|result| puts "remove success" }.
  rescue { |reason| puts reason }.execute

I'm quite confused cause Promise.all(arrPromisses) will execute all promisses in this array at the same time, while promises.each { |j| j.execute } delay a litle bit cause they're in loop.
Is there any better way to convert this js function to ruby code?
Thank you (bow)

Mikael Henriksson
@mhenrixon

I think that first of all you should prefer the Concurrent::Promises (plural) which seems to do the trick for me.

Let’s see if I can find the code...

@tuantv-0547 I did something like this:
Concurrent::Promises.zip(*tasks).value!.flatten.compact.uniq

def tasks
  files.map do |original_file|
    Concurrent::Promises.future(original_file) { |file| process_file(file) }.rescue do |exception|
      Rails.logger.error(exception)
      Bugsnag.notify(exception)
      []
    end
  end
end

def process_file(file)
  ProcessFile.perform(file: file, dir: dir, declaration_uuid: declaration_uuid)
end
If I am not mistaken this was kind of the whole point about the Promises api to provide better support for the exact thing you are trying to achieve.
Shawn Anderson
@shawn42
Not sure if this is the right place, but can anyone here describe the roadmap of getting this PR merged: ruby-concurrency/concurrent-ruby#856 ?
It's blocking my use of concurrent-ruby in production now (which makes me sad, because concurrent-ruby is awesome!)
Aditya C S
@adityacs
Noticed a strange behaviour. Channel.select doesn't block on channels and when used within loop it consumes full cpu(single core). Created an issue here ruby-concurrency/concurrent-ruby#883.
PikachuEXE
@PikachuEXE

Hi guys!
I have read the doc about high level abstracts but I am still unable to find out what to use.
Here is my use case:

I have a sidekiq worker class that run for quite long sometimes.
Jobs and their states are persisted in database records.

class Worker
  include Sidekiq::Worker

  def perform
    prepare_job_record

    do_work_that_might_be_long

    mark_job_completed
  end
end

However since sometimes worker processes are restarted due to code release
The job record state is "stuck" on "started"
My idea is to raise error when sidekiq is detected to be "quiet" and rescue that error to update job status.
Can someone provide some advice/direction on the implementaion?

Tried Concurrent::TimerTask but my sample code would not raise error on main thread
timer_task = Concurrent::TimerTask.new(execution_interval: 1, run_now: false) do |task|
  task.execution_interval.to_i.times{ STDOUT.puts 'Boom! ' }
  STDOUT.print "\n"
  task.execution_interval += 1
  if task.execution_interval > 2
    STDOUT.puts 'Stopping...'
    raise RuntimeError.new("bye")
  end
end
timer_task.with_observer do |_time, _result, ex|
  STDOUT.puts "in observer"
  next unless ex
  STDOUT.puts ex
  if ex.is_a?(RuntimeError)
    STDOUT.puts "ex is Interrupt"
    timer_task.shutdown
    raise ex
  end
end.execute
PikachuEXE
@PikachuEXE
main_thread = ::Thread.current
timer_task = Concurrent::TimerTask.new(execution_interval: 1, run_now: false) do |task|
  $sidekiq_is_quiet.tap do |quiet|
    task.shutdown if quiet
  end
end
timer_task.with_observer do |_time, quiet|
  puts "with_observer >>"
  next unless quiet

  puts "raising"
  main_thread.raise "Sidekiq is quiet!"
end.execute
Just got this and it seems working
Kris
@drselump14
ls
Michael Kuklinski
@ameisen
Hi there!
I'm wondering if it's possible to pass an additional lock/mutex to something such as Concurrent::Array in order to more easily perform atomic tasks on multiple collections at once
such as where I need to remove something from one and add it to another, atomically
Michael Kuklinski
@ameisen
Also, is there a proper means by which to promote a ReadWriteLock in read-lock state to write-lock (and demote)?
Alex Maslakov
@GildedHonour
Why is it not found?
irb(main):001:0> require 'concurrent'
=> true

irb(main):002:0> puts "Main thread: #{Thread.current}"
Main thread: #<Thread:0x00005581cd29b428 run>
=> nil

irb(main):004:1* Concurrent::Channel.go do
irb(main):005:1*   puts "Goroutine thread: #{Thread.current}"
irb(main):006:0> end

Traceback (most recent call last):
        4: from /home/alex/.rubies/ruby-3.0.0/bin/irb:23:in `<main>'
        3: from /home/alex/.rubies/ruby-3.0.0/bin/irb:23:in `load'
        2: from /home/alex/.rubies/ruby-3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        1: from (irb):3:in `<main>'
NameError (uninitialized constant Concurrent::Channel)
Ben Sheldon (he/him)
@bensheldon_twitter
If channels are still "edge" it needs to be required directly eg require "concurrent/channels"
Oops, that should be "concurrent/channel" (singular)
Andy Maleh
@AndyObtiva

I'd hate to bother you, but I recently used 'concurrent-ruby' inside Glimmer and blogged about an example of taking advantage of it over here, leveraging thread pools: https://andymaleh.blogspot.com/2021/02/glimmer-dsl-for-swt-mandelbrot-fractal.html

Java 8 and later versions offer something even superior to thread pools called parallel streams (which build on thread pools behind the scenes as a higher abstraction), enabling my original loop implementation before parallelization (not shown in link) to work by changing a single keyword only (in Java, you switch stream() to parallelStream()) instead of instantiating a thread pool, distributing work, and waiting for it to finish.

What is the closet equivalent to Java parallel streams in "concurrent-ruby"?

Thanks and Godspeed.

Ben Sheldon (he/him)
@bensheldon_twitter

@AndyObtiva that's cool! I think the closest equivalent is a Future: https://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future

A future will implicitly run on a global thread pool, but it's also possible to pass it an explicit thread pool too.