[#47787] Ruby Parallelism — Miguel Palhas <mpalhas@...>
Greetings
[#47790] [ruby-trunk - Bug #7097][Open] Thread locals don't work inside Enumerator — "tenderlovemaking (Aaron Patterson)" <aaron@...>
I don't have any objection.
On Fri, Oct 26, 2012 at 02:40:53PM +0900, SASADA Koichi wrote:
On Tue, Oct 02, 2012 at 03:05:17AM +0900, kosaki (Motohiro KOSAKI) wrote:
(2012/10/02 3:12), Aaron Patterson wrote:
(2012/10/02 8:22), SASADA Koichi wrote:
On Tue, Oct 02, 2012 at 08:32:51AM +0900, SASADA Koichi wrote:
>> For example:
[#47832] [ruby-trunk - Feature #7106][Open] FileUtils.touch should allow touching the symlink itself rather than the file the link points to — "cirrusthinking (Alessandro Diaferia)" <alessandro@...>
[#47841] [ruby-trunk - Bug #7109][Open] File.utime doesn't set nanoseconds — "bkabrda (Bohuslav Kabrda)" <bkabrda@...>
2012/10/5 bkabrda (Bohuslav Kabrda) <bkabrda@redhat.com>:
[#47847] [ruby-trunk - Bug #7110][Open] CGI: Add support for HTML5 <header> tag — "stomar (Marcus Stollsteimer)" <redmine@...>
[#47880] [ruby-trunk - Bug #7134][Open] Signal handling bug in Mac OS X — "auastro (Andy Kitchen)" <kitchen.andy+rubybug@...>
[#47881] [ruby-trunk - Bug #7135][Open] GC bug in Ruby 1.9.3-p194? — "alexdowad (Alex Dowad)" <alexinbeijing@...>
[#47887] [ruby-trunk - Bug #7137][Open] Date.parse overly lenient when attempting to parse Monday? — "garysweaver (Gary Weaver)" <garysweaver@...>
[#47927] new ruby 1.9.3 maintainer — "U.Nakamura" <usa@...>
Hello everyone of the Ruby development community
[#47930] [ruby-trunk - Feature #7148][Open] Improved Tempfile w/o DelegateClass — "Glass_saga (Masaki Matsushita)" <glass.saga@...>
[#47963] [ruby-trunk - Bug #7154][Open] For whatever reason \s doesn't match \u00a0. — "t0d0r (Todor Dragnev)" <todor.dragnev@...>
[#47970] [ruby-trunk - Bug #7158][Open] require is slow in its bookkeeping; can make Rails startup 2.2x faster — "gregprice (Greg Price)" <price@...>
(2012/10/28 7:10), h.shirosaki (Hiroshi Shirosaki) wrote:
Thank you for the careful work.
[#48032] [Backport93 - Backport #7174][Open] Advocating for backporting 36811 — "jonforums (Jon Forums)" <redmine@...>
[#48040] Should Hash#dup automatically rehash — Aaron Patterson <tenderlove@...>
Hi,
Hello,
On Wed, Oct 17, 2012 at 11:21:15AM +0900, U.Nakamura wrote:
[#48072] [ruby-trunk - Bug #7184][Open] --disable-gems commandline parameter does not show up with ruby -h — "steenslag (siep korteling)" <s.korteling@...>
[#48132] [ruby-trunk - Bug #7201][Open] Setting default_external affects STDIN encoding but default_internal does not — "brixen (Brian Ford)" <brixen@...>
[#48154] Patch to test_ssl to validate server-side support for SNI — Patrick Toomey <ptoomey3@...>
I recently made a pull request to JRuby (
We have incorporated Patrick's SNI patch for upcoming release JRuby
[#48191] [ANN] 2.0.0 feature freeze — Yusuke Endoh <mame@...>
Japanese later; 日本語は後で
Em 24-10-2012 09:39, Yusuke Endoh escreveu:
(2012/10/24 5:39), Yusuke Endoh wrote:
Hello ko1,
Hi,
AFAIK matz has not accepted #6636 completely yet.
Sorry, late to the party, but what's the status of #6679?
What status of #6638 <https://bugs.ruby-lang.org/issues/6638>
[#48260] [ruby-trunk - Bug #7214][Open] Ruby 2.0 breaks support for some debugging tools — "banister (john mair)" <jrmair@...>
[#48292] [ruby-trunk - Bug #7216][Open] object.c defines clone method for objects that cannot be cloned. — "therevmj (Michael Johnson)" <mj@...>
[#48315] [ruby-trunk - Bug #7220][Open] StringIO#initialize_copy causes aliasing between the objects — "brixen (Brian Ford)" <brixen@...>
[#48475] [ruby-trunk - Feature #3222] Can bignums have singleton class & methods? — "matz (Yukihiro Matsumoto)" <matz@...>
(2012/10/27 23:25), matz (Yukihiro Matsumoto) wrote:
[#48551] [ruby-trunk - Feature #7241][Open] Enumerable#to_h proposal — "nathan.f77 (Nathan Broadbent)" <nathan.f77@...>
On Tue, Oct 30, 2012 at 07:58:33PM +0900, rosenfeld (Rodrigo Rosenfeld Rosas) wrote:
Em 30-10-2012 16:23, Aaron Patterson escreveu:
[#48679] [ruby-trunk - Feature #905] Add String.new(fixnum) to preallocate large buffer — "headius (Charles Nutter)" <headius@...>
[ruby-core:48390] [ruby-trunk - Feature #6762] Control interrupt timing
Issue #6762 has been updated by ko1 (Koichi Sasada).
Assignee set to ko1 (Koichi Sasada)
It still remains naming consideration.
Comments are welcome.
And we need `signal handling' feature.
Kosaki-san, could we discuss about it at RubyConf next week?
Eric (Wong), will you attend RubyConf?
----------------------------------------
Feature #6762: Control interrupt timing
https://bugs.ruby-lang.org/issues/6762#change-31704
Author: ko1 (Koichi Sasada)
Status: Open
Priority: Normal
Assignee: ko1 (Koichi Sasada)
Category: core
Target version: 2.0.0
=begin
= Abstract
Add asynchronous interrupt timing control feature. Control with the following three modes:
* immediate: process interrupt immediately
* never: never process interrupt
* on_blocking: delay interrupt until blocking operation
# example
th = Thread.new do
Thread.control_interrupt(RuntimeError => :never) do
# in this block, thrown RuntimeError doesn't occur
end
... # raise thrown RuntimeError
end
...
th.raise "foo"
= Background
== Terminology
* Interrupt: asynchronous interrupt and corresponding procedures
* Thread#raise and occurring exception
* signal and corresponding trap
* Thread#kill and thread termination
* Main thread termination and thread termination
(after main thread termination, all threads exit themselves)
* Interrupt checking: check interrupt
* Blocking operation: Possible to block the current thread such as IO read/write. In CRuby implementation, it is nearly equals to tasks without GVL
== Current use-cases of Interrupt
There are several `Interrupt' in Ruby.
# Example 1
th = Thread.new{
begin
...
rescue FooError
...
end
}
th.raise(FooError) #=> Raise FooError on thread `th'
# Example 2
q = Queue.new
th1 = Thread.new{
q << calc_in_algorithm1
}
th2 = Thread.new{
q << calc_in_algorithm2
}
result = q.pop
th1.raise(TerminateCalcError)
th2.raise(TerminateCalcError)
# Run two algorithms simultaneously.
# If we get an answer from one algorithm,
# kill them with TerminateCalcError
# In this case, it is also okay with Thread#kill
# Example 3
trap(SIGINT){
# do something
# maybe termination process
}
trap(SIGHUP){
# do something
# maybe reloading configuration process
}
server_exec # server main process
In such interrupts are checked at several points such as:
* method invocation timing
* method returning timing
* move program counter
* before and after block operation
== Problem
Interrupt causes the following problems because we can't control occurring timing.
* Un-safe ensure clause: Generally, ensure clause should not interrupt because it contains important tasks such as freeing resources.
* Un-safe resource allocation: If interrupt occurs between resource allocation and assign it to the variable, we can't free this object (however, this problem not too big because we have a gc and appropriate finalizer can free it).
* (other problems? please complement me)
I show an example below.
# Example 4
# this method is similar implementation of timeout()
def timeout(sec)
timer_thread = Thread.new(Thread.current){|parent|
sleep(sec)
parent.raise(TimeoutError)
}
begin
yield
ensure
timer_thread.stop # close thread
end
end
timeout(3){
begin
f = # point (a)
open(...) # of course, there are no problem with open(...){|f| ...}
# but it is an example to show the problem
...
ensure
... # point (b)
f.close
end
}
On example 4, there are two problems.
Point (b) is easy to understand. If interrupt was thrown at point (b), then `f.close()' isn't called. It is problem.
On the point (a), it is a position between resource allocation (open()) and assignment `f = '. It is very rare, but it is possible. If we get interrupt before assignment, then we can't free resources (can't call f.close()) in ensure clause. It is also problem.
The problem is we can't control interrupt timing.
= Proposal
Adding interrupt timing control feature to Thread. Introduce two methods to Thread class.
* Thread.control_interrupt
* Thread.check_interrupt
Rdoc documents are:
Thread.control_interrupt():
call-seq:
Thread.control_interrupt(hash) { ... } -> result of the block
Thread.control_interrupt controls interrupt timing.
_interrupt_ means asynchronous event and corresponding procedure
by Thread#raise, Thread#kill, signal trap (not supported yet)
and main thread termination (if main thread terminates, then all
other thread will be killed).
_hash_ has pairs of ExceptionClass and TimingSymbol. TimingSymbol
is one of them:
- :immediate Invoke interrupt immediately.
- :on_blocking Invoke interrupt while _BlockingOperation_.
- :never Never invoke interrupt.
_BlockingOperation_ means that the operation will block the calling thread,
such as read and write. On CRuby implementation, _BlockingOperation_ is
operation executed without GVL.
Masked interrupts are delayed until they are enabled.
This method is similar to sigprocmask(3).
TODO (DOC): control_interrupt is stacked.
TODO (DOC): check ancestors.
TODO (DOC): to prevent all interrupt, {Object => :never} works.
NOTE: Asynchronous interrupts are difficult to use.
If you need to communicate between threads,
please consider to use another way such as Queue.
Or use them with deep understanding about this method.
# example: Guard from Thread#raise
th = Thread.new do
Thead.control_interrupt(RuntimeError => :never) {
begin
# Thread#raise doesn't interrupt here.
# You can write resource allocation code safely.
Thread.control_interrupt(RuntimeError => :immediate) {
# ...
# It is possible to be interrupted by Thread#raise.
}
ensure
# Thread#raise doesn't interrupt here.
# You can write resource dealocation code safely.
end
}
end
Thread.pass
# ...
th.raise "stop"
# example: Guard from TimeoutError
require 'timeout'
Thread.control_interrupt(TimeoutError => :never) {
timeout(10){
# TimeoutError doesn't occur here
Thread.control_interrupt(TimeoutError => :on_blocking) {
# possible to be killed by TimeoutError
# while blocking operation
}
# TimeoutError doesn't occur here
}
}
# example: Stack control settings
Thread.control_interrupt(FooError => :never) {
Thread.control_interrupt(BarError => :never) {
# FooError and BarError are prohibited.
}
}
# example: check ancestors
Thread.control_interrupt(Exception => :never) {
# all exceptions inherited from Exception are prohibited.
}
Thread.check_interrupt():
call-seq:
Thread.check_interrupt() -> nil
Check queued interrupts.
If there are queued interrupts, process respective procedures.
This method can be defined as the following Ruby code:
def Thread.check_interrupt
Thread.control_interrupt(Object => :immediate) {
Thread.pass
}
end
Examples:
th = Thread.new{
Thread.control_interrupt(RuntimeError => :on_blocking){
while true
...
# reach safe point to invoke interrupt
Thread.check_interrupt
...
end
}
}
...
th.raise # stop thread
NOTE: This example can be described by the another code.
You need to keep to avoid asynchronous interrupts.
flag = true
th = Thread.new{
Thread.control_interrupt(RuntimeError => :on_blocking){
while true
...
# reach safe point to invoke interrupt
break if flag == false
...
end
}
}
...
flag = false # stop thread
I have already commit-ed these methods into trunk.
Please try it and discuss.
This commit is easy to revert :)
Naming is also problem as usual. Good naming is also welcome.
= Acknowledgment
The base of this proposal is a discussion[1].
[1] Akira Tanaka "Re: Thread#raise, Thread#kill, and timeout.rb are
unsafe" ruty-talk (2008.3) <http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/294917>
Many dev-people help me to make up this proposal.
=end
--
http://bugs.ruby-lang.org/