startback-jobs 0.14.0 → 0.14.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/lib/startback/ext/support/operation_runner.rb +17 -0
  4. data/lib/startback/ext/web/api.rb +12 -0
  5. data/lib/startback/ext.rb +2 -2
  6. data/lib/startback/jobs/agent.rb +15 -0
  7. data/lib/startback/jobs/api.rb +12 -0
  8. data/lib/startback/jobs/event/job_created.rb +8 -0
  9. data/lib/startback/jobs/event/job_ran.rb +8 -0
  10. data/lib/startback/jobs/event.rb +8 -0
  11. data/lib/startback/jobs/model/job.rb +35 -0
  12. data/lib/startback/jobs/model.rb +12 -0
  13. data/lib/startback/jobs/operation/create_job.rb +37 -0
  14. data/lib/startback/jobs/operation/run_job.rb +35 -0
  15. data/lib/startback/jobs/operation.rb +8 -0
  16. data/lib/startback/jobs/services.rb +25 -0
  17. data/lib/startback/jobs/support/job_result/embedded.rb +15 -0
  18. data/lib/startback/jobs/support/job_result/not_ready.rb +15 -0
  19. data/lib/startback/jobs/support/job_result/redirect.rb +32 -0
  20. data/lib/startback/jobs/support/job_result.rb +31 -0
  21. data/lib/startback/jobs/support.rb +1 -0
  22. data/lib/startback/jobs.fio +44 -0
  23. data/lib/startback/jobs.rb +23 -0
  24. data/spec/spec_helper.rb +26 -33
  25. data/spec/unit/api/test_job_result.rb +121 -0
  26. data/spec/unit/model/test_job.rb +23 -0
  27. data/spec/unit/operation/test_create_job.rb +42 -0
  28. data/spec/unit/operation/test_run_job.rb +37 -0
  29. data/spec/unit/test_finitio_schema.rb +20 -0
  30. data/tasks/test.rake +0 -1
  31. metadata +29 -92
  32. data/README.md +0 -13
  33. data/lib/startback/audit/prometheus.rb +0 -87
  34. data/lib/startback/audit/shared.rb +0 -17
  35. data/lib/startback/audit/trailer.rb +0 -129
  36. data/lib/startback/audit.rb +0 -3
  37. data/lib/startback/caching/entity_cache.rb +0 -157
  38. data/lib/startback/caching/no_store.rb +0 -28
  39. data/lib/startback/caching/store.rb +0 -34
  40. data/lib/startback/context/h_factory.rb +0 -43
  41. data/lib/startback/context/middleware.rb +0 -53
  42. data/lib/startback/context.rb +0 -122
  43. data/lib/startback/errors.rb +0 -197
  44. data/lib/startback/event/agent.rb +0 -84
  45. data/lib/startback/event/bus/bunny/async.rb +0 -162
  46. data/lib/startback/event/bus/bunny.rb +0 -1
  47. data/lib/startback/event/bus/memory/async.rb +0 -45
  48. data/lib/startback/event/bus/memory/sync.rb +0 -35
  49. data/lib/startback/event/bus/memory.rb +0 -2
  50. data/lib/startback/event/bus.rb +0 -100
  51. data/lib/startback/event/engine.rb +0 -94
  52. data/lib/startback/event/ext/context.rb +0 -5
  53. data/lib/startback/event/ext/operation.rb +0 -13
  54. data/lib/startback/event.rb +0 -47
  55. data/lib/startback/ext/date_time.rb +0 -9
  56. data/lib/startback/ext/time.rb +0 -9
  57. data/lib/startback/model.rb +0 -6
  58. data/lib/startback/operation/error_operation.rb +0 -19
  59. data/lib/startback/operation/multi_operation.rb +0 -28
  60. data/lib/startback/operation.rb +0 -78
  61. data/lib/startback/services.rb +0 -11
  62. data/lib/startback/support/data_object.rb +0 -71
  63. data/lib/startback/support/env.rb +0 -41
  64. data/lib/startback/support/fake_logger.rb +0 -18
  65. data/lib/startback/support/hooks.rb +0 -48
  66. data/lib/startback/support/log_formatter.rb +0 -34
  67. data/lib/startback/support/logger.rb +0 -34
  68. data/lib/startback/support/operation_runner.rb +0 -150
  69. data/lib/startback/support/robustness.rb +0 -157
  70. data/lib/startback/support/transaction_manager.rb +0 -25
  71. data/lib/startback/support/transaction_policy.rb +0 -33
  72. data/lib/startback/support/world.rb +0 -54
  73. data/lib/startback/support.rb +0 -26
  74. data/lib/startback/version.rb +0 -8
  75. data/lib/startback/web/api.rb +0 -99
  76. data/lib/startback/web/auto_caching.rb +0 -85
  77. data/lib/startback/web/catch_all.rb +0 -52
  78. data/lib/startback/web/cors_headers.rb +0 -80
  79. data/lib/startback/web/health_check.rb +0 -49
  80. data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
  81. data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
  82. data/lib/startback/web/magic_assets.rb +0 -98
  83. data/lib/startback/web/middleware.rb +0 -13
  84. data/lib/startback/web/prometheus.rb +0 -16
  85. data/lib/startback/web/shield.rb +0 -58
  86. data/lib/startback.rb +0 -43
  87. data/spec/unit/audit/test_prometheus.rb +0 -72
  88. data/spec/unit/audit/test_trailer.rb +0 -105
  89. data/spec/unit/caching/test_entity_cache.rb +0 -136
  90. data/spec/unit/context/test_abstraction_factory.rb +0 -64
  91. data/spec/unit/context/test_dup.rb +0 -42
  92. data/spec/unit/context/test_fork.rb +0 -37
  93. data/spec/unit/context/test_h_factory.rb +0 -31
  94. data/spec/unit/context/test_middleware.rb +0 -45
  95. data/spec/unit/context/test_with_world.rb +0 -20
  96. data/spec/unit/context/test_world.rb +0 -17
  97. data/spec/unit/event/bus/memory/test_async.rb +0 -43
  98. data/spec/unit/event/bus/memory/test_sync.rb +0 -43
  99. data/spec/unit/support/hooks/test_after_hook.rb +0 -54
  100. data/spec/unit/support/hooks/test_before_hook.rb +0 -54
  101. data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
  102. data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
  103. data/spec/unit/support/test_data_object.rb +0 -156
  104. data/spec/unit/support/test_env.rb +0 -75
  105. data/spec/unit/support/test_robusteness.rb +0 -229
  106. data/spec/unit/support/test_transaction_manager.rb +0 -64
  107. data/spec/unit/support/test_world.rb +0 -72
  108. data/spec/unit/test_event.rb +0 -62
  109. data/spec/unit/test_operation.rb +0 -55
  110. data/spec/unit/test_support.rb +0 -40
  111. data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
  112. data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
  113. data/spec/unit/web/fixtures/assets/index.es6 +0 -1
  114. data/spec/unit/web/test_api.rb +0 -82
  115. data/spec/unit/web/test_auto_caching.rb +0 -81
  116. data/spec/unit/web/test_catch_all.rb +0 -77
  117. data/spec/unit/web/test_cors_headers.rb +0 -88
  118. data/spec/unit/web/test_healthcheck.rb +0 -59
  119. data/spec/unit/web/test_magic_assets.rb +0 -82
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Jobs
5
+ describe CreateJob do
6
+
7
+ let(:request) do
8
+ {
9
+ isReady: false,
10
+ opClass: 'CowSay',
11
+ opInput: {},
12
+ opContext: {},
13
+ createdBy: 'blambeau',
14
+ }
15
+ end
16
+
17
+ let(:jobs_relvar) do
18
+ Bmg.mutable([])
19
+ end
20
+
21
+ let(:context) do
22
+ Context.new.with_world(startback_jobs: jobs_relvar)
23
+ end
24
+
25
+ subject do
26
+ CreateJob.new(request).bind({
27
+ context: context,
28
+ }).call
29
+ end
30
+
31
+ it 'creates a job' do
32
+ expect(subject).to be_a(Model::Job)
33
+ expect(subject.id).not_to be_nil
34
+ end
35
+
36
+ it 'inserts the job in the relvar' do
37
+ subject
38
+ expect(jobs_relvar.count).to eql(1)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Jobs
5
+ describe RunJob do
6
+
7
+ let(:job_data) do
8
+ a_job_data
9
+ end
10
+
11
+ let(:jobs_relvar) do
12
+ Bmg.mutable([job_data])
13
+ end
14
+
15
+ let(:context) do
16
+ Context.new.with_world(startback_jobs: jobs_relvar)
17
+ end
18
+
19
+ subject do
20
+ RunJob.new(id: 'abcdef').bind({
21
+ context: context,
22
+ }).call
23
+ end
24
+
25
+ it 'runs the job' do
26
+ expect(subject).to eql('Hello !!')
27
+ end
28
+
29
+ it 'updates the job' do
30
+ subject
31
+ job_info = jobs_relvar.one
32
+ expect(job_info[:opResult]).to eql('Hello !!')
33
+ expect(job_info[:isReady]).to eql(true)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module Startback
4
+ module Jobs
5
+ describe 'Finitio schemas' do
6
+
7
+ it 'is correctly installed on stdlib' do
8
+ system = Finitio.system <<~FIO
9
+ @import startback/jobs
10
+
11
+ Job.Ref
12
+ FIO
13
+ expect {
14
+ system.dress({ id: "hello" })
15
+ }.not_to raise_error
16
+ end
17
+
18
+ end
19
+ end
20
+ end
data/tasks/test.rake CHANGED
@@ -1,5 +1,4 @@
1
1
  require 'rspec/core/rake_task'
