marty 2.5.2 → 2.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +4 -0
  3. data/.rubocop.yml +7 -0
  4. data/.rubocop_todo.yml +11 -589
  5. data/Gemfile +9 -9
  6. data/Gemfile.lock +1 -1
  7. data/Rakefile +1 -3
  8. data/app/components/marty/api_auth_view.rb +3 -3
  9. data/app/components/marty/api_config_view.rb +8 -8
  10. data/app/components/marty/api_log_view.rb +16 -20
  11. data/app/components/marty/auth_app.rb +6 -6
  12. data/app/components/marty/base_rule_view.rb +27 -19
  13. data/app/components/marty/config_view.rb +12 -9
  14. data/app/components/marty/data_grid_view.rb +26 -26
  15. data/app/components/marty/delorean_rule_view.rb +0 -1
  16. data/app/components/marty/event_view.rb +27 -27
  17. data/app/components/marty/extras/layout.rb +26 -26
  18. data/app/components/marty/extras/misc.rb +2 -2
  19. data/app/components/marty/grid.rb +13 -13
  20. data/app/components/marty/grid_append_only.rb +0 -1
  21. data/app/components/marty/import_type_view.rb +13 -13
  22. data/app/components/marty/import_view.rb +17 -16
  23. data/app/components/marty/log_view.rb +16 -14
  24. data/app/components/marty/main_auth_app.rb +59 -59
  25. data/app/components/marty/main_auth_app/client/main_auth_app.js +3 -3
  26. data/app/components/marty/mcfly_grid_panel.rb +10 -10
  27. data/app/components/marty/new_posting_form.rb +11 -11
  28. data/app/components/marty/new_posting_window.rb +0 -1
  29. data/app/components/marty/posting_grid.rb +12 -13
  30. data/app/components/marty/promise_view.rb +6 -6
  31. data/app/components/marty/report_form.rb +50 -53
  32. data/app/components/marty/report_select.rb +27 -27
  33. data/app/components/marty/reporting.rb +4 -4
  34. data/app/components/marty/script_form.rb +40 -42
  35. data/app/components/marty/script_grid.rb +24 -24
  36. data/app/components/marty/script_tester.rb +40 -42
  37. data/app/components/marty/scripting.rb +25 -27
  38. data/app/components/marty/simple_app.rb +24 -9
  39. data/app/components/marty/tag_grid.rb +12 -13
  40. data/app/components/marty/user_view.rb +35 -35
  41. data/app/controllers/marty/application_controller.rb +3 -4
  42. data/app/controllers/marty/components_controller.rb +1 -1
  43. data/app/controllers/marty/delayed_job_controller.rb +1 -0
  44. data/app/controllers/marty/diagnostic/controller.rb +4 -6
  45. data/app/controllers/marty/job_controller.rb +6 -6
  46. data/app/controllers/marty/report_controller.rb +11 -11
  47. data/app/controllers/marty/rpc_controller.rb +15 -16
  48. data/app/helpers/marty/script_set.rb +4 -4
  49. data/app/models/marty/api_auth.rb +4 -5
  50. data/app/models/marty/api_config.rb +1 -1
  51. data/app/models/marty/base.rb +9 -8
  52. data/app/models/marty/base_rule.rb +18 -13
  53. data/app/models/marty/config.rb +4 -5
  54. data/app/models/marty/data_grid.rb +157 -181
  55. data/app/models/marty/delorean_rule.rb +63 -62
  56. data/app/models/marty/enum.rb +1 -1
  57. data/app/models/marty/event.rb +56 -59
  58. data/app/models/marty/helper.rb +38 -6
  59. data/app/models/marty/import_type.rb +6 -6
  60. data/app/models/marty/log.rb +3 -2
  61. data/app/models/marty/name_validator.rb +3 -2
  62. data/app/models/marty/pg_enum.rb +3 -4
  63. data/app/models/marty/posting.rb +20 -24
  64. data/app/models/marty/promise.rb +28 -30
  65. data/app/models/marty/script.rb +30 -28
  66. data/app/models/marty/tag.rb +8 -8
  67. data/app/models/marty/token.rb +2 -2
  68. data/app/models/marty/user.rb +24 -23
  69. data/app/models/marty/vw_promise.rb +10 -11
  70. data/config/routes.rb +2 -2
  71. data/delorean/blame_report.dl +268 -0
  72. data/{spec/dummy/delorean/fields.dl → delorean/marty_fields.dl} +8 -0
  73. data/delorean/table_report.dl +34 -0
  74. data/docker-compose.dummy.yml +2 -3
  75. data/lib/marty/aws/base.rb +8 -8
  76. data/lib/marty/aws/request.rb +4 -4
  77. data/lib/marty/cache_adapters/mcfly_ruby_cache.rb +1 -0
  78. data/lib/marty/content_handler.rb +25 -25
  79. data/lib/marty/data_change.rb +49 -71
  80. data/lib/marty/data_conversion.rb +20 -28
  81. data/lib/marty/data_exporter.rb +25 -28
  82. data/lib/marty/data_importer.rb +25 -27
  83. data/lib/marty/engine.rb +1 -2
  84. data/lib/marty/json_schema.rb +22 -24
  85. data/lib/marty/logger.rb +6 -9
  86. data/lib/marty/mcfly_model.rb +20 -24
  87. data/lib/marty/migrations.rb +37 -35
  88. data/lib/marty/monkey.rb +33 -33
  89. data/lib/marty/permissions.rb +18 -18
  90. data/lib/marty/promise_job.rb +17 -17
  91. data/lib/marty/promise_proxy.rb +6 -6
  92. data/lib/marty/relation.rb +6 -7
  93. data/lib/marty/rpc_call.rb +13 -12
  94. data/lib/marty/rule_script_set.rb +32 -28
  95. data/lib/marty/schema_helper.rb +37 -51
  96. data/lib/marty/util.rb +25 -24
  97. data/lib/marty/version.rb +1 -1
  98. data/lib/marty/xl.rb +121 -115
  99. data/make-dummy.mk +3 -0
  100. data/marty.gemspec +21 -21
  101. data/other/marty/api/base.rb +34 -35
  102. data/other/marty/diagnostic/aws/ec2_instance.rb +8 -8
  103. data/other/marty/diagnostic/base.rb +13 -14
  104. data/other/marty/diagnostic/collection.rb +2 -1
  105. data/other/marty/diagnostic/connections.rb +8 -6
  106. data/other/marty/diagnostic/database.rb +1 -0
  107. data/other/marty/diagnostic/delayed_job_version.rb +7 -9
  108. data/other/marty/diagnostic/delayed_job_worker_total_count.rb +1 -1
  109. data/other/marty/diagnostic/delayed_job_workers.rb +1 -1
  110. data/other/marty/diagnostic/environment_variables.rb +17 -15
  111. data/other/marty/diagnostic/fatal.rb +1 -1
  112. data/other/marty/diagnostic/node.rb +5 -9
  113. data/other/marty/diagnostic/nodes.rb +7 -5
  114. data/other/marty/diagnostic/packer.rb +7 -7
  115. data/other/marty/diagnostic/reporter.rb +24 -27
  116. data/other/marty/diagnostic/version.rb +3 -5
  117. data/script/rails +2 -1
  118. data/spec/controllers/application_controller_spec.rb +6 -6
  119. data/spec/controllers/delayed_job_controller_spec.rb +4 -4
  120. data/spec/controllers/diagnostic/controller_spec.rb +59 -60
  121. data/spec/controllers/job_controller_spec.rb +68 -69
  122. data/spec/controllers/rpc_controller_spec.rb +353 -359
  123. data/spec/controllers/rpc_import_spec.rb +15 -16
  124. data/spec/dummy/delorean/blame_report.dl +110 -15
  125. data/spec/dummy/delorean/data_report.dl +4 -4
  126. data/spec/dummy/delorean/marty_fields.dl +63 -0
  127. data/spec/dummy/delorean/table_report.dl +34 -0
  128. data/spec/features/auth_app_spec.rb +1 -2
  129. data/spec/features/data_import_spec.rb +2 -3
  130. data/spec/features/enum_spec.rb +42 -46
  131. data/spec/features/jobs_dashboard_spec.rb +14 -8
  132. data/spec/features/log_view_spec.rb +40 -43
  133. data/spec/features/reporting_spec.rb +15 -15
  134. data/spec/features/rule_spec.rb +195 -190
  135. data/spec/features/scripting_spec.rb +17 -20
  136. data/spec/features/scripting_test_spec.rb +32 -33
  137. data/spec/features/user_view_spec.rb +15 -17
  138. data/spec/job_helper.rb +11 -11
  139. data/spec/lib/data_blame_spec.rb +82 -0
  140. data/spec/lib/data_exporter_spec.rb +31 -32
  141. data/spec/lib/data_importer_spec.rb +382 -395
  142. data/spec/lib/delorean_query_spec.rb +117 -119
  143. data/spec/lib/json_schema_spec.rb +382 -392
  144. data/spec/lib/logger_spec.rb +23 -24
  145. data/spec/lib/mcfly_model_spec.rb +112 -109
  146. data/spec/lib/migrations_spec.rb +10 -10
  147. data/spec/lib/struct_compare_spec.rb +6 -6
  148. data/spec/lib/table_report_spec.rb +90 -0
  149. data/spec/lib/xl_spec.rb +63 -65
  150. data/spec/lib/xl_styles_spec.rb +16 -19
  151. data/spec/models/api_auth_spec.rb +30 -30
  152. data/spec/models/config_spec.rb +32 -32
  153. data/spec/models/data_grid_spec.rb +642 -655
  154. data/spec/models/event_spec.rb +96 -88
  155. data/spec/models/import_type_spec.rb +20 -20
  156. data/spec/models/posting_spec.rb +35 -35
  157. data/spec/models/promise_spec.rb +5 -5
  158. data/spec/models/rule_spec.rb +280 -269
  159. data/spec/models/script_spec.rb +27 -18
  160. data/spec/models/user_spec.rb +9 -9
  161. data/spec/other/diagnostic/base_spec.rb +20 -19
  162. data/spec/other/diagnostic/collection_spec.rb +6 -5
  163. data/spec/other/diagnostic/delayed_job_version_spec.rb +1 -1
  164. data/spec/other/diagnostic/delayed_job_workers_spec.rb +8 -8
  165. data/spec/other/diagnostic/reporter_spec.rb +31 -33
  166. data/spec/spec_helper.rb +5 -5
  167. data/spec/support/chromedriver.rb +3 -5
  168. data/spec/support/components/netzke_combobox.rb +1 -1
  169. data/spec/support/components/netzke_grid.rb +17 -17
  170. data/spec/support/custom_matchers.rb +2 -2
  171. data/spec/support/download_helper.rb +1 -1
  172. data/spec/support/helper.rb +1 -2
  173. data/spec/support/netzke.rb +31 -31
  174. data/spec/support/performance_helper.rb +8 -8
  175. data/spec/support/post_run_logger.rb +1 -2
  176. data/spec/support/setup.rb +1 -4
  177. data/spec/support/shared_connection.rb +2 -2
  178. data/spec/support/structure_compare.rb +21 -22
  179. data/spec/support/suite.rb +1 -2
  180. data/spec/support/users.rb +5 -6
  181. metadata +32 -26
