opera 0.3.3 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +38 -8
- data/lib/opera/operation/base.rb +3 -1
- data/lib/opera/operation/builder.rb +1 -0
- data/lib/opera/operation/config.rb +9 -2
- data/lib/opera/operation/instructions/executors/benchmark.rb +8 -1
- data/lib/opera/operation/instructions/executors/step.rb +4 -2
- data/lib/opera/operation/instrumentation.rb +44 -0
- data/lib/opera/operation.rb +1 -0
- data/lib/opera/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d44889b440322513ca1bb949f4d57d317141196e76bb56a67447b200d8dac47
|
4
|
+
data.tar.gz: fdd2f513da963271101a5f9f5bcf9f3d4d8c65ea9a15d743c804cc97b764e501
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d744526b9a983f73f2f5560f62938794bbf10b8dab9e2564c9916ec921aa9509489ff6c6611256502085c6f7b9f5c2a631e90e31f2cebc89bf5a3df2bd7e7ce8
|
7
|
+
data.tar.gz: 3b7a366e473983a416fcb4b22ed01791d1f89b5cc06fb9daf1f6af244df158e8891de9def6233654611217787cb16417d55d5a3b117ac47b8f2dcd7a60faf360
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -37,7 +37,10 @@ Simply initialise the configuration and chose what method you want to use to rep
|
|
37
37
|
Opera::Operation::Config.configure do |config|
|
38
38
|
config.transaction_class = ActiveRecord::Base
|
39
39
|
config.transaction_method = :transaction
|
40
|
-
config.transaction_options = { requires_new: true }
|
40
|
+
config.transaction_options = { requires_new: true, level: :step } # or level: :operation - default
|
41
|
+
config.instrumentation_class = Datadog::Tracing
|
42
|
+
config.instrumentation_method = :trace
|
43
|
+
config.instrumentation_options = { service: :operation }
|
41
44
|
config.mode = :development # Can be set to production too
|
42
45
|
config.reporter = defined?(Rollbar) ? Rollbar : Rails.logger
|
43
46
|
end
|
@@ -52,7 +55,6 @@ Once opera gem is in your project you can start to build Operations
|
|
52
55
|
|
53
56
|
```ruby
|
54
57
|
class A < Opera::Operation::Base
|
55
|
-
|
56
58
|
configure do |config|
|
57
59
|
config.transaction_class = Profile
|
58
60
|
config.reporter = Rails.logger
|
@@ -96,18 +98,44 @@ Start developing your business logic, services and interactions as Opera::Operat
|
|
96
98
|
When using Opera::Operation inside an engine add the following
|
97
99
|
configuration to your spec_helper.rb or rails_helper.rb:
|
98
100
|
|
99
|
-
```
|
101
|
+
```ruby
|
100
102
|
Opera::Operation::Config.configure do |config|
|
101
103
|
config.transaction_class = ActiveRecord::Base
|
102
104
|
end
|
103
105
|
```
|
104
106
|
|
105
107
|
Without this extra configuration you will receive:
|
106
|
-
```
|
108
|
+
```ruby
|
107
109
|
NoMethodError:
|
108
110
|
undefined method `transaction' for nil:NilClass
|
109
111
|
```
|
110
112
|
|
113
|
+
### Instrumentation
|
114
|
+
|
115
|
+
When you want to easily instrument your operations you can add this to the opera config:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
Rails.application.configure do
|
119
|
+
config.x.instrumentation_class = Datadog::Tracing
|
120
|
+
config.x.instrumentation_method = :trace
|
121
|
+
config.x.instrumentation_options = { service: :opera }
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
You can also instrument individual operations by adding this to the operation config:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
class A < Opera::Operation::Base
|
129
|
+
configure do |config|
|
130
|
+
config.instrumentation_class = Datadog::Tracing
|
131
|
+
config.instrumentation_method = :trace
|
132
|
+
config.instrumentation_options = { service: :opera, level: :step }
|
133
|
+
end
|
134
|
+
|
135
|
+
# steps
|
136
|
+
end
|
137
|
+
```
|
138
|
+
|
111
139
|
### Debugging
|
112
140
|
|
113
141
|
When you want to easily debug exceptions you can add this
|
@@ -674,10 +702,12 @@ class Profile::Create < Opera::Operation::Base
|
|
674
702
|
|
675
703
|
validate :profile_schema
|
676
704
|
|
677
|
-
|
678
|
-
|
705
|
+
benchmark :fast_section do
|
706
|
+
step :create
|
707
|
+
step :update
|
708
|
+
end
|
679
709
|
|
680
|
-
benchmark do
|
710
|
+
benchmark :slow_section do
|
681
711
|
step :send_email
|
682
712
|
step :output
|
683
713
|
end
|
@@ -717,7 +747,7 @@ Profile::Create.call(params: {
|
|
717
747
|
}, dependencies: {
|
718
748
|
current_account: Account.find(1)
|
719
749
|
})
|
720
|
-
#<Opera::Operation::Result:0x007ff414a01238 @errors={}, @exceptions={}, @information={:real=>1.800013706088066e-05, :total=>0.0}, @executions=[:profile_schema, :create, :update, :send_email, :output], @output={:model=>#<Profile id: 30, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-19 10:46:00", updated_at: "2020-08-18 10:46:00", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
750
|
+
#<Opera::Operation::Result:0x007ff414a01238 @errors={}, @exceptions={}, @information={fast_section: {:real=>0.300013706088066e-05, :total=>0.0}, slow_section: {:real=>1.800013706088066e-05, :total=>0.0}}, @executions=[:profile_schema, :create, :update, :send_email, :output], @output={:model=>#<Profile id: 30, user_id: nil, linkedin_uid: nil, picture: nil, headline: nil, summary: nil, first_name: "foo", last_name: "bar", created_at: "2020-08-19 10:46:00", updated_at: "2020-08-18 10:46:00", agree_to_terms_and_conditions: nil, registration_status: "", account_id: 1, start_date: nil, supervisor_id: nil, picture_processing: false, statistics: {}, data: {}, notification_timestamps: {}, suggestions: {}, notification_settings: {}, contact_information: []>}>
|
721
751
|
```
|
722
752
|
|
723
753
|
### Success
|
data/lib/opera/operation/base.rb
CHANGED
@@ -33,7 +33,9 @@ module Opera
|
|
33
33
|
def call(args = {})
|
34
34
|
operation = new(params: args.fetch(:params, {}), dependencies: args.fetch(:dependencies, {}))
|
35
35
|
executor = Executor.new(operation)
|
36
|
-
|
36
|
+
Instrumentation.new(config).instrument(name: self.name, level: :operation) do
|
37
|
+
executor.evaluate_instructions(instructions)
|
38
|
+
end
|
37
39
|
executor.result
|
38
40
|
end
|
39
41
|
|
@@ -6,12 +6,18 @@ module Opera
|
|
6
6
|
DEVELOPMENT_MODE = :development
|
7
7
|
PRODUCTION_MODE = :production
|
8
8
|
|
9
|
-
attr_accessor :transaction_class, :transaction_method, :transaction_options,
|
9
|
+
attr_accessor :transaction_class, :transaction_method, :transaction_options,
|
10
|
+
:instrumentation_class, :instrumentation_method, :instrumentation_options, :mode, :reporter
|
10
11
|
|
11
12
|
def initialize
|
12
13
|
@transaction_class = self.class.transaction_class
|
13
14
|
@transaction_method = self.class.transaction_method || :transaction
|
14
15
|
@transaction_options = self.class.transaction_options
|
16
|
+
|
17
|
+
@instrumentation_class = self.class.instrumentation_class
|
18
|
+
@instrumentation_method = self.class.instrumentation_method || :instrument
|
19
|
+
@instrumentation_options = self.class.instrumentation_options || {}
|
20
|
+
|
15
21
|
@mode = self.class.mode || DEVELOPMENT_MODE
|
16
22
|
@reporter = custom_reporter || self.class.reporter
|
17
23
|
|
@@ -35,7 +41,8 @@ module Opera
|
|
35
41
|
end
|
36
42
|
|
37
43
|
class << self
|
38
|
-
attr_accessor :transaction_class, :transaction_method, :transaction_options,
|
44
|
+
attr_accessor :transaction_class, :transaction_method, :transaction_options,
|
45
|
+
:instrumentation_class, :instrumentation_method, :instrumentation_options, :mode, :reporter
|
39
46
|
|
40
47
|
def configure
|
41
48
|
yield self
|
@@ -7,10 +7,17 @@ module Opera
|
|
7
7
|
class Benchmark < Executor
|
8
8
|
def call(instruction)
|
9
9
|
benchmark = ::Benchmark.measure do
|
10
|
+
instruction[:kind] = :step
|
10
11
|
super
|
11
12
|
end
|
12
13
|
|
13
|
-
result.add_information(real: benchmark.real, total: benchmark.total)
|
14
|
+
result.add_information(benchmark_key(instruction) => { real: benchmark.real, total: benchmark.total })
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def benchmark_key(instruction)
|
20
|
+
instruction[:method] || instruction[:label] || instruction[:instructions].map { |e| e[:method] }.join('-').to_sym
|
14
21
|
end
|
15
22
|
end
|
16
23
|
end
|
@@ -8,8 +8,10 @@ module Opera
|
|
8
8
|
def call(instruction)
|
9
9
|
method = instruction[:method]
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
Instrumentation.new(config).instrument(name: "##{method}", level: :step) do
|
12
|
+
operation.result.add_execution(method) unless production_mode?
|
13
|
+
operation.send(method)
|
14
|
+
end
|
13
15
|
rescue StandardError => exception
|
14
16
|
reporter&.error(exception)
|
15
17
|
operation.result.add_exception(method, "#{exception.message}, for #{operation.inspect}", classname: operation.class.name)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Opera
|
4
|
+
module Operation
|
5
|
+
class Instrumentation
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
def initialize(config)
|
9
|
+
@config = config
|
10
|
+
end
|
11
|
+
|
12
|
+
def instrument(name:, level: :operation)
|
13
|
+
return yield if !instrumentation_enabled?
|
14
|
+
return yield if level == :step && instrumentation_level != :step
|
15
|
+
|
16
|
+
instrumentation_class.send(instrumentation_method, name, **instrumentation_options.except(:level)) do
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def instrumentation_options
|
24
|
+
config.instrumentation_options
|
25
|
+
end
|
26
|
+
|
27
|
+
def instrumentation_method
|
28
|
+
config.instrumentation_method
|
29
|
+
end
|
30
|
+
|
31
|
+
def instrumentation_class
|
32
|
+
config.instrumentation_class
|
33
|
+
end
|
34
|
+
|
35
|
+
def instrumentation_enabled?
|
36
|
+
!!config.instrumentation_class
|
37
|
+
end
|
38
|
+
|
39
|
+
def instrumentation_level
|
40
|
+
instrumentation_options[:level] || :operation
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/opera/operation.rb
CHANGED
@@ -4,6 +4,7 @@ require 'opera/operation/attributes_dsl'
|
|
4
4
|
require 'opera/operation/builder'
|
5
5
|
require 'opera/operation/base'
|
6
6
|
require 'opera/operation/executor'
|
7
|
+
require 'opera/operation/instrumentation'
|
7
8
|
require 'opera/operation/result'
|
8
9
|
require 'opera/operation/config'
|
9
10
|
require 'opera/operation/instructions/executors/success'
|
data/lib/opera/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opera
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ProFinda Development Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-validation
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/opera/operation/instructions/executors/success.rb
|
92
92
|
- lib/opera/operation/instructions/executors/transaction.rb
|
93
93
|
- lib/opera/operation/instructions/executors/validate.rb
|
94
|
+
- lib/opera/operation/instrumentation.rb
|
94
95
|
- lib/opera/operation/result.rb
|
95
96
|
- lib/opera/version.rb
|
96
97
|
- opera.gemspec
|