2
- require 'path'
3
2
 
4
3
  namespace :test do
5
4
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: startback-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.0
4
+ version: 0.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-07 00:00:00.000000000 Z
11
+ date: 2022-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -118,14 +118,14 @@ dependencies:
118
118
  requirements:
119
119
  - - '='
120
120
  - !ruby/object:Gem::Version
121
- version: 0.14.0
121
+ version: 0.14.1
122
122
  type: :runtime
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - '='
127
127
  - !ruby/object:Gem::Version
128
- version: 0.14.0
128
+ version: 0.14.1
129
129
  description: Asynchronous jobs on top of the Startback framework
130
130
  email: blambeau@gmail.com
131
131
  executables: []
@@ -133,97 +133,34 @@ extensions: []
133
133
  extra_rdoc_files: []
134
134
  files:
135
135
  - Gemfile
136
- - README.md
137
136
  - Rakefile
138
- - lib/startback.rb
139
- - lib/startback/audit.rb
140
- - lib/startback/audit/prometheus.rb
141
- - lib/startback/audit/shared.rb
142
- - lib/startback/audit/trailer.rb
143
- - lib/startback/caching/entity_cache.rb
144
- - lib/startback/caching/no_store.rb
145
- - lib/startback/caching/store.rb
146
- - lib/startback/context.rb
147
- - lib/startback/context/h_factory.rb
148
- - lib/startback/context/middleware.rb
149
- - lib/startback/errors.rb
150
- - lib/startback/event.rb
151
- - lib/startback/event/agent.rb
152
- - lib/startback/event/bus.rb
153
- - lib/startback/event/bus/bunny.rb
154
- - lib/startback/event/bus/bunny/async.rb
155
- - lib/startback/event/bus/memory.rb
156
- - lib/startback/event/bus/memory/async.rb
157
- - lib/startback/event/bus/memory/sync.rb
158
- - lib/startback/event/engine.rb
159
- - lib/startback/event/ext/context.rb
160
- - lib/startback/event/ext/operation.rb
161
137
  - lib/startback/ext.rb
