tengine_core 0.5.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +40 -0
  4. data/Gemfile.lock +95 -0
  5. data/README.md +54 -0
  6. data/Rakefile +44 -0
  7. data/VERSION +1 -0
  8. data/bin/tengine_atd +8 -0
  9. data/bin/tengine_heartbeat_watchd +8 -0
  10. data/bin/tengined +182 -0
  11. data/examples/VERSION +1 -0
  12. data/examples/uc01_execute_processing_for_event.rb +11 -0
  13. data/examples/uc02_fire_another_event.rb +16 -0
  14. data/examples/uc03_2handlers_for_1event.rb +16 -0
  15. data/examples/uc08_if_both_a_and_b_occurs.rb +11 -0
  16. data/examples/uc10_if_the_event_occurs_at_the_server.rb +15 -0
  17. data/examples/uc50_commit_event_at_first.rb +17 -0
  18. data/examples/uc51_commit_event_at_first_submit.rb +29 -0
  19. data/examples/uc52_commit_event_after_all_handler_submit.rb +31 -0
  20. data/examples/uc52_never_commit_event_unless_all_handler_submit.rb +31 -0
  21. data/examples/uc60_event_in_handler.rb +18 -0
  22. data/examples/uc62_session_in_driver.rb +16 -0
  23. data/examples/uc64_safety_countup.rb +14 -0
  24. data/examples/uc70_driver_enabled_on_activation.rb +13 -0
  25. data/examples/uc71_driver_disabled_on_activation.rb +14 -0
  26. data/examples/uc72_setup_eventmachine.rb +17 -0
  27. data/examples/uc80_raise_io_error.rb +10 -0
  28. data/examples/uc81_raise_runtime_error.rb +10 -0
  29. data/examples2/driver01.rb +18 -0
  30. data/examples2/driver02.rb +19 -0
  31. data/examples2/uc08_if_both_a_and_b_occurs.rb +13 -0
  32. data/examples2/uc10_if_the_event_occurs_at_the_server.rb +18 -0
  33. data/examples2/uc51_commit_event_at_first_submit_1.rb +16 -0
  34. data/examples2/uc51_commit_event_at_first_submit_2.rb +17 -0
  35. data/examples2/uc51_commit_event_at_first_submit_3.rb +17 -0
  36. data/examples2/uc62_session_in_driver.rb +16 -0
  37. data/examples2/uc71_driver_disabled_on_activation.rb +16 -0
  38. data/failure_examples/VERSION +1 -0
  39. data/failure_examples/uc53_submit_outside_of_handler.rb +15 -0
  40. data/failure_examples/uc61_event_outside_of_handler.rb +12 -0
  41. data/failure_examples/uc63_session_outside_of_driver.rb +13 -0
  42. data/lib/tengine/core.rb +74 -0
  43. data/lib/tengine/core/bootstrap.rb +123 -0
  44. data/lib/tengine/core/collection_accessible.rb +34 -0
  45. data/lib/tengine/core/config.rb +10 -0
  46. data/lib/tengine/core/config/atd.rb +225 -0
  47. data/lib/tengine/core/config/core.rb +319 -0
  48. data/lib/tengine/core/config/heartbeat_watcher.rb +229 -0
  49. data/lib/tengine/core/connection_test/.gitignore +1 -0
  50. data/lib/tengine/core/connection_test/fire_bar_on_foo.rb +16 -0
  51. data/lib/tengine/core/driveable.rb +213 -0
  52. data/lib/tengine/core/driver.rb +69 -0
  53. data/lib/tengine/core/driver/finder.rb +42 -0
  54. data/lib/tengine/core/dsl_evaluator.rb +110 -0
  55. data/lib/tengine/core/dsl_filter_def.rb +11 -0
  56. data/lib/tengine/core/dsl_loader.rb +108 -0
  57. data/lib/tengine/core/event.rb +145 -0
  58. data/lib/tengine/core/event/finder.rb +82 -0
  59. data/lib/tengine/core/event_exception_reportable.rb +88 -0
  60. data/lib/tengine/core/event_wrapper.rb +21 -0
  61. data/lib/tengine/core/find_by_name.rb +31 -0
  62. data/lib/tengine/core/handler.rb +152 -0
  63. data/lib/tengine/core/handler_path.rb +33 -0
  64. data/lib/tengine/core/heartbeat_watcher.rb +161 -0
  65. data/lib/tengine/core/io_to_logger.rb +22 -0
  66. data/lib/tengine/core/kernel.rb +510 -0
  67. data/lib/tengine/core/kernel_runtime.rb +91 -0
  68. data/lib/tengine/core/method_traceable.rb +38 -0
  69. data/lib/tengine/core/mongoid_fix.rb +19 -0
  70. data/lib/tengine/core/mutex.rb +177 -0
  71. data/lib/tengine/core/optimistic_lock.rb +69 -0
  72. data/lib/tengine/core/plugins.rb +54 -0
  73. data/lib/tengine/core/schedule.rb +21 -0
  74. data/lib/tengine/core/scheduler.rb +156 -0
  75. data/lib/tengine/core/selectable_attr.rb +29 -0
  76. data/lib/tengine/core/session.rb +21 -0
  77. data/lib/tengine/core/session_wrapper.rb +68 -0
  78. data/lib/tengine/core/setting.rb +21 -0
  79. data/lib/tengine/core/validation.rb +36 -0
  80. data/lib/tengine/errors.rb +18 -0
  81. data/lib/tengine/rspec.rb +8 -0
  82. data/lib/tengine/rspec/context_wrapper.rb +51 -0
  83. data/lib/tengine/rspec/extension.rb +53 -0
  84. data/lib/tengine_core.rb +23 -0
  85. data/spec/factories/tengine_core_drivers.rb +10 -0
  86. data/spec/factories/tengine_core_events.rb +14 -0
  87. data/spec/factories/tengine_core_handler_paths.rb +9 -0
  88. data/spec/factories/tengine_core_handlers.rb +9 -0
  89. data/spec/factories/tengine_core_sessions.rb +9 -0
  90. data/spec/mongoid.yml +35 -0
  91. data/spec/spec_helper.rb +48 -0
  92. data/spec/support/mongo_index_key_log.rb +91 -0
  93. data/spec/tengine/core/bootstrap_spec.rb +278 -0
  94. data/spec/tengine/core/bugfix/bind_dsl_file_in_multi_byte_dir_spec.rb +21 -0
  95. data/spec/tengine/core/bugfix/enabled_on_activation_spec.rb +112 -0
  96. data/spec/tengine/core/bugfix/receive_event_spec.rb +133 -0
  97. data/spec/tengine/core/bugfix/use_dsl_version_method.rb +12 -0
  98. data/spec/tengine/core/bugfix/use_dsl_version_method_spec.rb +28 -0
  99. data/spec/tengine/core/bugfix/use_event_in_handler_dsl.rb +11 -0
  100. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/206/343/202/231/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215/source_location_encoding.rb +35 -0
  101. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/206/343/202/231/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215//351/235/236ASCII/343/201/256/343/203/225/343/202/241/343/202/244/343/203/253/345/220/215_dsl.rb +38 -0
  102. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/207/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215/source_location_encoding.rb +35 -0
  103. data/spec/tengine/core/bugfix//351/235/236ACSII/343/201/256/343/203/207/343/202/243/343/203/254/343/202/257/343/203/210/343/203/252/345/220/215//351/235/236ASCII/343/201/256/343/203/225/343/202/241/343/202/244/343/203/253/345/220/215_dsl.rb +38 -0
  104. data/spec/tengine/core/config/atd_spec.rb +62 -0
  105. data/spec/tengine/core/config/core_spec.rb +479 -0
  106. data/spec/tengine/core/config/heartbeat_watcher_spec.rb +62 -0
  107. data/spec/tengine/core/config/syntax_error_in_erb.yml.erb +13 -0
  108. data/spec/tengine/core/config/wrong_category_name.yml.erb +13 -0
  109. data/spec/tengine/core/config/wrong_field_name.yml.erb +12 -0
  110. data/spec/tengine/core/config/wrong_yaml.yml.erb +13 -0
  111. data/spec/tengine/core/config_spec/another_port.yml +54 -0
  112. data/spec/tengine/core/config_spec/config_with_dir_absolute_load_path.yml +16 -0
  113. data/spec/tengine/core/config_spec/config_with_dir_relative_load_path.yml +16 -0
  114. data/spec/tengine/core/config_spec/config_with_file_absolute_load_path.yml +16 -0
  115. data/spec/tengine/core/config_spec/config_with_file_relative_load_path.yml +16 -0
  116. data/spec/tengine/core/config_spec/log_config_spec.rb +235 -0
  117. data/spec/tengine/core/driveable_spec.rb +240 -0
  118. data/spec/tengine/core/driver_spec.rb +159 -0
  119. data/spec/tengine/core/dsl_loader_spec.rb +172 -0
  120. data/spec/tengine/core/dsls/uc08_if_both_a_and_b_occurs_spec.rb +35 -0
  121. data/spec/tengine/core/dsls/uc10_if_the_event_occurs_at_the_server_spec.rb +58 -0
  122. data/spec/tengine/core/dsls/uc50_commit_event_at_first_spec.rb +29 -0
  123. data/spec/tengine/core/dsls/uc52_commit_event_after_all_handler_submit_spec.rb +33 -0
  124. data/spec/tengine/core/dsls/uc52_never_commit_event_unless_all_handler_submit_spec.rb +37 -0
  125. data/spec/tengine/core/dsls/uc53_submit_outside_of_handler_spec.rb +37 -0
  126. data/spec/tengine/core/dsls/uc60_event_in_handler_spec.rb +31 -0
  127. data/spec/tengine/core/dsls/uc61_event_outside_of_handler_spec.rb +37 -0
  128. data/spec/tengine/core/dsls/uc62_session_in_driver_spec.rb +36 -0
  129. data/spec/tengine/core/dsls/uc63_session_outside_of_driver_spec.rb +35 -0
  130. data/spec/tengine/core/dsls/uc64_safety_countup_spec.rb +134 -0
  131. data/spec/tengine/core/dsls/uc70_driver_enabled_on_activation_spec.rb +39 -0
  132. data/spec/tengine/core/dsls/uc71_driver_disabled_on_activation_spec.rb +36 -0
  133. data/spec/tengine/core/dsls/uc72_setup_eventmachine_spec.rb +39 -0
  134. data/spec/tengine/core/dsls/uc80_raise_io_error_spec.rb +53 -0
  135. data/spec/tengine/core/dsls/uc81_raise_runtime_error_spec.rb +49 -0
  136. data/spec/tengine/core/event/finder_spec.rb +136 -0
  137. data/spec/tengine/core/event_exception_reportable_spec.rb +33 -0
  138. data/spec/tengine/core/event_spec.rb +161 -0
  139. data/spec/tengine/core/event_wrapper_spec.rb +35 -0
  140. data/spec/tengine/core/handler_path_spec.rb +87 -0
  141. data/spec/tengine/core/handler_spec.rb +190 -0
  142. data/spec/tengine/core/heartbeat_watcher_spec.rb +131 -0
  143. data/spec/tengine/core/io_to_logger_spec.rb +30 -0
  144. data/spec/tengine/core/kernel_spec.rb +885 -0
  145. data/spec/tengine/core/mutex_spec.rb +184 -0
  146. data/spec/tengine/core/optimistic_lock_spec.rb +55 -0
  147. data/spec/tengine/core/scheculer_spec.rb +121 -0
  148. data/spec/tengine/core/selectable_attr_spec.rb +30 -0
  149. data/spec/tengine/core/session_spec.rb +104 -0
  150. data/spec/tengine/core/setting_spec.rb +79 -0
  151. data/spec/tengine/core_spec.rb +13 -0
  152. data/spec/tengine_spec.rb +14 -0
  153. data/tengine_core.gemspec +248 -0
  154. data/tmp/log/.gitignore +1 -0
  155. data/tmp/tengined_status/.gitignore +1 -0
  156. metadata +421 -0