@@ -1,21 +1,53 @@
1
1
  class Marty::Helper
2
2
  include Delorean::Model
3
3
 
4
- delorean_fn :sleep, sig: 1 do
5
- |seconds|
4
+ delorean_fn :sleep, sig: 1 do |seconds|
6
5
  Kernel.sleep seconds
7
6
  end
8
7
 
9
- delorean_fn :range_step, sig: 3 do
10
- |rstart, rend, step|
8
+ delorean_fn :range_step, sig: 3 do |rstart, rend, step|
11
9
  (rstart..rend).step(step).to_a
12
10
  end
13
11
 
14
- delorean_fn :my_ip, sig:0 do
12
+ delorean_fn :my_ip, sig: 0 do
15
13
  Marty::Diagnostic::Node.my_ip
16
14
  end
17
15
 
18
- delorean_fn :git, sig:0 do
16
+ delorean_fn :git, sig: 0 do
19
17
  [my_ip, ENV['DELAYED_VER']]
20
18
  end
19
+
20
+ delorean_fn :infinity_dt, sig: 1 do |pt|
21
+ Mcfly.is_infinity pt
22
+ end
23
+
24
+ delorean_fn :constantize, sig: 1 do |class_name|
25
+ raise 'bad class_name' unless class_name.is_a?(String)
26
+
27
+ class_name.constantize
28
+ end
29
+
30
+ delorean_fn :get_column_types, sig: 1 do |klass|
31
+ Marty::DataConversion.col_types(klass)
32
+ end
33
+
34
+ delorean_fn :parse_csv_to_hash, sig: 3 do |txt, comma_sep, types|
35
+ txt ||= ''
36
+ headers, *rows = CSV.parse(txt.strip,
37
+ headers: true,
38
+ col_sep: (comma_sep ? ',' : "\t")).to_a
39
+ rows.map do |row|
40
+ headers.zip(row).each_with_object({}) do |(h, v), res|
41
+ res[h] = v.blank? ? nil :
42
+ Marty::DataConversion.convert(v, (types[h] || 'text').to_sym)
43
+ end
44
+ end
45
+ end
46
+
47
+ delorean_fn :to_csv, sig: [1, 2] do |*args|
48
+ # NOTE: can't use |data, config| due to delorean_fn weirdness.
49
+ data, config = args
50
+
51
+ Marty::DataExporter.to_csv(data, config)
52
+ end
21
53
  end