162
- - lib/startback/ext/date_time.rb
163
- - lib/startback/ext/time.rb
164
- - lib/startback/model.rb
165
- - lib/startback/operation.rb
166
- - lib/startback/operation/error_operation.rb
167
- - lib/startback/operation/multi_operation.rb
168
- - lib/startback/services.rb
169
- - lib/startback/support.rb
170
- - lib/startback/support/data_object.rb
171
- - lib/startback/support/env.rb
172
- - lib/startback/support/fake_logger.rb
173
- - lib/startback/support/hooks.rb
174
- - lib/startback/support/log_formatter.rb
175
- - lib/startback/support/logger.rb
176
- - lib/startback/support/operation_runner.rb
177
- - lib/startback/support/robustness.rb
178
- - lib/startback/support/transaction_manager.rb
179
- - lib/startback/support/transaction_policy.rb
180
- - lib/startback/support/world.rb
181
- - lib/startback/version.rb
182
- - lib/startback/web/api.rb
183
- - lib/startback/web/auto_caching.rb
184
- - lib/startback/web/catch_all.rb
185
- - lib/startback/web/cors_headers.rb
186
- - lib/startback/web/health_check.rb
187
- - lib/startback/web/magic_assets.rb
188
- - lib/startback/web/magic_assets/ng_html_transformer.rb
189
- - lib/startback/web/magic_assets/rake_tasks.rb
190
- - lib/startback/web/middleware.rb
191
- - lib/startback/web/prometheus.rb
192
- - lib/startback/web/shield.rb
138
+ - lib/startback/ext/support/operation_runner.rb
139
+ - lib/startback/ext/web/api.rb
140
+ - lib/startback/jobs.fio
141
+ - lib/startback/jobs.rb
142
+ - lib/startback/jobs/agent.rb
143
+ - lib/startback/jobs/api.rb
144
+ - lib/startback/jobs/event.rb
145
+ - lib/startback/jobs/event/job_created.rb
146
+ - lib/startback/jobs/event/job_ran.rb
147
+ - lib/startback/jobs/model.rb
148
+ - lib/startback/jobs/model/job.rb
149
+ - lib/startback/jobs/operation.rb
150
+ - lib/startback/jobs/operation/create_job.rb
151
+ - lib/startback/jobs/operation/run_job.rb
152
+ - lib/startback/jobs/services.rb
153
+ - lib/startback/jobs/support.rb
154
+ - lib/startback/jobs/support/job_result.rb
155
+ - lib/startback/jobs/support/job_result/embedded.rb
156
+ - lib/startback/jobs/support/job_result/not_ready.rb
157
+ - lib/startback/jobs/support/job_result/redirect.rb
193
158
  - spec/spec_helper.rb
