chillout 0.8.7 → 0.8.8

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +8 -0
  3. data/CHANGELOG.md +5 -0
  4. data/lib/chillout.rb +1 -0
  5. data/lib/chillout/integrations/state_machine.rb +90 -0
  6. data/lib/chillout/railtie.rb +15 -1
  7. data/lib/chillout/version.rb +1 -1
  8. data/test/acceptance/client_sends_state_machine_metrics_test.rb +45 -0
  9. data/test/support/rails_4_0_0/Gemfile +1 -0
  10. data/test/support/rails_4_0_0/app/controllers/entities_controller.rb +1 -1
  11. data/test/support/rails_4_0_0/app/controllers/transitions_controller.rb +8 -0
  12. data/test/support/rails_4_0_0/app/models/entity.rb +35 -1
  13. data/test/support/rails_4_0_0/config/routes.rb +1 -0
  14. data/test/support/rails_4_0_0/db/schema.rb +2 -0
  15. data/test/support/rails_4_0_13/Gemfile +1 -0
  16. data/test/support/rails_4_0_13/app/controllers/entities_controller.rb +1 -1
  17. data/test/support/rails_4_0_13/app/controllers/transitions_controller.rb +8 -0
  18. data/test/support/rails_4_0_13/app/models/entity.rb +35 -1
  19. data/test/support/rails_4_0_13/config/routes.rb +1 -0
  20. data/test/support/rails_4_0_13/db/schema.rb +2 -0
  21. data/test/support/rails_4_1_0/Gemfile +1 -0
  22. data/test/support/rails_4_1_0/app/controllers/entities_controller.rb +1 -1
  23. data/test/support/rails_4_1_0/app/controllers/transitions_controller.rb +8 -0
  24. data/test/support/rails_4_1_0/app/models/entity.rb +35 -1
  25. data/test/support/rails_4_1_0/config/initializers/state_machine_integration_hack.rb +3 -0
  26. data/test/support/rails_4_1_0/config/routes.rb +1 -0
  27. data/test/support/rails_4_1_0/db/schema.rb +2 -0
  28. data/test/support/rails_4_1_16/Gemfile +2 -1
  29. data/test/support/rails_4_1_16/app/controllers/entities_controller.rb +1 -1
  30. data/test/support/rails_4_1_16/app/controllers/transitions_controller.rb +8 -0
  31. data/test/support/rails_4_1_16/app/jobs/create_entity_job.rb +1 -1
  32. data/test/support/rails_4_1_16/app/models/entity.rb +35 -1
  33. data/test/support/rails_4_1_16/config/initializers/state_machine_integration_hack.rb +3 -0
  34. data/test/support/rails_4_1_16/config/routes.rb +1 -0
  35. data/test/support/rails_4_1_16/db/schema.rb +2 -0
  36. data/test/support/rails_4_2_0/Gemfile +2 -1
  37. data/test/support/rails_4_2_0/app/controllers/entities_controller.rb +1 -1
  38. data/test/support/rails_4_2_0/app/controllers/transitions_controller.rb +8 -0
  39. data/test/support/rails_4_2_0/app/jobs/create_entity_job.rb +1 -1
  40. data/test/support/rails_4_2_0/app/models/entity.rb +35 -1
  41. data/test/support/rails_4_2_0/config/initializers/state_machine_integration_hack.rb +3 -0
  42. data/test/support/rails_4_2_0/config/routes.rb +1 -0
  43. data/test/support/rails_4_2_0/db/schema.rb +2 -0
  44. data/test/support/rails_4_2_8/Gemfile +7 -1
  45. data/test/support/rails_4_2_8/app/controllers/entities_controller.rb +1 -1
  46. data/test/support/rails_4_2_8/app/controllers/transitions_controller.rb +8 -0
  47. data/test/support/rails_4_2_8/app/jobs/create_entity_job.rb +1 -1
  48. data/test/support/rails_4_2_8/app/models/entity.rb +35 -1
  49. data/test/support/rails_4_2_8/config/initializers/state_machine_integration_hack.rb +3 -0
  50. data/test/support/rails_4_2_8/config/routes.rb +1 -0
  51. data/test/support/rails_4_2_8/db/schema.rb +2 -0
  52. data/test/support/rails_5_0_3/Gemfile +7 -1
  53. data/test/support/rails_5_0_3/app/controllers/entities_controller.rb +1 -1
  54. data/test/support/rails_5_0_3/app/controllers/transitions_controller.rb +8 -0
  55. data/test/support/rails_5_0_3/app/jobs/create_entity_job.rb +1 -1
  56. data/test/support/rails_5_0_3/app/models/entity.rb +35 -1
  57. data/test/support/rails_5_0_3/config/initializers/state_machine_integration_hack.rb +3 -0
  58. data/test/support/rails_5_0_3/config/routes.rb +1 -0
  59. data/test/support/rails_5_0_3/db/schema.rb +2 -0
  60. data/test/support/rails_5_1_1/Gemfile +6 -0
  61. data/test/support/rails_5_1_1/app/controllers/entities_controller.rb +1 -1
  62. data/test/support/rails_5_1_1/app/controllers/transitions_controller.rb +8 -0
  63. data/test/support/rails_5_1_1/app/jobs/create_entity_job.rb +1 -1
  64. data/test/support/rails_5_1_1/app/models/application_record.rb +3 -0
  65. data/test/support/rails_5_1_1/app/models/entity.rb +35 -1
  66. data/test/support/rails_5_1_1/app/models/user.rb +2 -0
  67. data/test/support/rails_5_1_1/config/routes.rb +2 -1
  68. data/test/support/rails_5_1_1/db/schema.rb +2 -0
  69. data/test/test_helper.rb +19 -3
  70. metadata +36 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6631dcadcf73b03ed3a10a4ef2e7d79ac081c3cf