@@ -4,7 +4,7 @@ class Marty::ImportType < Marty::Base
4
4
  klass = entry.get_model_class
5
5
 
6
6
  unless klass.is_a?(Class) && klass < ActiveRecord::Base
7
- entry.errors.add :base, "bad model name"
7
+ entry.errors.add :base, 'bad model name'
8
8
  return
9
9
  end
10
10
 
@@ -12,19 +12,19 @@ class Marty::ImportType < Marty::Base
12
12
  entry.cleaner_function,
13
13
  entry.validation_function,
14
14
  entry.preprocess_function,
15
- ].each { |func|
15
+ ].each do |func|
16
16
  entry.errors.add(:base, "unknown class method #{func}") if
17
17
  func && !klass.respond_to?(func.to_sym)
18
- }
18
+ end
19
19
  end
20
20
  end
21
21
 
22
22
  before_validation do
23
23
  # Fix issue with blank strings in popup edit form or grid
24
24
  # being interpreted as a function
25
- self.cleaner_function = nil if self.cleaner_function.blank?
26
- self.validation_function = nil if self.validation_function.blank?
27
- self.preprocess_function = nil if self.preprocess_function.blank?
25
+ self.cleaner_function = nil if cleaner_function.blank?
26
+ self.validation_function = nil if validation_function.blank?
27
+ self.preprocess_function = nil if preprocess_function.blank?
28
28
  end