194
- - spec/unit/audit/test_prometheus.rb
195
- - spec/unit/audit/test_trailer.rb
196
- - spec/unit/caching/test_entity_cache.rb
197
- - spec/unit/context/test_abstraction_factory.rb
198
- - spec/unit/context/test_dup.rb
199
- - spec/unit/context/test_fork.rb
200
- - spec/unit/context/test_h_factory.rb
201
- - spec/unit/context/test_middleware.rb
202
- - spec/unit/context/test_with_world.rb
203
- - spec/unit/context/test_world.rb
204
- - spec/unit/event/bus/memory/test_async.rb
205
- - spec/unit/event/bus/memory/test_sync.rb
206
- - spec/unit/support/hooks/test_after_hook.rb
207
- - spec/unit/support/hooks/test_before_hook.rb
208
- - spec/unit/support/operation_runner/test_around_run.rb
209
- - spec/unit/support/operation_runner/test_before_after_call.rb
210
- - spec/unit/support/test_data_object.rb
211
- - spec/unit/support/test_env.rb
212
- - spec/unit/support/test_robusteness.rb
213
- - spec/unit/support/test_transaction_manager.rb
214
- - spec/unit/support/test_world.rb
215
- - spec/unit/test_event.rb
216
- - spec/unit/test_operation.rb
217
- - spec/unit/test_support.rb
218
- - spec/unit/web/fixtures/assets/app/hello.es6
219
- - spec/unit/web/fixtures/assets/app/hello.html
220
- - spec/unit/web/fixtures/assets/index.es6
221
- - spec/unit/web/test_api.rb
222
- - spec/unit/web/test_auto_caching.rb
223
- - spec/unit/web/test_catch_all.rb
224
- - spec/unit/web/test_cors_headers.rb
225
- - spec/unit/web/test_healthcheck.rb
226
- - spec/unit/web/test_magic_assets.rb
159
+ - spec/unit/api/test_job_result.rb
160
+ - spec/unit/model/test_job.rb
161
+ - spec/unit/operation/test_create_job.rb
162
+ - spec/unit/operation/test_run_job.rb
163
+ - spec/unit/test_finitio_schema.rb
227
164
  - tasks/test.rake
228
165
  homepage: https://www.enspirit.be
229
166
  licenses:
data/README.md DELETED
@@ -1,13 +0,0 @@
1
- # Startback - Got Your Ruby Back
2
-
3
- Yet another ruby framework, I'm afraid. Here, we srongly seperate between:
4
-
5
- 1. the web layer, in charge of a quality HTTP handling
6
- 2. the operations layer, in charge of the high-level software operations
7
- 3. the database layer, abstracted using the Relations As First Class Citizen pattern
8
-
9
- Currently,
10
-
11
- 1. is handled using extra support on top of Sinatra
12
- 2. is handled using Startback specific classes
13
- 3. is handled using Bmg
@@ -1,87 +0,0 @@
1
- require_relative 'shared'
2
- require 'prometheus/client'
3
-
4
- module Startback
5
- module Audit
6
- #
7
- # Prometheus exporter abstraction, that can be registered as an around
8
- # hook on OperationRunner and as a prometheus client on Context instances.
9
- #
10
- # The exporter uses the ruby client for prometheus to expose metrics regarding Operation runs.
11
- #
12
- # The following metrics are exported:
13
- #
14
- # A counter 'operation_errors' (failed runs)
15
- # A histogram 'operation_calls'
16
- #
17
- # All these metrics use the following labels
18
- # - operation : class name of the operation executed
19
- #
20
- # Given that this Exporter is intended to be used as around hook on an
21
- # `OperationRunner`, operations that fail at construction time will not be
22
- # exported at all, since they can't be ran in the first place. This may lead
23
- # to metrics not containing important errors cases if operations check their
24
- # input at construction time.
25
- #
26
- class Prometheus
27
- include Shared
28
-
29
- def initialize(options = {})
30
- @prefix = options[:prefix] || "startback"
31
- @options = options
32
- @registry = ::Prometheus::Client.registry
33
- all_labels = [:operation, :startback_version] + option_labels.keys
34
- @errors = @registry.counter(
35
- :"#{prefix}_operation_errors",
36
- docstring: 'A counter of operation errors',
37
- labels: all_labels)
38
- @calls = @registry.histogram(
39
- :"#{prefix}_operation_calls",
40
- docstring: 'A histogram of operation latency',
41
- labels: all_labels)
42
- end
43
- attr_reader :registry, :calls, :errors, :options, :prefix
44
-
45
- def call(runner, op)
46
- name = op_name(op)
47
- result = nil
48
- time = Benchmark.realtime{
49
- result = yield
50
- }
51
- ignore_safely {
52
- @calls.observe(time, labels: get_labels(name))
53
- }
54
- result
55
- rescue => ex
56
- ignore_safely {
57
- @errors.increment(labels: get_labels(name))
58
- }
59
- raise
60
- end
61
-
62
- protected
63
-
64
- def ignore_safely
65
- yield
66
- rescue => ex
67
- nil
68
- end
69
-
70
- def get_labels(op_name)
71
- option_labels.merge({
72
- operation: op_name,
73
- startback_version: version
74
- })
75
- end
76
-
77
- def option_labels
78
- @options[:labels] || {}
79
- end
80
-
81
- def version
82
- Startback::VERSION
83
- end
84
-
85
- end # class Prometheus
86
- end # module Audit
87
- end # module Startback
@@ -1,17 +0,0 @@
1
- module Startback
2
- module Audit
3
- module Shared
4
-
5
- def op_name(op)
6
- return op.op_name if op.respond_to?(:op_name)
7
-
8
- case op
9
- when String then op
10
- when Class then op.name
11
- else op.class.name
12
- end
13
- end
14
-
15
- end # module Shared
16
- end # module Audit
17
- end # module Startback
@@ -1,129 +0,0 @@
1
- require_relative 'shared'
2
- require 'forwardable'
3
- module Startback
4
- module Audit
5
- #
6
- # Log & Audit trail abstraction, that can be registered as an around
7
- # hook on OperationRunner and as an actual logger on Context instances.
8
- #
9
- # The trail is outputted as JSON lines, using a Logger on the "device"
10
- # passed at construction. The following JSON entries are dumped:
11
- #
12
- # - severity : INFO or ERROR
13
- # - time : ISO8601 Datetime of operation execution
14
- # - op : class name of the operation executed
15
- # - op_took : Execution duration of the operation
16
- # - op_data : Dump of operation input data
17
- # - context : Execution context, through its `h` information contract (IC)
18
- #
19
- # Dumping of operation data follows the following duck typing conventions:
20
- #
21
- # - If the operation instance responds to `to_trail`, this data is taken
22
- # - If the operation instance responds to `input`, this data is taken
23
- # - If the operation instance responds to `request`, this data is taken
24
- # - Otherwise op_data is a JSON null
25
- #
26
- # By contributing to the Context's `h` IC, users can easily dump information that
27
- # makes sense (such as the operation execution requester).
28
- #
29
- # The class implements a sanitization process when dumping the context and
30
- # operation data. Blacklisted words taken in construction options are used to
31
- # prevent dumping hash keys that match them (insentively). Default stop words
32
- # are equivalent to:
33
- #
34
- # Trailer.new("/var/log/trail.log", {
35
- # blacklist: "token password secret credential"
36
- # })
37
- #
38
- # Please note that the sanitization process does not apply recursively if
39
- # the operation data is hierarchic. It only applies to the top object of
40
- # Hash and [Hash]. Use `Operation#to_trail` to fine-tune your audit trail.
41
- #
42
- # Given that this Trailer is intended to be used as around hook on an
43
- # `OperationRunner`, operations that fail at construction time will not be
44
- # trailed at all, since they can't be ran in the first place. This may lead
45
- # to trails not containing important errors cases if operations check their
46
- # input at construction time.
47
- #
48
- class Trailer
49
- include Shared
50
- extend Forwardable
51
- def_delegators :@logger, :debug, :info, :warn, :error, :fatal
52
-
53
- DEFAULT_OPTIONS = {
54
-
55
- # Words used to stop dumping for, e.g., security reasons
56
- blacklist: "token password secret credential"
57
-
58
- }
59
-
60
- def initialize(device, options = {})
61
- @options = DEFAULT_OPTIONS.merge(options)
62
- @logger = ::Logger.new(device, 'daily')
63
- @logger.formatter = Support::LogFormatter.new
64
- end
65
- attr_reader :logger, :options
66
-
67
- def call(runner, op)
68
- result = nil
69
- time = Benchmark.realtime{ result = yield }
70
- logger.info(op_to_trail(op, time))
71
- result
72
- rescue => ex
73
- logger.error(op_to_trail(op, time, ex))
74
- raise
75
- end
76
-
77
- protected
78
-
79
- def op_to_trail(op, time = nil, ex = nil)
80
- log_msg = {
81
- op_took: time ? time.round(8) : nil,
82
- op: op_name(op),
83
- context: op_context(op),
84
- op_data: op_data(op)
85
- }.compact
86
- log_msg[:error] = ex if ex
87
- log_msg
88
- end
89
-
90
- def op_context(op)
91
- sanitize(op.respond_to?(:context, false) ? op.context.to_h : {})
92
- end
93
-
94
- def op_data(op)
95
- data = if op.respond_to?(:op_data, false)
96
- op.op_data
97
- elsif op.respond_to?(:to_trail, false)
98
- op.to_trail
99
- elsif op.respond_to?(:input, false)
100
- op.input
101
- elsif op.respond_to?(:request, false)
102
- op.request
103
- elsif op.is_a?(Operation::MultiOperation)
104
- op.ops.map{ |sub_op| op_to_trail(sub_op) }
105
- end
106
- sanitize(data)
107
- end
108
-
109
- def sanitize(data)
110
- case data
111
- when Hash, OpenStruct
112
- data.dup.delete_if{|k| k.to_s =~ blacklist_rx }
113
- when Enumerable
114
- data.map{|elm| sanitize(elm) }.compact
115
- else
116
- data
117
- end
118
- end
119
-
120
- def blacklist_rx
121
- @blacklist_rx ||= Regexp.new(
122
- options[:blacklist].split(/\s+/).join("|"),
123
- Regexp::IGNORECASE
124
- )
125
- end
126
-
127
- end # class Trailer
128
- end # module Audit
129
- end # module Startback
@@ -1,3 +0,0 @@
1
- require_relative 'audit/shared'
2
- require_relative 'audit/trailer'
3
- require_relative 'audit/prometheus'
@@ -1,157 +0,0 @@
1
- module Startback
2
- module Caching
3
- #
4
- # A overriable caching abstraction aiming at making Entity-based caching easy.
5
- #
6
- # This class MUST be overriden:
7
- #
8
- # * the `load_entity` protected method MUST be implemented to load data from
9
- # a primary & context unaware key.
10
- #
11
- # * the `primary_key` protected method MAY be implemented to convert candidate
12
- # keys (received from ultimate callers) to primary keys. The method is also
13
- # a good place to check and/or log the keys actually used by callers.
14
- #
15
- # * the `context_free_key` protected method MAY be overriden to provide
16
- # domain unrelated caching keys from primary keys, e.g. by encoding the
17
- # context into the caching key itself, if needed.
18
- #
19
- # * the `valid?` protected method MAY be overriden to check validity of data
20
- # extracted from the cache and force a refresh even if found.
21
- #
22
- # An EntityCache takes an actual store at construction. The object must meet the
23
- # specification writtern in Store. The 'cache' ruby gem can be used in practice.
24
- #
25
- # Cache hits, outdated and miss are logged in debug, info, and info severity.
26
- # The `cache_hit`, `cache_outdated`, `cache_miss` protected methods MAY be
27
- # overriden to change that behavior.
28
- #
29
- class EntityCache
30
- include Support::Robustness
31
-
32
- class << self
33
-
34
- # Default time to live, in seconds
35
- attr_writer :default_ttl
36
-
37
- def default_ttl
38
- @default_ttl || (superclass.respond_to?(:default_ttl, true) && superclass.default_ttl) || 3600
39
- end
40
-
41
- end # class DSL
42
-
43
- def initialize(store, context = nil)
44
- @store = store
45
- @context = context
46
- end
47
- attr_reader :store, :context
48
-
49
- # Returns the entity corresponding to a given key.
50
- #
51
- # If the entity is not in cache, loads it and puts it in cache using
52
- # the caching options passed as second parameter.
53
- def get(candidate_key, caching_options = default_caching_options)
54
- pkey = primary_key(candidate_key)
55
- cache_key = encode_key(context_free_key(pkey))
56
- if store.exist?(cache_key)
57
- cached = store.get(cache_key)
58
- if valid?(pkey, cached)
59
- cache_hit(pkey, cached)
60
- return cached
61
- else
62
- cache_outdated(pkey, cached)
63
- end
64
- end
65
- cache_miss(pkey)
66
- load_entity(pkey).tap{|to_cache|
67
- store.set(cache_key, to_cache, caching_options)
68
- }
69
- end
70
-
71
- # Invalidates the cache under a given key.
72
- def invalidate(candidate_key)
73
- pkey = primary_key(candidate_key)
74
- cache_key = encode_key(context_free_key(pkey))
75
- store.delete(cache_key)
76
- end
77
-
78
- protected
79
-
80
- def cache_hit(pkey, cached)
81
- log(:debug, self, "cache_hit", context, op_data: pkey)
82
- end
83
-
84
- def cache_outdated(pkey, cached)
85
- log(:info, self, "cache_outdated", context, op_data: pkey)
86
- end
87
-
88
- def cache_miss(pkey)
89
- log(:info, self, "cache_miss", context, op_data: pkey)
90
- end
91
-
92
- def default_caching_options
93
- { ttl: self.class.default_ttl }
94
- end
95
-
96
- # Converts a candidate key to a primary key, so as to prevent
97
- # cache duplicates if callers are allowed to request an entity
98
- # through various keys.
99
- #
100
- # The default implementation returns the candidate key and MAY
101
- # be overriden.
102
- def primary_key(candidate_key)
103
- candidate_key
104
- end
105
-
106
- # Encodes a context free key to an actual cache key.
107
- #
108
- # Default implementation uses JSON.fast_generate but MAY be
109
- # overriden.
110
- def encode_key(context_free_key)
111
- JSON.fast_generate(context_free_key)
112
- end
113
-
114
- # Returns whether `cached` entity seems fresh enough to
115
- # be returned as a cache hit.
116
- #
117
- # This method provides a way to check freshness using, e.g.
118
- # `updated_at` or `etag` kind of entity fields. The default
119
- # implementation returns true and MAY be overriden.
120
- def valid?(primary_key, cached)
121
- true
122
- end
123
-
124
- # Converts a primary_key to a context_free_key, using the
125
- # context (instance variable) to encode the context itself
126
- # into the actual cache key.
127
- #
128
- # The default implementation simply returns the primary key
129
- # and MAY be overriden.
130
- def context_free_key(primary_key)
131
- full_key(primary_key)
132
- end
133
-
134
- # Deprecated, will be removed in 0.6.0. Use context_free_key
135
- # instead.
136
- def full_key(primary_key)
137
- primary_key
138
- end
139
-
140
- # Actually loads the entity using the given primary key, and
141
- # possibly the cache context.
142
- #
143
- # This method MUST be implemented and raises a NotImplementedError
144
- # by default.
145
- def load_entity(primary_key)
146
- load_raw_data(primary_key)
147
- end
148
-
149
- # Deprecated, will be removed in 0.6.0. Use load_entity
150
- # instead.
151
- def load_raw_data(*args, &bl)
152
- raise NotImplementedError, "#{self.class.name}#load_entity"
153
- end
154
-
155
- end # class EntityCache
156
- end # module Caching
157
- end # module Startback