4
- data.tar.gz: e2097e2a4d295b7fd0f6c36f6eac008aad94523c
3
+ metadata.gz: 146543514bd9a57101ff6edfa2e7f4b9230c6b32
4
+ data.tar.gz: 8d99f8a62af72773cbe7344ccef119a435b066a1
5
5
  SHA512:
6
- metadata.gz: d10872b0af3d30b51ef10dfaa6530e177cc1d3f329ea39a621127d691dc10d9befc1a73e4fc2e3029fa06c0605df6fc51369bf0d662f0f3babd603a8ec6fe61b
7
- data.tar.gz: b1a7b075053a58cb0e06e7f75cac2f6c6c4ca255c7a8abe9056eae3c05ea9549ece21bc5341ff6ac263631f479466d4474f8c1571ec77f5b0e2024a2079639b7
6
+ metadata.gz: 61bc007ffd4972c0a1d6bbd38288e326e40f4a11609be28e9454438a4cae84e51d9c3a52245f8a8f703e8fca510033fefb62226d63432fc6967c70c43c256f32
7
+ data.tar.gz: d7d9a20333b07c7a11139609060ef23669602615859a94e6c452d74e3ab14d978122dd7c878dc9103cbdfbe265e2ef12d3a174c25d7a222622d67d005e38c245
@@ -44,6 +44,14 @@ matrix:
44
44
  env: SAMPLE_APP=rails_5_0_3 STRATEGY=active_job SIDEKIQ_SUPPORTED=true
45
45
  - rvm: 2.4.1
46
46
  env: SAMPLE_APP=rails_5_1_1 STRATEGY=active_job SIDEKIQ_SUPPORTED=true
47
+ - rvm: 2.3.4
48
+ env: SAMPLE_APP=rails_4_0_0 STATE_MACHINE_VERSION=1.1.2
49
+ - rvm: 2.4.1
50
+ env: SAMPLE_APP=rails_5_1_1 STATE_MACHINES_ACTIVERECORD_VERSION=">=0.5"
51
+ - rvm: 2.4.1
52
+ env: SAMPLE_APP=rails_5_0_3 STATE_MACHINES_ACTIVERECORD_VERSION=0.4
53
+ - rvm: 2.4.1
54
+ env: SAMPLE_APP=rails_4_2_8 STATE_MACHINES_ACTIVERECORD_VERSION=0.3 STATE_MACHINES_VERSION=0.4
47
55
  notifications:
48
56
  slack:
49
57
  secure: 6IAlvKplFv94Vaf0LES197FFIgt5cs1fUFA9820mmeoTGLDQcN+4Hpv+2/NRRqrfb2k+V+uFKmsuY8azHBoKHLIzH6d1T0NS82j54Ti+tm0iFZaKLHVp8TxuIge0/e0Niamod5mMziLTg6KcM+zNBYcoxS3th1mQNWQ2mtD9JZ8=
@@ -1,5 +1,10 @@
1
1
  # chillout gem changes
2
2
 
3
+ 0.8.8
4
+ -----
5
+
6
+ - Introduced `state_machine` / `state_machines-activerecord` transitions monitoring.
7
+
3
8
  0.8.7
4
9
  -----
5
10
 
@@ -4,6 +4,7 @@ require "chillout/creations_container"
4
4
  require "chillout/custom_advanced_metric"
5
5
  require "chillout/middleware/creations_monitor"
