Modern concurrency tools including agents, futures, promises, thread pools, supervisors, and more. Inspired by Erlang, Clojure, Scala, Go, Java, JavaScript, and classic concurrency patterns.
Thread#kill
on it.Using https://travis-ci.org/ruby-concurrency/concurrent-ruby/jobs/659471195
Rubinius
osx, Xcode: xcode8 Ruby: rbx-3.107
Hey. I have a Javascript Promise/A+ background. Trying to understand the API reference, cause it's hard to find any examples for the library usage in the Net.
The question is how to create a pending Promise?
I use multiple constructor functions like: Concurrent::Promises.future
and Concurrent::Promises.zip_futures
(aka Promise.all) and both start to invoke resolver immediately.
I want to be able to resolve explicitly with the wait
/result
/value
method.
Instead, now I need to add an unneeded condition like this:result.wait unless result.fulfilled?
Thanks.
@Hyperc0der_twitter here's a GitHub search that has plenty of code examples:
I do though think most usages are executing the promise and resolving.
Channel.go
Concurrent::Channel.go do
loop do
Concurrent::Channel.select do |s|
s.take(somechannel) {
#do something
}
s.take(otherchannel) {
# dosomething
}
end
end
end
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)
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
Promises
api to provide better support for the exact thing you are trying to achieve.
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.
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?
Concurrent::TimerTask
but my sample code would not raise error on main threadtimer_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
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