29
29
 
30
30
  belongs_to :role
@@ -9,7 +9,7 @@ class Marty::Log < Marty::Base
9
9
  message: message,
10
10
  details: details,
11
11
  timestamp: Time.zone.now)
12
- rescue => e
12
+ rescue StandardError => e
13
13
  Marty::Util.logger.error("Marty::Logger failure: #{e.message}")
14
14
  end
15
15
  true
@@ -18,6 +18,7 @@ class Marty::Log < Marty::Base
18
18
  def self.cleanup(days_to_keep)
19
19
  raise "Must give numeric value. (Got '#{days_to_keep}')" unless
20
20
  (Float(days_to_keep) rescue false)
21
- where("timestamp <= ?", Time.zone.now - days_to_keep.to_i.days).delete_all
21
+
22
+ where('timestamp <= ?', Time.zone.now - days_to_keep.to_i.days).delete_all
22
23
  end
23
24
  end
@@ -1,6 +1,7 @@
1
1
  class Marty::NameValidator < ActiveModel::Validator
2
2
  def validate(entry)
3
- raise "need field option" unless options[:field]
3
+ raise 'need field option' unless options[:field]
4
+
4
5
  field = options[:field].to_sym
5
6
  value = entry.send(field)
6
7
 
@@ -9,7 +10,7 @@ class Marty::NameValidator < ActiveModel::Validator
9
10
  # disallow leading, trailing, >1 internal spaces, special chars (|)
10
11
  if value =~ /\A\s|\s\z|\A.*\s\s.*\z|.*\|.*/
11
12
  entry.errors[field] <<
12
- I18n.t("activerecord.errors.messages.extraneous_spaces")
13
+ I18n.t('activerecord.errors.messages.extraneous_spaces')
13
14
  end
14
15
  end
15
16
  end
@@ -1,16 +1,15 @@
1
1
  module Marty::PgEnum
2
-
3
- def [](i0, i1=nil)
2
+ def [](i0, i1 = nil)
4
3
  # if i1 is provided, then i0 is a pt and we ignore it.
5
4
  index = (i1 || i0).to_s
6
5
 
7
- raise "no such #{self.name}: '#{index}'" unless
6
+ raise "no such #{name}: '#{index}'" unless
8
7
  self::VALUES.include?(index)
9
8
 
10
9
  index
11
10
  end
12
11
 
13
- def get_all(pt=nil)
12
+ def get_all(pt = nil)
14
13
  self::VALUES.map(&:to_s)
15
14
  end
16
15
 
@@ -4,7 +4,7 @@ class Marty::Posting < Marty::Base
4
4
  mcfly_validates_uniqueness_of :name
5
5
  validates_presence_of :name, :posting_type_id, :comment
6
6
 
7
- belongs_to :user, class_name: "Marty::User"
7
+ belongs_to :user, class_name: 'Marty::User'
8
8
  belongs_to :posting_type
9
9
 
10
10
  def self.make_name(posting_type, dt)
@@ -22,8 +22,8 @@ class Marty::Posting < Marty::Base
22
22
 
23
23
  before_validation :set_posting_name
24
24
  def set_posting_name
25
- posting_type = Marty::PostingType.find_by_id(self.posting_type_id)
26
- self.name = self.class.make_name(posting_type, self.created_dt)
25
+ posting_type = Marty::PostingType.find_by_id(posting_type_id)
26
+ self.name = self.class.make_name(posting_type, created_dt)
27
27
  true