6
6
  require "chillout/integrations/sidekiq"
7
+ require "chillout/integrations/state_machine"
7
8
  require "chillout/subscribers/action_controller_notifications"
8
9
  require "chillout/server_side/dispatcher"
9
10
  require "chillout/server_side/server_side"
@@ -0,0 +1,90 @@
1
+ module Chillout
2
+ module Integrations
3
+
4
+ class StateMachineTransitionMeasurement
5
+
6
+ def initialize(instance, transition, started, finished)
7
+ @class = instance.class.name
8
+
9
+ @attribute = transition.attribute.to_s
10
+ @event = transition.event.to_s
11
+ @from = transition.from.to_s
12
+ @to = transition.to.to_s
13
+
14
+ @started = started.utc
15
+ @finished = finished.utc
16
+ @duration = 1000.0 * (@finished.to_f - @started.to_f)
17
+ end
18
+
19
+ def job_class
20
+ @class
21
+ end
22
+
23
+ def as_measurements()
24
+ [{
25
+ series: "#{@class}##{@attribute}",
26
+ tags: {
27
+ class: @class,
28
+ attribute: @attribute,
29
+ event: @event,
30
+ from: @from,
31
+ to: @to,
32
+ },
33
+ timestamp: @finished.iso8601,
34
+ values: {
35
+ value: 1,
36
+ duration: @duration.to_f,
37
+ },
38
+ }]
39
+ end
40
+
41
+ end
42
+
43
+ class StateMachine
44
+
45
+ def available?
46
+ if defined?(::StateMachines::Integrations::ActiveRecord::VERSION) && defined?(::ActiveRecord)
47
+ return Gem::Version.new(::StateMachines::Integrations::ActiveRecord::VERSION) >= Gem::Version.new('0.3.0')
48
+ end
49
+ if defined?(::StateMachine) && defined?(::ActiveRecord)
50
+ require 'state_machine/version'
51
+ return Gem::Version.new(::StateMachine::VERSION) >= Gem::Version.new('1.1.2')
52
+ end
53
+ rescue
54
+ false
55
+ end
56
+
57
+ def enable(client)
58
+ callback_class = defined?(::StateMachine::Callback) ? ::StateMachine::Callback : ::StateMachines::Callback
59
+ ActiveRecord::Base.subclasses.select do |klass|
60
+ klass.respond_to?(:state_machines)
61
+ end.each do |klass|
62
+ klass.state_machines.each_value do |state_machine|
63
+ state_machine.callbacks[:before].unshift(
64
+ callback_class.new(:around, &callback(client))
65
+ )
66
+ end
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def callback(client)
73
+ Proc.new do |instance, transition, block|
74
+ started = Time.now.utc
75
+ block.call
76
+ finished = Time.now.utc
77
+ client.enqueue(StateMachineTransitionMeasurement.new(
78
+ instance,
79
+ transition,
80
+ started,
81
+ finished,
82
+ ))
83
+ true
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
@@ -4,15 +4,24 @@ require 'chillout/listener_injector'
4
4
  module Chillout
5
5
  class Railtie < Rails::Railtie
6
6
  config.chillout = ActiveSupport::OrderedOptions.new
7
+ chillout_init = nil
8
+
7
9
  initializer "chillout.creations_listener_initialization" do |rails_app|
8
10
  chillout_config = rails_app.config.chillout
9
11
  if chillout_config.present?
10
- RailsInitializer.new(rails_app, chillout_config, Rails.logger).start
12
+ chillout_init = RailsInitializer.new(rails_app, chillout_config, Rails.logger)
13
+ chillout_init.start
11
14
  else
12
15
  Rails.logger.debug "[Chillout] Not enabled for #{Rails.env}"
13
16
  end
14
17
  end
15
18
 
19
+ initializer "chillout.after_eager_load", after: :eager_load! do
20
+ if chillout_init
21
+ chillout_init.after_eager_load
22
+ end
23
+ end
24
+
16
25
  rake_tasks do
17
26
  load "chillout/tasks.rb"
18
27
  end
@@ -53,6 +62,11 @@ module Chillout
53
62
  Chillout.client = client
54
63
  end
55
64
 
65
+ def after_eager_load
66
+ state_machine = Integrations::StateMachine.new
67
+ state_machine.enable(Chillout.client) if state_machine.available?
68
+ end
69
+
56
70
  private
57
71
 
58
72
  def options
@@ -1,3 +1,3 @@
1
1
  module Chillout
2
- VERSION = "0.8.7"
2
+ VERSION = "0.8.8"
3
3
  end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class ClientSendsStateMachineMetrics < AcceptanceTestCase