@@ -0,0 +1 @@
1
+ /VERSION
@@ -0,0 +1,16 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/core'
3
+
4
+ class << Tengine
5
+ attr_accessor :callback_for_test
6
+ end
7
+
8
+ driver :connection_test_driver do
9
+ on :foo do
10
+ Tengine.callback_for_test.call(:foo) if Tengine.callback_for_test
11
+ fire :bar
12
+ end
13
+ on :bar do
14
+ Tengine.callback_for_test.call(:bar) if Tengine.callback_for_test
15
+ end
16
+ end
@@ -0,0 +1,213 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/core'
3
+ require 'active_support/core_ext/kernel/singleton_class'
4
+
5
+ # イベントドライバ定義モジュール
6
+ #
7
+ module Tengine::Core::Driveable
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ @__context__ = self.singleton_class
12
+ @__context__.extend(ClassMethods)
13
+ @__context__.instance_eval do
14
+ def driver; @driver; end
15
+ def driver=(val); @driver = val; end
16
+
17
+ def __on_args__; @__on_args__; end
18
+ def __on_args__=(val); @__on_args__ = val; end
19
+
20
+ def __creating_driver__; @__creating_driver__; end
21
+ def __creating_driver__=(val); @__creating_driver__ = val; end
22
+ end
23
+
24
+ driver = nil
25
+ if @__context__.__creating_driver__ = self.driver.nil? # ==比較じゃなくて、代入した結果で条件分岐してます
26
+ config = @__context__.respond_to?(:config) ? @__context__.config : nil
27
+ options = @__context__.respond_to?(:options) ? @__context__.options : {}
28
+ driver = Tengine::Core::Driver.new({
29
+ :name => self.driver_name, # self.name.gsub(/:/, 'Colon'),
30
+ :version => Tengine::Core::Setting.dsl_version,
31
+ :enabled => config ? !config[:tengined][:skip_enablement] : true, # driverを有効化して登録するかのオプション
32
+ :enabled_on_activation => options[:enabled_on_activation].nil? || options[:enabled_on_activation], # DSLに記述されているオプション
33
+ :target_class_name => self.name,
34
+ })
35
+ driver.create_session
36
+ begin
37
+ driver.save!
38
+ rescue Mongoid::Errors::Validations => e
39
+ raise e unless e.document.errors[:name].any?{|s| s =~ /taken/}
40
+ Tengine::Core.stdout_logger.debug("[#{Process.pid}] Occured #{e.inspect}")
41
+ driver = Tengine::Core::Driver.where(:name => self.driver_name, :version => Tengine::Core::Setting.dsl_version).first
42
+ rescue Mongo::OperationFailure => e
43
+ raise e unless e.message =~ /E11000 duplicate key error/
44
+ Tengine::Core.stdout_logger.debug("[#{Process.pid}] Occured #{e.inspect}")
45
+ driver = Tengine::Core::Driver.where(:name => self.driver_name, :version => Tengine::Core::Setting.dsl_version).first
46
+ end
47
+ end
48
+ @__context__.driver = driver || self.driver
49
+
50
+ def self.method_added(method_name)
51
+ return unless @__context__.__on_args__
52
+ args = @__context__.__on_args__
53
+ @__context__.__on_args__ = nil
54
+ return unless @__context__.__creating_driver__
55
+ driver = @__context__.driver
56
+ driver.reload
57
+ options = args.extract_options!
58
+ handler = driver.handlers.create!({
59
+ :event_type_names => args,
60
+ :target_instantiation_key => :instance_method,
61
+ :target_method_name => method_name.to_s
62
+ }.update(options))
63
+ args.each do |event_type_name|
64
+ driver.handler_paths.create!(:event_type_name => event_type_name, :handler_id => handler.id)
65
+ end
66
+ end
67
+
68
+ def self.singleton_method_added(method_name)
69
+ return if method_name == :singleton_method_added
70
+ # def self.hoge... と class << self; def baz...; end ではselfが異なる
71
+ # (前者はclass自身、後者はclassのsingleton_classになる)ので、差異を吸収するために
72
+ # selfが前者の場合@__context__には後者への参照が設定されており、
73
+ # selfが後者の場合には、@__context__はnilなので、selfを使うことによって
74
+ # 同じインスタンスの__on_args__を使用することが可能になります。
75
+ context = @__context__ || self
76
+ return unless context.__on_args__
77
+ args = context.__on_args__
78
+ context.__on_args__ = nil
79
+ return unless @__context__.__creating_driver__
80
+ driver = context.driver
81
+ driver.reload
82
+ options = args.extract_options!
83
+ handler = driver.handlers.create!({
84
+ :event_type_names => args,
85
+ :target_instantiation_key => :static,
86
+ :target_method_name => method_name.to_s
87
+ }.update(options))
88
+ # puts "handler: #{handler.inspect}\n#{args.inspect}"
89
+ args.each do |event_type_name|
90
+ driver.handler_paths.create!(:event_type_name => event_type_name, :handler_id => handler.id)
91
+ end
92
+ end
93
+ end
94
+
95
+ module ClassMethods
96
+ def driver_name
97
+ return nil if self.name.nil?
98
+ (self < Tengine::Core::Driveable::ByDsl) ? self.name.underscore : self.name
99
+ end
100
+
101
+ def driver
102
+ unless @driver
103
+ driver_attrs = {
104
+ :name => self.driver_name, # self.name.gsub(/:/, 'Colon'),
105
+ :version => Tengine::Core::Setting.dsl_version
106
+ }
107
+ @driver = Tengine::Core::Driver.first(:conditions => driver_attrs)
108
+ end
109
+ @driver
110
+ end
111
+
112
+ def session
113
+ @__session_wrapper__ ||= Tengine::Core::SessionWrapper.new(driver.session)
114
+ end
115
+
116
+ def on(*args, &block)
117
+ context = @__context__ || self
118
+ options = args.extract_options!
119
+ event_type_names = args
120
+ if block
121
+ filepath, lineno = *block.source_location
122
+ filepath = context.config.relative_path_from_dsl_dir(filepath.dup.force_encoding(Encoding.default_external).freeze)
123
+ options.update(:filepath => filepath, :lineno => lineno)
124
+ filter_def = nil
125
+ handler = nil
126
+ if event_type_names.length == 1 && event_type_names.first.is_a?(Tengine::Core::DslFilterDef)
127
+ filter_def = event_type_names.first
128
+ options[:filter] = filter_def.filter
129
+ event_type_names = filter_def.event_type_names
130
+ base_method_name = event_type_names.map(&:to_s).join("_")
131
+ driver = context.driver
132
+ driver.reload
133
+ handler = driver.handlers.new({
134
+ :event_type_names => event_type_names,
135
+ :target_instantiation_key => :instance_method,
136
+ }.update(options))
137
+ # フィルタ付きの場合は単純なイベントハンドラ名だけではメソッド名として表現できないので
138
+ # handler自身のIDをメソッド名に含めます。
139
+ method_name = "#{base_method_name}_#{handler.id.to_s}"
140
+ handler.target_method_name = method_name.to_s
141
+ handler.save!
142
+ event_type_names.each do |event_type_name|
143
+ driver.handler_paths.create!(:event_type_name => event_type_name, :handler_id => handler.id)
144
+ end
145
+ else
146
+ method_name = event_type_names.map(&:to_s).join("_")
147
+ context.__on_args__ = event_type_names.map(&:to_s) + [options]
148
+ end
149
+ case block.arity
150
+ when 1 then
151
+ define_method(method_name, &block)
152
+ when 0 then
153
+ impl_method_name = "__#{method_name}_impl__"
154
+ self.instance_eval do
155
+ define_method(method_name) do |event|
156
+ @__event__ = event
157
+ begin
158
+ send(impl_method_name)
159
+ ensure
160
+ @__event__ = nil
161
+ end
162
+ end
163
+ define_method(impl_method_name, &block)
164
+ end
165
+ else
166
+ raise Tengine::Core::DslError, "#{block.artity} aritties block given"
167
+ end
168
+ # handler.save! if handler
169
+ else
170
+ filepath, lineno = *caller.first.sub(/:in.+\Z/, '').split(/:/, 2)
171
+ options.update(:filepath => filepath, :lineno => lineno)
172
+ context.__on_args__ = ( args + [options] )
173
+ end
174
+ end
175
+ end
176
+
177
+ def session
178
+ self.class.session
179
+ end
180
+
181
+ def event
182
+ @__event_wrapper__ ||= (@__event__ ? Tengine::Core::EventWrapper.new(@__event__) : nil)
183
+ end
184
+
185
+ def kernel
186
+ ev = @__event__
187
+ ev ? ev.kernel : nil
188
+ end
189
+
190
+ def ack?; kernel.ack?; end
191
+ def submit; kernel.submit; end
192
+
193
+ def fire(*args, &block)
194
+ kernel.fire(*args, &block)
195
+ end
196
+
197
+
198
+ module ByDsl
199
+ extend ActiveSupport::Concern
200
+
201
+ included do
202
+ @__context__ = self.singleton_class
203
+ @__context__.instance_eval do
204
+ def config; @config; end
205
+ def config=(val); @config = val; end
206
+
207
+ def options; @options; end
208
+ def options=(val); @options = val; end
209
+ end
210
+ end
211
+ end
212
+
213
+ end
@@ -0,0 +1,69 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/core'
3
+
4
+ # イベントドライバ
5
+ #
6
+ # イベントに対する処理はイベントハンドラによって実行されますが、イベントドライバはそのイベントハンドラの上位の概念です。
7
+ # イベントハンドラは必ずイベントドライバの中に定義されます。
8
+ #
9
+ # またイベントドライバは有効化/無効化を設定する単位であり、起動時の設定あるいはユーザーの指定によって変更することができます。
10
+ #
11
+ class Tengine::Core::Driver
12
+ autoload :Finder, 'tengine/core/driver/finder'
13
+
14
+ include Mongoid::Document
15
+ include Mongoid::Timestamps
16
+ include Tengine::Core::Validation
17
+ include Tengine::Core::FindByName
18
+
19
+ # @attribute 名前
20
+ field :name, :type => String
21
+
22
+ # @attribute バージョン。デプロイされた際に設定されます。
23
+ field :version, :type => String
24
+
25
+ # @attribute 有効/無効
26
+ field :enabled, :type => Boolean
27
+
28
+ # @attribute 実行時有効/無効
29
+ field :enabled_on_activation, :type => Boolean, :default => true
30
+
31
+ # @attribute 対象クラス名
32
+ field :target_class_name, :type => String
33
+
34
+ index([ [:_id, Mongo::ASCENDING], [:enabled, Mongo::ASCENDING], [:version, Mongo::ASCENDING], ])
35
+ index([ [:name, Mongo::ASCENDING], [:version, Mongo::ASCENDING], ], :unique => true)
36
+ index([ [:version, Mongo::ASCENDING], [:enabled_on_activation, Mongo::ASCENDING], ])
37
+ index([ [:version, Mongo::ASCENDING], ])
38
+ index([ [:_id, Mongo::ASCENDING], [:name, Mongo::ASCENDING], ])
39
+
40
+ validates(:name, :presence => true,
41
+ :uniqueness => {:scope => :version, :message => "is already taken in same version"},
42
+ :format => BASE_NAME.options
43
+ )
44
+ validates :version, :presence => true
45
+
46
+ embeds_many :handlers, :class_name => "Tengine::Core::Handler"
47
+
48
+ belongs_to :session, :index => true, :class_name => "Tengine::Core::Session"
49
+ has_many :handler_paths, :class_name => "Tengine::Core::HandlerPath"
50
+
51
+ after_create :update_handler_path
52
+ before_create :create_session # has_oneによって追加されるメソッドcreate_sessionのように振る舞うメソッドです
53
+
54
+ def update_handler_path
55
+ handlers.each(&:update_handler_path)
56
+ end
57
+
58
+ def create_session
59
+ self.session ||= Tengine::Core::Session.create
60
+ end
61
+
62
+ class << self
63
+ # Tengine::Core::FindByName で定義しているクラスメソッドfind_by_nameを上書きしています
64
+ def find_by_name(name, options = {})
65
+ version = options[:version] || Tengine::Core::Setting.dsl_version
66
+ first(:conditions => {:name => name, :version => version})
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/core/driver'
3
+
4
+ class Tengine::Core::Driver::Finder
5
+
6
+ ATTRIBUTE_NAMES = [
7
+ :name,
8
+ :version,
9
+ :enabled,
10
+ :enabled_on_activation
11
+ ].freeze
12
+
13
+ ATTRIBUTE_NAMES.each{|name| attr_accessor(name)}
14
+
15
+ def initialize(attrs = {})
16
+ attrs ||= {}
17
+ attrs.each do |attr, v|
18
+ send("#{attr}=", v) unless v.blank?
19
+ end
20
+ end
21
+
22
+ def attributes
23
+ ATTRIBUTE_NAMES.inject({}){|d, name| d[name] = send(name); d}
24
+ end
25
+
26
+ def paginate(page)
27
+ scope(Tengine::Core::Driver).page(page)
28
+ end
29
+
30
+ def scope(criteria)
31
+ result = criteria
32
+ result = result.where(name: name) if name
33
+ result = result.where(version: version) if version
34
+ result = result.where(enabled: enabled) if enabled
35
+ result = result.where(enabled_on_activation: enabled_on_activation) if enabled_on_activation
36
+ # ソート
37
+ result = result.asc(:_id, :name)
38
+ result
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,110 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'tengine/core'
3
+
4
+ require 'active_support/dependencies'
5
+
6
+ module Tengine::Core::DslEvaluator
7
+ attr_accessor :config
8
+
9
+ def __evaluate__
10
+ __setup_core_ext__
11
+ begin
12
+ Tengine.plugins.notify(self, :__evaluate__) do
13
+ ActiveSupport::Dependencies.mechanism = config.tengined.cache_drivers ? :require : :load
14
+ config.dsl_dir_path.tap do |dsl_dir_path|
15
+ $LOAD_PATH.unshift(dsl_dir_path) unless $LOAD_PATH.include?(dsl_dir_path)
16
+ ActiveSupport::Dependencies.autoload_paths = [dsl_dir_path]
17
+ end
18
+ config.dsl_file_paths.each do |f|
19
+ Tengine::Core.stdout_logger.debug("now loading #{f}")
20
+ # self.instance_eval(File.read(f), f)
21
+ # require(f)
22
+ if config.tengined.cache_drivers
23
+ load(f)
24
+ else
25
+ begin
26
+ require_dependency( config.relative_path_from_dsl_dir(f) )
27
+ rescue NameError => e
28
+ # ロードするパスのディレクトリ名をcamelizeした際に不正なモジュール名(例えば先頭が数字)
29
+ # だと失敗してしまうのでその場合はloadし直す
30
+ if e.message =~ /wrong constant name/
31
+ load(f)
32
+ else
33
+ raise
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ ensure
40
+ __teardown_core_ext__
41
+ end
42
+ end
43
+
44
+ def __safety_event__(event)
45
+ @__event__ = event
46
+ begin
47
+ yield if block_given?
48
+ ensure
49
+ @__event__ = nil
50
+ @__event_wrapper__ = nil
51
+ end
52
+ end
53
+
54
+ def __safety_driver__(driver)
55
+ @__driver__ = driver
56
+ @__session__ = driver.session
57
+ begin
58
+ yield if block_given?
59
+ ensure
60
+ @__driver__ = nil
61
+ @__session__ = nil
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def __setup_core_ext__
68
+ Symbol.class_eval do
69
+ def and(other)
70
+ Tengine::Core::DslFilterDef.new(
71
+ [self.to_s, other.to_s],
72
+ {
73
+ 'method' => :and,
74
+ 'children' => [
75
+ { 'pattern' => self, 'method' => :find_or_mark_in_session },
76
+ { 'pattern' => other, 'method' => :find_or_mark_in_session },
77
+ ]
78
+ })
79
+ end
80
+ alias_method :&, :and
81
+
82
+ def at(soruce_pattern)
83
+ Tengine::Core::DslFilterDef.new(
84
+ [self.to_s],
85
+ {
86
+ 'method' => :match_source_name?,
87
+ 'pattern' => soruce_pattern.to_s,
88
+ })
89
+ end
90
+ end
91
+ end
92
+
93
+ def __teardown_core_ext__
94
+ Symbol.class_eval do
95
+ remove_method(:&, :and)
96
+ end
97
+ end
98
+
99
+ # requireではなく、ファイルを文字列としてロードしてinstance_evalで評価される場合、
100
+ # Proc#source_locationが返す配列の一つ目の文字列がUTF-8ではなくASCII-8BITになってしまう。
101
+ # そのままこれを使って検索すると、ヒットするべき検索もヒットしない。
102
+ # これを回避するためにUTF-8として解釈するようにString#force_encodingを使用している。
103
+ # http://doc.ruby-lang.org/ja/1.9.2/method/String/i/force_encoding.html
104
+ def __source_location__(block)
105
+ filepath, lineno = *block.source_location
106
+ filepath = filepath.dup
107
+ filepath.force_encoding(Encoding::UTF_8)
108
+ return filepath, lineno
109
+ end
110
+ end