28
28
  end
29
29
 
@@ -41,7 +41,7 @@ class Marty::Posting < Marty::Base
41
41
  end
42
42
 
43
43
  def self.get_struct_attrs
44
- self.struct_attrs ||= super + ["created_dt", "name"]
44
+ self.struct_attrs ||= super + ['created_dt', 'name']
45
45
  end
46
46
 
47
47
  # Not using mcfly_lookup since we don't want these time-warp markers
@@ -49,43 +49,39 @@ class Marty::Posting < Marty::Base
49
49
  # may allow deletion of postings. i.e. a new one with same name
50
50
  # might be created. Or, use regular validates_uniqueness_of instead
51
51
  # of mcfly_validates_uniqueness_of.
52
- delorean_fn :lookup, sig: 1 do
53
- |name|
52
+ delorean_fn :lookup, sig: 1 do |name|
54
53
  p = select(get_struct_attrs).find_by_name(name)
55
54
  make_openstruct(p)
56
55
  end
57
56
 
58
- delorean_fn :lookup_dt, sig: 1 do
59
- |name|
57
+ delorean_fn :lookup_dt, sig: 1 do |name|
60
58
  find_by_name(name).try(:created_dt)
61
59
  end
62
60
 
63
- delorean_fn :first_match, sig: [1, 2] do
64
- |dt, posting_type=nil|
65
- raise "bad posting type" if
61
+ delorean_fn :first_match, sig: [1, 2] do |dt, posting_type = nil|
62
+ raise 'bad posting type' if
66
63
  posting_type && !posting_type.is_a?(Marty::PostingType)
67
64
 
68
- q = where("created_dt <= ?", dt)
65
+ q = where('created_dt <= ?', dt)
69
66
  q = q.where(posting_type_id: posting_type.id) if posting_type
70
- q.order("created_dt DESC").first.attributes
67
+ q.order('created_dt DESC').first.attributes
71
68
  end
72
69
 
73
- def self.get_latest(limit, is_test=nil)
70
+ def self.get_latest(limit, is_test = nil)
74
71
  # IMPORTANT: is_test arg is ignored (KEEP for backward compat.)
75
72
 
76
- q=where("created_dt <> 'infinity'").
77
- order("created_dt DESC").limit(limit)
73
+ q = where("created_dt <> 'infinity'").
74
+ order('created_dt DESC').limit(limit)
78
75
  end
79
76
 
80
- delorean_fn :get_latest_by_type, sig: [1, 2] do
81
- |limit, posting_types=[]|
82
- raise "missing posting types list" unless posting_types
83
- raise "bad posting types list" unless posting_types.is_a?(Array)
77
+ delorean_fn :get_latest_by_type, sig: [1, 2] do |limit, posting_types = []|
78
+ raise 'missing posting types list' unless posting_types
79
+ raise 'bad posting types list' unless posting_types.is_a?(Array)
84
80
 
85
- q=joins(:posting_type).where("created_dt <> 'infinity'").
86
- where(marty_posting_types: { name: posting_types } ).
81
+ q = joins(:posting_type).where("created_dt <> 'infinity'").
82
+ where(marty_posting_types: { name: posting_types }).
87
83
  select(get_struct_attrs).
88
- order("created_dt DESC").limit(limit || 1)
89
- q.map{|ar| ar.attributes}
84
+ order('created_dt DESC').limit(limit || 1)
85
+ q.map(&:attributes)
90
86
  end
91
87
  end
@@ -1,28 +1,27 @@
1
1
  class Marty::Promise < Marty::Base
2
-
3
2
  # default timeout (seconds) to wait for promise values
4
3
  DEFAULT_PROMISE_TIMEOUT = Rails.configuration.marty.promise_timeout || 30
5
4
 
6
5
  # default timeout (seconds) to wait for jobs to start
7
6
  DEFAULT_JOB_TIMEOUT = Rails.configuration.marty.job_timeout || 10
8
7
 
9
- def result(force=false)
8
+ def result(force = false)
10
9
  res = super()
11
10
  Marty::Promise.load_result(res, force)
12
11
  end
13
12
 
14
- def self.load_result(obj, force=false)
13
+ def self.load_result(obj, force = false)
15
14
  if force && obj.respond_to?(:__force__)
16
15
  obj = obj.__force__
17
16
  end
18
17
 
19
18
  case obj
20
19
  when Array
21
- obj.map {|x| load_result(x, force)}
20
+ obj.map { |x| load_result(x, force) }
22
21
  when Hash
23
22
  p = obj['__promise__']
24
23
 