4
+
5
+ def test_client_sends_state_machine_metrics
6
+ test_app = TestApp.new
7
+ test_endpoint = TestEndpoint.new(port: 8085)
8
+ test_user = TestUser.new
9
+
10
+ test_endpoint.listen
11
+ test_app.boot(chillout_port: 8085)
12
+ if ENV['STRATEGY'] != 'active_job'
13
+ assert test_endpoint.has_received_information_about_startup
14
+ end
15
+ test_user.transition_entity('Yay')
16
+ assert transition = test_endpoint.has_one_state_machine_metric
17
+
18
+ assert_equal "Entity#state", transition["series"]
19
+ assert_equal "Entity", transition["tags"]["class"]
20
+ assert_equal "state", transition["tags"]["attribute"]
21
+ assert_equal "ignite", transition["tags"]["event"]
22
+ assert_equal "parked", transition["tags"]["from"]
23
+ assert_equal "idling", transition["tags"]["to"]
24
+
25
+ assert_equal 1, transition["values"]["value"]
26
+ assert_operator 100, :<, transition["values"]["duration"]
27
+ assert_operator 600, :>, transition["values"]["duration"]
28
+
29
+ assert transition = test_endpoint.has_one_state_machine_metric
30
+
31
+ assert_equal "Entity#state", transition["series"]
32
+ assert_equal "Entity", transition["tags"]["class"]
33
+ assert_equal "state", transition["tags"]["attribute"]
34
+ assert_equal "shift_up", transition["tags"]["event"]
35
+ assert_equal "idling", transition["tags"]["from"]
36
+ assert_equal "first_gear", transition["tags"]["to"]
37
+
38
+ assert_equal 1, transition["values"]["value"]
39
+ assert_operator 0, :<, transition["values"]["duration"]
40
+ assert_operator 200, :>, transition["values"]["duration"]
41
+ ensure
42
+ test_app.shutdown if test_app
43
+ end
44
+
45
+ end
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
3
3
  gem 'rails', '4.0.0'
4
4
  gem 'sqlite3'
5
5
  gem 'chillout', :path => '../../../'
6
+ gem "state_machine", ENV['STATE_MACHINE_VERSION'] || ">= 1.2"
@@ -31,7 +31,7 @@ class EntitiesController < ApplicationController
31
31
  end
32
32
 
33
33
  def create
34
- @entity = Entity.new(params.require(:entity).permit!)
34
+ @entity = Entity.new(params.require(:entity).permit!.merge(state: "parked"))
35
35
 
36
36
  respond_to do |format|
37
37
  if @entity.save
@@ -0,0 +1,8 @@
1
+ class TransitionsController < ApplicationController
2
+ def create
3
+ e = Entity.new(state: "parked")
4
+ e.ignite
5
+ e.shift_up
6
+ head :ok
7
+ end
8
+ end
@@ -1,2 +1,36 @@
1
1
  class Entity < ActiveRecord::Base
2
- end
2
+ state_machine :initial => :parked do
3
+ before_transition :parked => any - :parked, do: :put_on_seatbelt
4
+ after_transition any => :parked do |vehicle, _transition|
5
+ vehicle.seatbelt = 'off'
6
+ end
7
+ around_transition :benchmark
8
+
9
+ event :ignite do
10
+ transition :parked => :idling
11
+ end
12
+
13
+ event :shift_up do
14
+ transition :idling => :first_gear,
15
+ :first_gear => :second_gear,
16
+ :second_gear => :third_gear
17
+ end
18
+
19
+ state :first_gear, :second_gear do
20
+ validates_presence_of :seatbelt_on
21
+ end
22
+ end
23
+
24
+ def put_on_seatbelt
25
+ sleep(0.1)
26
+ self.seatbelt = 'on'
27
+ end
28
+
29
+ def benchmark
30
+ yield
31
+ end
32
+
33
+ def seatbelt_on
34
+ self.seatbelt == 'on'
35
+ end
36
+ end
@@ -1,4 +1,5 @@
1
1
  Rails400::Application.routes.draw do
2
2
  resources :entities
3
3
  resources :purchases, only: %i(create)
4
+ resources :transitions, only: %i(create)
4
5
  end
@@ -15,6 +15,8 @@ ActiveRecord::Schema.define(:version => 20130103115400) do
15
15
 
16
16
  create_table "entities", :force => true do |t|
17
17
  t.string "name"
18
+ t.string "state"
19
+ t.string "seatbelt"
18
20
  t.datetime "created_at", :null => false
19
21
  t.datetime "updated_at", :null => false
20
22
  end
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
3
3
  gem 'rails', '4.0.13'
