aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorToshiaki Asai <toshi.alternative@gmail.com>2015-01-18 14:38:10 +0900
committerToshiaki Asai <toshi.alternative@gmail.com>2015-01-18 14:38:10 +0900
commit3baf68d2aac750e5879881fb2f3e6508248ad29c (patch)
tree21f415f21ba8213c76577ec5aa69222842b99449 /core
parent025631f5696e0b0290e0b755ddc7a2388c7329b4 (diff)
downloadmikutter-3baf68d2aac750e5879881fb2f3e6508248ad29c.tar.gz
イベントコールバック処理中に例外が発生した時、mikutterがクラッシュしない refs #746
Diffstat (limited to 'core')
-rw-r--r--core/event.rb24
-rw-r--r--core/lib/deferred/deferred.rb3
-rw-r--r--core/serialthread.rb3
-rw-r--r--core/service.rb6
4 files changed, 14 insertions, 22 deletions
diff --git a/core/event.rb b/core/event.rb
index 1d45b855..709678a2 100644
--- a/core/event.rb
+++ b/core/event.rb
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
require 'observer'
-miquire :lib, "instance_storage", "delayer"
+miquire :lib, "instance_storage", "delayer", 'deferred', 'serialthread'
# イベントの定義。イベントの種類を識別するためのオブジェクト。
class Event
@@ -34,7 +34,7 @@ class Event
# ==== Args
# [*args] イベントの引数
# ==== Return
- # Delayerか、イベントを待ち受けているリスナがない場合はnil
+ # self
def call(*args)
prototype = @options.has_key? :prototype
type_strict args.zip(@options[:prototype]) if prototype
@@ -45,19 +45,15 @@ class Event
changed
catch(:plugin_exit){ notify_observers(*args) } }
else
- promise = Deferred.new true
- SerialThread.new{
- filtered_args = filtering(*args)
+ filter_thread = Thread.new do
+ filtering(*args) end
+ Delayer.new do
+ filtered_args = filter_thread.join.value
+ filter_thread = nil
if filtered_args.is_a? Array
- Delayer.new(priority) {
- begin
- changed
- catch(:plugin_exit){ notify_observers(*filtered_args) }
- promise.call
- rescue Exception => e
- promise.fail e
- end } end }
- promise end
+ changed
+ catch(:plugin_exit){ notify_observers(*filtered_args) } end end
+ end
else
Delayer.new(priority) {
changed
diff --git a/core/lib/deferred/deferred.rb b/core/lib/deferred/deferred.rb
index a6f13269..c15dfa60 100644
--- a/core/lib/deferred/deferred.rb
+++ b/core/lib/deferred/deferred.rb
@@ -73,6 +73,7 @@ class Thread
result
rescue Exception => e
self.fail(e)
+ raise e
end
}
end
@@ -103,5 +104,3 @@ end
def deferred(&proc)
Deferred.new.next(&proc) end
# ~> -:4: uninitialized constant Deferred::Deferredable (NameError)
-
-
diff --git a/core/serialthread.rb b/core/serialthread.rb
index b397a191..914643bc 100644
--- a/core/serialthread.rb
+++ b/core/serialthread.rb
@@ -34,7 +34,7 @@ class SerialThreadGroup
alias new push
# 処理中なら真
- def self.busy?
+ def busy?
@thread_pool.any?{ |t| :run == t.status.to_sym } end
# 全てのserial threadの実行をキャンセルする。終了時の処理用
@@ -82,4 +82,3 @@ end
# SerialThreadGroup のインスタンス。
# 同時実行数は1固定
SerialThread = SerialThreadGroup.new
-
diff --git a/core/service.rb b/core/service.rb
index a9b4953e..e16fd324 100644
--- a/core/service.rb
+++ b/core/service.rb
@@ -3,8 +3,6 @@
miquire :core, 'environment', 'user', 'message', 'userlist', 'configloader', 'userconfig', 'service_keeper'
miquire :lib, "mikutwitter", 'reserver', 'delayer', 'instance_storage'
-Thread.abort_on_exception = true
-
=begin rdoc
Twitter APIとmikutterプラグインのインターフェイス
=end
@@ -25,7 +23,7 @@ class Service
# 存在するServiceオブジェクトをSetで返す。
# つまり、投稿権限のある「自分」のアカウントを全て返す。
- alias services instances
+ alias services instances
# Service.instances.eachと同じ
def each(*args, &proc)
@@ -103,7 +101,7 @@ class Service
__destroy_e3de__("twitter#{service.user_obj.id}".to_sym)
Plugin.call(:service_destroyed, service) end
def remove_service(service)
- destroy(service) end
+ destroy(service) end
end
# プラグインには、必要なときにはこのインスタンスが渡るようになっているので、インスタンスを