25
- if p && obj.length==1
24
+ if p && obj.length == 1
26
25
  load_result(Marty::PromiseProxy.new(*p), force)
27
26
  else
28
27
  obj.each_with_object({}) { |(k, v), h| h[k] = load_result(v, force) }
@@ -34,21 +33,19 @@ class Marty::Promise < Marty::Base
34
33
 
35
34
  has_many :children,
36
35
  foreign_key: 'parent_id',
37
- class_name: "Marty::Promise",
36
+ class_name: 'Marty::Promise',
38
37
  dependent: :destroy
39
38
 
40
39
  validates_presence_of :title
41
40
 
42
- belongs_to :parent, class_name: "Marty::Promise"
43
- belongs_to :user, class_name: "Marty::User"
41
+ belongs_to :parent, class_name: 'Marty::Promise'
42
+ belongs_to :user, class_name: 'Marty::User'
44
43
 
45
- def self.cleanup(all=false)
46
- begin
44
+ def self.cleanup(all = false)
47
45
  where('start_dt < ? AND parent_id IS NULL',
48
46
  DateTime.now - (all ? 0.hours : 4.hours)).destroy_all
49
- rescue => exc
47
+ rescue StandardError => exc
50
48
  Marty::Util.logger.error("promise GC error: #{exc}")
51
- end
52
49
  end
53
50
 
54
51
  def raw_conn
@@ -60,38 +57,38 @@ class Marty::Promise < Marty::Base
60
57
  end
61
58
 
62
59
  def set_start
63
- if self.start_dt || self.result != {}
60
+ if start_dt || result != {}
64
61
  Marty::Util.logger.error("promise already started: #{self}")
65
62
  return
66
63
  end
67
64
 
68
65
  # mark promise as started
69
66
  self.start_dt = DateTime.now
70
- self.save!
67
+ save!
71
68
  end
72
69
 
73
70
  def set_result(res)
74
71
  # log "SETRES #{Process.pid} #{self}"
75
72
 
76
73
  # promise must have been started and not yet ended
77
- if !self.start_dt || self.end_dt || self.result != {}
74
+ if !start_dt || end_dt || result != {}
78
75
  # log "SETERR #{Process.pid} #{self}"
79
76
  Marty::Util.logger.error("unexpected promise state: #{self}")
80
77
  return
81
78
  end
82
79
 
83
- raise "bad result" unless res.is_a?(Hash)
80
+ raise 'bad result' unless res.is_a?(Hash)
84
81
 
85
- self.status = res["error"].nil?
82
+ self.status = res['error'].nil?
86
83
  self.result = res
87
84
 
88
85
  # update title/format from result hash (somewhat hacky)
89
- self.title = res["title"].to_s if res["title"]
90
- self.cformat = res["format"].to_s if res["format"]
86
+ self.title = res['title'].to_s if res['title']
87
+ self.cformat = res['format'].to_s if res['format']
91
88
 
92
89
  # mark promise as ended
93
90
  self.end_dt = DateTime.now
94
- self.save!
91
+ save!
95
92
 
96
93
  # log "NOTIFY #{Process.pid}"
97
94
  pg_notify
@@ -106,11 +103,11 @@ class Marty::Promise < Marty::Base
106
103
  # end
107
104
 
108
105
  def wait_for_my_notify(timeout)
109
- while true do
106
+ while true
110
107
  # FIXME: we keep using the same timeout. The timeout should be
111
108
  # reduced by total time spent here.
112
109
  n = raw_conn.wait_for_notify(timeout)
113
- return n if !n || n=="promise_#{id}"
110
+ return n if !n || n == "promise_#{id}"
114
111
  end
115
112
  end
116
113
 
@@ -120,17 +117,17 @@ class Marty::Promise < Marty::Base
120
117
  # seems to work.
121
118
 
122
119
  # get latest uncached version
123
- Marty::Promise.uncached {Marty::Promise.find(id)}
120
+ Marty::Promise.uncached { Marty::Promise.find(id) }
124
121
  end
125
122
 
126
123
  def self.job_by_id(job_id)
127
- Delayed::Job.uncached {Delayed::Job.find_by_id(job_id)}
124
+ Delayed::Job.uncached { Delayed::Job.find_by_id(job_id) }
128
125
  end
129
126
 
130
127
  def work_off_job(job)
131
128
  # Create a temporary worker to work off the job
132
129
  Delayed::Job.where(id: job.id).
133
- update_all(locked_at: Delayed::Job.db_time_now, locked_by: "Temp")
130
+ update_all(locked_at: Delayed::Job.db_time_now, locked_by: 'Temp')
134
131
  w = Delayed::Worker.new