4
4
  gem 'sqlite3'
5
5
  gem 'chillout', :path => '../../../'
6
+ gem "state_machine", ENV['STATE_MACHINE_VERSION'] || ">= 1.2"
@@ -31,7 +31,7 @@ class EntitiesController < ApplicationController
31
31
  end
32
32
 
33
33
  def create
34
- @entity = Entity.new(params.require(:entity).permit!)
34
+ @entity = Entity.new(params.require(:entity).permit!.merge(state: "parked"))
35
35
 
36
36
  respond_to do |format|
37
37
  if @entity.save
@@ -0,0 +1,8 @@
1
+ class TransitionsController < ApplicationController
2
+ def create
3
+ e = Entity.new(state: "parked")
4
+ e.ignite
5
+ e.shift_up
6
+ head :ok
7
+ end
8
+ end
@@ -1,2 +1,36 @@
1
1
  class Entity < ActiveRecord::Base
2
- end
2
+ state_machine :initial => :parked do
3
+ before_transition :parked => any - :parked, do: :put_on_seatbelt
4
+ after_transition any => :parked do |vehicle, _transition|
5
+ vehicle.seatbelt = 'off'
6
+ end
7
+ around_transition :benchmark
8
+
9
+ event :ignite do
10
+ transition :parked => :idling
11
+ end
12
+
13
+ event :shift_up do
14
+ transition :idling => :first_gear,
15
+ :first_gear => :second_gear,
16
+ :second_gear => :third_gear
17
+ end
18
+
19
+ state :first_gear, :second_gear do
20
+ validates_presence_of :seatbelt_on
21
+ end
22
+ end
23
+
24
+ def put_on_seatbelt
25
+ sleep(0.1)
26
+ self.seatbelt = 'on'
27
+ end
28
+
29
+ def benchmark
30
+ yield
31
+ end
32
+
33
+ def seatbelt_on
34
+ self.seatbelt == 'on'
35
+ end
36
+ end
@@ -1,4 +1,5 @@
1
1
  Rails400::Application.routes.draw do
2
2
  resources :entities
3
3
  resources :purchases, only: %i(create)
4
+ resources :transitions, only: %i(create)
4
5
  end
@@ -15,6 +15,8 @@ ActiveRecord::Schema.define(:version => 20130103115400) do
15
15
 
16
16
  create_table "entities", :force => true do |t|
17
17
  t.string "name"
18
+ t.string "state"
19
+ t.string "seatbelt"
18
20
  t.datetime "created_at", :null => false
19
21
  t.datetime "updated_at", :null => false
20
22
  end
@@ -3,3 +3,4 @@ source 'https://rubygems.org'
3
3
  gem 'rails', '4.1.0'
4
4
  gem 'sqlite3'
5
5
  gem 'chillout', :path => '../../../'
6
+ gem "state_machine", ENV['STATE_MACHINE_VERSION'] || ">= 1.2"
@@ -31,7 +31,7 @@ class EntitiesController < ApplicationController
31
31
  end
32
32
 
33
33
  def create
34
- @entity = Entity.new(params.require(:entity).permit!)
34
+ @entity = Entity.new(params.require(:entity).permit!.merge(state: "parked"))
35
35
 
36
36
  respond_to do |format|
37
37
  if @entity.save
@@ -0,0 +1,8 @@
1
+ class TransitionsController < ApplicationController
2
+ def create
3
+ e = Entity.new(state: "parked")
4
+ e.ignite
5
+ e.shift_up
6
+ head :ok
7
+ end
8
+ end
@@ -1,2 +1,36 @@
1
1
  class Entity < ActiveRecord::Base
2
- end
2
+ state_machine :initial => :parked do
3
+ before_transition :parked => any - :parked, do: :put_on_seatbelt
4
+ after_transition any => :parked do |vehicle, _transition|
5
+ vehicle.seatbelt = 'off'
6
+ end
7
+ around_transition :benchmark
8
+
9
+ event :ignite do
10
+ transition :parked => :idling
11
+ end
12
+
13
+ event :shift_up do
14
+ transition :idling => :first_gear,
15
+ :first_gear => :second_gear,
16
+ :second_gear => :third_gear
17
+ end
18
+
19
+ state :first_gear, :second_gear do
20
+ validates_presence_of :seatbelt_on
21
+ end
22
+ end
23
+
24
+ def put_on_seatbelt
25
+ sleep(0.1)
26
+ self.seatbelt = 'on'
27
+ end
28
+
29
+ def benchmark
30
+ yield
31
+ end
32
+
33
+ def seatbelt_on
34
+ self.seatbelt == 'on'
35
+ end
36
+ end