135
132
  w.run(job)
136
133
  end
@@ -138,7 +135,7 @@ class Marty::Promise < Marty::Base
138
135
  def wait_for_result(timeout)
139
136
  # FIXME: Not sure that comparing result with empty hash if a good idea
140
137
  # perhaps it's better to use .present? or .blank?
141
- return self.result if self.result != {}
138
+ return result if result != {}
142
139
 
143
140
  begin
144
141
  # start listening on promise's notification
@@ -150,7 +147,8 @@ class Marty::Promise < Marty::Base
150
147
  if !last.start_dt
151
148
  job = Marty::Promise.job_by_id(last.job_id)
152
149
 
153
- # FIXME: this block is needed since a lot of specs rely on delayed job being runned in the same thread as promise
150
+ # FIXME: this block is needed since a lot of specs rely on
151
+ # delayed job being runned in the same thread as promise
154
152
  # Can be deleted later and replaces with simple timeout below
155
153
  if !job || job.locked_at
156
154
  # job has been locked, so it looks like it started already
@@ -162,7 +160,7 @@ class Marty::Promise < Marty::Base
162
160
  # log "OFF0 #{Process.pid} #{last}"
163
161
  begin
164
162
  work_off_job(job)
165
- rescue => exc
163
+ rescue StandardError => exc
166
164
  # log "OFFERR #{exc}"
167
165
  res = Delorean::Engine.grok_runtime_exception(exc)
168
166
  last.set_result(res)
@@ -179,7 +177,7 @@ class Marty::Promise < Marty::Base
179
177
  # timeout error.
180
178
  if !last.start_dt
181
179
  # log "TO11 #{Process.pid} #{last}"
182
- return {"error" => "promise #{last.id} timed out (never started)"}
180
+ return { 'error' => "promise #{last.id} timed out (never started)" }
183
181
  end
184
182
  end
185
183
 
@@ -192,7 +190,7 @@ class Marty::Promise < Marty::Base
192
190
  last = latest
193
191
 
194
192
  if !last.end_dt
195
- return {"error" => "promise #{last.id} timed out (didn't end)"}
193
+ return { 'error' => "promise #{last.id} timed out (didn't end)" }
196
194
  end
197
195
  end
198
196
 
@@ -3,24 +3,23 @@ class Marty::Script < Marty::Base
3
3
 
4
4
  validates_presence_of :name, :body
5
5
  mcfly_validates_uniqueness_of :name
6
- validates_format_of :name, {
7
- with: /\A[A-Z][a-zA-Z0-9]*\z/,
8
- message: I18n.t('script.save_error'),
9
- }
6
+ validates_format_of :name,
7
+ with: /\A[A-Z][a-zA-Z0-9]*\z/,
8
+ message: I18n.t('script.save_error')
10
9
 
11
- belongs_to :user, class_name: "Marty::User"
10
+ belongs_to :user, class_name: 'Marty::User'
12
11
 
13
12
  gen_mcfly_lookup :lookup, [:name], cache: true
14
13
 
15
14
  # find script by name/tag (not cached)
16
- def self.find_script(sname, tag=nil)
15
+ def self.find_script(sname, tag = nil)
17
16
  tag = Marty::Tag.map_to_tag(tag)
18
17
  Marty::Script.mcfly_pt(tag.created_dt).find_by(name: sname)
19
18
  end
20
19
 
21
20
  def find_tag
22
21
  # find the first tag created after this script.
23
- Marty::Tag.where("created_dt >= ?", created_dt).order(:created_dt).first
22
+ Marty::Tag.where('created_dt >= ?', created_dt).order(:created_dt).first
24
23
  end
25
24
 
26
25
  def self.create_script(name, body)
@@ -31,7 +30,7 @@ class Marty::Script < Marty::Base
31
30
  script
32
31
  end
33
32
 
34
- def self.load_a_script(sname, body, dt=nil)
33
+ def self.load_a_script(sname, body, dt = nil)
35
34
  s = Marty::Script.find_by(obsoleted_dt: 'infinity', name: sname)
36
35
 
37
36
  if !s
@@ -47,28 +46,27 @@ class Marty::Script < Marty::Base
47
46
  end
48
47
  end
49
48
 
50
- def self.load_script_bodies(bodies, dt=nil)
51
- bodies.each {
52
- |sname, body|
49
+ def self.load_script_bodies(bodies, dt = nil)
50
+ bodies.each do |sname, body|
53
51
  load_a_script(sname, body, dt)
54
- }
52
+ end
55
53
 
56
54
  # Create a new tag if scripts were modified after the last tag
57
55
  tag = Marty::Tag.get_latest1
58
- latest = Marty::Script.order("created_dt DESC").first
56
+ latest = Marty::Script.order('created_dt DESC').first
59
57
 
60
58
  tag_time = (dt || [latest.try(:created_dt), Time.now].compact.max) +
61
59
  1.second
62
60
 
63
61
  # If no tag_time is provided, the tag created_dt will be the same
64
62
  # as the scripts.
65
- tag = Marty::Tag.do_create(tag_time, "tagged from load scripts") if
63
+ tag = Marty::Tag.do_create(tag_time, 'tagged from load scripts') if
66
64
  !(tag && latest) || tag.created_dt <= latest.created_dt
67
65
 
68
66
  tag
69
67
  end
70
68
 
71
- def self.load_scripts(path=nil, dt=nil)
69
+ def self.load_scripts(path = nil, dt = nil)
72
70
  files = get_script_filenames(path)
73
71
 
74
72
  bodies = read_script_files(files)
@@ -77,10 +75,10 @@ class Marty::Script < Marty::Base
77
75
  end
78
76
 
79
77
  def self.read_script_files(files)
80
- files.collect { |fpath|
78
+ files.collect do |fpath|
81
79
  fname = File.basename(fpath)[0..-4].camelize
82
80
  [fname, File.read(fpath)]
83
- }
81
+ end
84
82
  end
85
83
 
86
84
  def self.get_script_filenames(paths = nil)
@@ -90,7 +88,7 @@ class Marty::Script < Marty::Base
90
88
  paths.each do |path|
91
89
  Dir.glob("#{path}/*.dl").each do |filename|
92
90
  basename = File.basename(filename)
93
- filenames[basename] = filename unless filenames.has_key?(basename)
91
+ filenames[basename] = filename unless filenames.key?(basename)
94
92
  end
95
93
  end
96
94
 
@@ -114,15 +112,15 @@ class Marty::Script < Marty::Base
114
112
 
115
113
  def self.delete_scripts
116
114
  ActiveRecord::Base.connection.
117
- execute("ALTER TABLE marty_scripts DISABLE TRIGGER USER;")
115
+ execute('ALTER TABLE marty_scripts DISABLE TRIGGER USER;')
118
116
  Marty::Script.delete_all
119
117
  ActiveRecord::Base.connection.
120
- execute("ALTER TABLE marty_scripts ENABLE TRIGGER USER;")
118
+ execute('ALTER TABLE marty_scripts ENABLE TRIGGER USER;')
121
119
  end
122
120
 
123
- delorean_fn :eval_to_hash, sig: 5 do
124
- |dt, script, node, attrs, params|
125
- tag = Marty::Tag.find_match(dt) || raise("no tag found for #{dt}")
121
+ delorean_fn :eval_to_hash, sig: 5 do |dt, script, node, attrs, params|
122
+ tag = Marty::Tag.find_match(dt) if dt.present?
123
+ raise("no tag for #{dt}") if tag.nil? && dt.present?
126
124
 
127
125
  engine = Marty::ScriptSet.new(tag).get_engine(script)
128
126
  # IMPORTANT: engine evals (e.g. eval_to_hash) modify the
@@ -134,11 +132,16 @@ class Marty::Script < Marty::Base
134
132
  # current tag can caused problems.
135
133
  end
136
134
 
137
- delorean_fn :evaluate, sig: 5 do
138
- |dt, script, node, attr, params|
139
- tag = Marty::Tag.find_match(dt) || raise("no tag found for #{dt}")
135
+ # evaluate script's node attribute (attr) with the given params. dt
136
+ # is used to determine which script tag to use. The latest tag is
137
+ # used if dt is nil.
138
+ delorean_fn :evaluate, sig: 5 do |dt, script, node, attr, params|
139
+ tag = Marty::Tag.find_match(dt) if dt.present?
140
+ raise("no tag for #{dt}") if tag.nil? && dt.present?
140
141
 
142
+ # nil tag, uses the latest one
141
143
  engine = Marty::ScriptSet.new(tag).get_engine(script)
144
+
142
145
  # IMPORTANT: engine evals (e.g. eval_to_hash) modify the
143
146
  # params, but it is possible that we may be passing in
144
147
  # a frozen hash. To avoid performance impacts, we should first check if
@@ -146,8 +149,7 @@ class Marty::Script < Marty::Base
146
149
  engine.evaluate(node, attr, params.frozen? ? params.dup : params.clone)
147
150
  end
148
151
 
149
- delorean_fn :pretty_print, sig: 1 do
150
- |id|
152
+ delorean_fn :pretty_print, sig: 1 do |id|
151
153
  script = find_by_id id
152
154
 
153
155
  next "unknown script #{id}" unless script