startback-websocket 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 (110) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -2
  3. data/README.md +64 -9
  4. data/lib/startback/ext/context.rb +6 -0
  5. data/lib/startback/ext.rb +1 -2
  6. data/lib/startback/websocket/app.rb +82 -0
  7. data/lib/startback/websocket/hub/app.rb +28 -0
  8. data/lib/startback/websocket/hub/builder.rb +55 -0
  9. data/lib/startback/websocket/hub/errors.rb +9 -0
  10. data/lib/startback/websocket/hub/message.rb +29 -0
  11. data/lib/startback/websocket/hub/middleware/command_handler.rb +34 -0
  12. data/lib/startback/websocket/hub/middleware/room_handler.rb +30 -0
  13. data/lib/startback/websocket/hub/middleware.rb +12 -0
  14. data/lib/startback/websocket/hub/participant.rb +16 -0
  15. data/lib/startback/websocket/hub/room.rb +46 -0
  16. data/lib/startback/websocket/hub.rb +15 -0
  17. data/lib/startback/websocket.rb +8 -0
  18. data/spec/spec_helper.rb +21 -32
  19. data/spec/unit/hub/test_builder.rb +141 -0
  20. data/spec/unit/hub/test_room.rb +27 -0
  21. data/spec/unit/test_app.rb +35 -0
  22. data/tasks/test.rake +0 -1
  23. metadata +20 -91
  24. data/lib/startback/audit/prometheus.rb +0 -87
  25. data/lib/startback/audit/shared.rb +0 -17
  26. data/lib/startback/audit/trailer.rb +0 -129
  27. data/lib/startback/audit.rb +0 -3
  28. data/lib/startback/caching/entity_cache.rb +0 -157
  29. data/lib/startback/caching/no_store.rb +0 -28
  30. data/lib/startback/caching/store.rb +0 -34
  31. data/lib/startback/context/h_factory.rb +0 -43
  32. data/lib/startback/context/middleware.rb +0 -53
  33. data/lib/startback/context.rb +0 -122
  34. data/lib/startback/errors.rb +0 -197
  35. data/lib/startback/event/agent.rb +0 -84
  36. data/lib/startback/event/bus/bunny/async.rb +0 -162
  37. data/lib/startback/event/bus/bunny.rb +0 -1
  38. data/lib/startback/event/bus/memory/async.rb +0 -45
  39. data/lib/startback/event/bus/memory/sync.rb +0 -35
  40. data/lib/startback/event/bus/memory.rb +0 -2
  41. data/lib/startback/event/bus.rb +0 -100
  42. data/lib/startback/event/engine.rb +0 -94
  43. data/lib/startback/event/ext/context.rb +0 -5
  44. data/lib/startback/event/ext/operation.rb +0 -13
  45. data/lib/startback/event.rb +0 -47
  46. data/lib/startback/ext/date_time.rb +0 -9
  47. data/lib/startback/ext/time.rb +0 -9
  48. data/lib/startback/model.rb +0 -6
  49. data/lib/startback/operation/error_operation.rb +0 -19
  50. data/lib/startback/operation/multi_operation.rb +0 -28
  51. data/lib/startback/operation.rb +0 -78
  52. data/lib/startback/services.rb +0 -11
  53. data/lib/startback/support/data_object.rb +0 -71
  54. data/lib/startback/support/env.rb +0 -41
  55. data/lib/startback/support/fake_logger.rb +0 -18
  56. data/lib/startback/support/hooks.rb +0 -48
  57. data/lib/startback/support/log_formatter.rb +0 -34
  58. data/lib/startback/support/logger.rb +0 -34
  59. data/lib/startback/support/operation_runner.rb +0 -150
  60. data/lib/startback/support/robustness.rb +0 -157
  61. data/lib/startback/support/transaction_manager.rb +0 -25
  62. data/lib/startback/support/transaction_policy.rb +0 -33
  63. data/lib/startback/support/world.rb +0 -54
  64. data/lib/startback/support.rb +0 -26
  65. data/lib/startback/version.rb +0 -8
  66. data/lib/startback/web/api.rb +0 -99
  67. data/lib/startback/web/auto_caching.rb +0 -85
  68. data/lib/startback/web/catch_all.rb +0 -52
  69. data/lib/startback/web/cors_headers.rb +0 -80
  70. data/lib/startback/web/health_check.rb +0 -49
  71. data/lib/startback/web/magic_assets/ng_html_transformer.rb +0 -80
  72. data/lib/startback/web/magic_assets/rake_tasks.rb +0 -64
  73. data/lib/startback/web/magic_assets.rb +0 -98
  74. data/lib/startback/web/middleware.rb +0 -13
  75. data/lib/startback/web/prometheus.rb +0 -16
  76. data/lib/startback/web/shield.rb +0 -58
  77. data/lib/startback.rb +0 -43
  78. data/spec/unit/audit/test_prometheus.rb +0 -72
  79. data/spec/unit/audit/test_trailer.rb +0 -105
  80. data/spec/unit/caching/test_entity_cache.rb +0 -136
  81. data/spec/unit/context/test_abstraction_factory.rb +0 -64
  82. data/spec/unit/context/test_dup.rb +0 -42
  83. data/spec/unit/context/test_fork.rb +0 -37
  84. data/spec/unit/context/test_h_factory.rb +0 -31
  85. data/spec/unit/context/test_middleware.rb +0 -45
  86. data/spec/unit/context/test_with_world.rb +0 -20
  87. data/spec/unit/context/test_world.rb +0 -17
  88. data/spec/unit/event/bus/memory/test_async.rb +0 -43
  89. data/spec/unit/event/bus/memory/test_sync.rb +0 -43
  90. data/spec/unit/support/hooks/test_after_hook.rb +0 -54
  91. data/spec/unit/support/hooks/test_before_hook.rb +0 -54
  92. data/spec/unit/support/operation_runner/test_around_run.rb +0 -156
  93. data/spec/unit/support/operation_runner/test_before_after_call.rb +0 -48
  94. data/spec/unit/support/test_data_object.rb +0 -156
  95. data/spec/unit/support/test_env.rb +0 -75
  96. data/spec/unit/support/test_robusteness.rb +0 -229
  97. data/spec/unit/support/test_transaction_manager.rb +0 -64
  98. data/spec/unit/support/test_world.rb +0 -72
  99. data/spec/unit/test_event.rb +0 -62
  100. data/spec/unit/test_operation.rb +0 -55
  101. data/spec/unit/test_support.rb +0 -40
  102. data/spec/unit/web/fixtures/assets/app/hello.es6 +0 -4
  103. data/spec/unit/web/fixtures/assets/app/hello.html +0 -1
  104. data/spec/unit/web/fixtures/assets/index.es6 +0 -1
  105. data/spec/unit/web/test_api.rb +0 -82
  106. data/spec/unit/web/test_auto_caching.rb +0 -81
  107. data/spec/unit/web/test_catch_all.rb +0 -77
  108. data/spec/unit/web/test_cors_headers.rb +0 -88
  109. data/spec/unit/web/test_healthcheck.rb +0 -59
  110. data/spec/unit/web/test_magic_assets.rb +0 -82
@@ -1,78 +0,0 @@
1
- module Startback
2
- #
3
- # High-level Operation abstraction, that is a piece of code that executes
4
- # on demand and (generally) changes the state of the software system.
5
- #
6
- # An operation is basically an object that respond to `call`, but that
7
- # executes within a given world (see `bind`). It also has before and
8
- # after hooks that allows specifying what needs to be done before invoking
9
- # call and after having invoked it. All this protocol is actually under
10
- # the responsibility of an `OperationRunner`. Operations should not be
11
- # called manually by third-party code.
12
- #
13
- # Example:
14
- #
15
- # class SayHello < Startback::Operation
16
- #
17
- # before_call do
18
- # # e.g. check_some_permissions
19
- # end
20
- #
21
- # def call
22
- # puts "Hello"
23
- # end
24
- #
25
- # after_call do
26
- # # e.g. log and/or emit something on a bus
27
- # end
28
- #
29
- # end
30
- #
31
- class Operation
32
- extend Support::TransactionPolicy
33
- include Errors
34
- include Support::OperationRunner
35
- include Support::Hooks.new(:call)
36
-
37
- attr_accessor :world
38
- protected :world=
39
-
40
- def initialize(input = {})
41
- @input = input
42
- end
43
- attr_reader :input
44
-
45
- def bind(world)
46
- return self unless world
47
- self.world = world
48
- self
49
- end
50
-
51
- def method_missing(name, *args, &bl)
52
- return super unless args.empty? and bl.nil?
53
- return super unless world
54
- world.fetch(name){ super }
55
- end
56
-
57
- def respond_to?(name, *args)
58
- super || (world && world.has_key?(name))
59
- end
60
-
61
- def with_context(ctx = nil)
62
- old_world = self.world
63
- self.world = self.world.merge(context: ctx || old_world.context.dup)
64
- result = ctx ? yield : yield(self.world.context)
65
- self.world = old_world
66
- result
67
- end
68
-
69
- protected
70
-
71
- def operation_world(op)
72
- self.world
73
- end
74
-
75
- end # class Operation
76
- end # module Startback
77
- require_relative 'operation/error_operation'
78
- require_relative 'operation/multi_operation'
@@ -1,11 +0,0 @@
1
- module Startback
2
- class Services
3
- include Startback::Errors
4
-
5
- def initialize(context)
6
- @context = context
7
- end
8
- attr_reader :context
9
-
10
- end # class Services
11
- end # module Startback
@@ -1,71 +0,0 @@
1
- module Startback
2
- module Support
3
- module DataObject
4
-
5
- def initialize(data = {})
6
- @_data = data.dup.freeze
7
- end
8
-
9
- attr_writer :_data
10
- protected :_data=
11
-
12
- def method_missing(name, *args, &bl)
13
- return super unless args.empty? && bl.nil?
14
- return super unless pair = _data_key_for(name)
15
-
16
- pair.last ? !!@_data[pair.first] : @_data[pair.first]
17
- end
18
-
19
- def [](name)
20
- return nil unless pair = _data_key_for(name, false, false)
21
-
22
- @_data[pair.first]
23
- end
24
-
25
- def respond_to?(name)
26
- super || !_data_key_for(name).nil?
27
- end
28
-
29
- def to_data
30
- @_data
31
- end
32
- alias :to_h :to_data
33
-
34
- def to_json(*args, &bl)
35
- to_data.to_json(*args, &bl)
36
- end
37
-
38
- private
39
-
40
- def _data_key_for(key, try_camelize = _data_allow_camelize, try_query = _data_allow_query)
41
- if @_data.key?(key)
42
- [key, false]
43
- elsif @_data.key?(key.to_s)
44
- [key.to_s, false]
45
- elsif key.is_a?(String) && @_data.key?(key.to_sym)
46
- [key.to_sym, false]
47
- elsif try_camelize
48
- cam = key.to_s.gsub(/_([a-z])/){ $1.upcase }.to_sym
49
- _data_key_for(cam, false, true)
50
- elsif try_query && key.to_s =~ /\?$/
51
- got = _data_key_for(key[0...-1].to_sym, false, false)
52
- got ? [got.first, true] : _data_key_not_found(key)
53
- else
54
- _data_key_not_found(key)
55
- end
56
- end
57
-
58
- def _data_allow_camelize
59
- true
60
- end
61
-
62
- def _data_allow_query
63
- true
64
- end
65
-
66
- def _data_key_not_found(key)
67
- nil
68
- end
69
- end # module DataObject
70
- end # module Support
71
- end # module Startback
@@ -1,41 +0,0 @@
1
- module Startback
2
- module Support
3
- # This method provides the `env` and `env!` methods that
4
- # help querying environment variables easily.
5
- module Env
6
-
7
- # Returns an environment variable or raise an error if
8
- # not set.
9
- #
10
- # The result is always a String with no leading/trailing
11
- # spaces.
12
- #
13
- # If a block is given, the environment variable is yield
14
- # and the result of the block returned.
15
- def env!(key, default = nil, &bl)
16
- v = ENV[key].to_s.strip
17
- raise Startback::Error, "Missing ENV var `#{key}`" if v.empty?
18
-
19
- env(key, default, &bl)
20
- end
21
- module_function :env!
22
-
23
- # Returns an environment variable or the default value
24
- # passed as second argument.
25
- #
26
- # The result is always a String with no leading/trailing
27
- # spaces.
28
- #
29
- # If a block is given, the environment variable is yield
30
- # and the result of the block returned.
31
- def env(key, default = nil, &bl)
32
- v = ENV[key].to_s.strip
33
- v = v.empty? ? default : v
34
- v = bl.call(v) if bl && v
35
- v
36
- end
37
- module_function :env
38
-
39
- end # module Env
40
- end # module Support
41
- end # module Startback
@@ -1,18 +0,0 @@
1
- module Startback
2
- module Support
3
- class FakeLogger < Logger
4
-
5
- def initialize(*args)
6
- @last_msg = nil
7
- end
8
- attr_reader :last_msg
9
-
10
- [:debug, :info, :warn, :error, :fatal].each do |meth|
11
- define_method(meth) do |msg|
12
- @last_msg = msg
13
- end
14
- end
15
-
16
- end # class Logger
17
- end # module Support
18
- end # module Startback
@@ -1,48 +0,0 @@
1
- module Startback
2
- module Support
3
- class Hooks < Module
4
-
5
- def initialize(suffix)
6
- @suffix = suffix
7
- define_method :"before_#{suffix}" do
8
- self.class.__befores.each do |bl|
9
- instance_exec(&bl)
10
- end
11
- end
12
- define_method :"after_#{suffix}" do
13
- self.class.__afters.each do |bl|
14
- instance_exec(&bl)
15
- end
16
- end
17
- end
18
- attr_reader :suffix
19
-
20
- def included(by)
21
- by.instance_eval %Q{
22
- def __befores(create = false)
23
- if create
24
- @__befores ||= (superclass.respond_to?(:__befores, false) ? superclass.__befores.dup : [])
25
- end
26
- @__befores || (superclass.respond_to?(:__befores, false) ? superclass.__befores : [])
27
- end
28
-
29
- def __afters(create = false)
30
- if create
31
- @__afters ||= (superclass.respond_to?(:__afters, false) ? superclass.__afters.dup : [])
32
- end
33
- @__afters || (superclass.respond_to?(:__afters, false) ? superclass.__afters : [])
34
- end
35
-
36
- def before_#{suffix}(&bl)
37
- __befores(true) << bl
38
- end
39
-
40
- def after_#{suffix}(&bl)
41
- __afters(true) << bl
42
- end
43
- }
44
- end
45
-
46
- end # class Hooks
47
- end # module Support
48
- end # module Startback
@@ -1,34 +0,0 @@
1
- module Startback
2
- module Support
3
- class LogFormatter
4
-
5
- def call(severity, time, progname, msg)
6
- msg = { message: msg } if msg.is_a?(String)
7
- msg = { error: msg } if msg.is_a?(Exception)
8
- {
9
- severity: severity,
10
- time: time
11
- }.merge(msg)
12
- .merge(error: error_to_json(msg[:error], severity))
13
- .compact
14
- .to_json << "\n"
15
- end
16
-
17
- def error_to_json(error, severity = nil)
18
- return error if error.nil?
19
- return error if error.is_a?(String)
20
- return error.to_s unless error.is_a?(Exception)
21
-
22
- backtrace = error.backtrace[0..25] if severity == "FATAL"
23
- causes = error.causes.map{|c| error_to_json(c) } if error.respond_to?(:causes)
24
- causes = nil if causes && causes.empty?
25
- {
26
- message: error.message,
27
- backtrace: backtrace,
28
- causes: causes
29
- }.compact
30
- end
31
-
32
- end # class LogFormatter
33
- end # module Support
34
- end # module Startback
@@ -1,34 +0,0 @@
1
- module Startback
2
- module Support
3
- #
4
- # A Logger extension that sends info and debug messages to STDOUT
5
- # and other messages to STDERR. This is not configurable.
6
- #
7
- class Logger < ::Logger
8
-
9
- def initialize
10
- super(STDOUT)
11
- @err_logger = ::Logger.new(STDERR)
12
- end
13
-
14
- def self.level=(level)
15
- super.tap{
16
- @err_logger.level = level
17
- }
18
- end
19
-
20
- def warn(*args, &bl)
21
- @err_logger.warn(*args, &bl)
22
- end
23
-
24
- def error(*args, &bl)
25
- @err_logger.error(*args, &bl)
26
- end
27
-
28
- def fatal(*args, &bl)
29
- @err_logger.fatal(*args, &bl)
30
- end
31
-
32
- end # class Logger
33
- end # module Support
34
- end # module Startback
@@ -1,150 +0,0 @@
1
- module Startback
2
- module Support
3
- #
4
- # Support module for high-level architectural components that
5
- # execute operations as part of their logic, see e.g. Web::Api.
6
- #
7
- # This module contributes a `run` instance method that allows
8
- # binding an operation with a world, and executing it while
9
- # supporting around runners.
10
- #
11
- # Example:
12
- #
13
- # class HighLevelComponent
14
- # include Startback::Support::OperationRunner
15
- #
16
- # def some_method
17
- # # Runs the operation passed after some binding
18
- # run SomeOperation.new
19
- # end
20
- #
21
- # protected
22
- #
23
- # # Overriden to inject some extra world
24
- # def operation_world(op)
25
- # super(op).merge({ hello: "world" })
26
- # end
27
- #
28
- # # Execute this around op
29
- # around_run do |op, then_block|
30
- # puts "About to run #{op.inspect}"
31
- # then_block.call
32
- # end
33
- #
34
- # # SomeClass#call will be called with the operation
35
- # # as first parameter and a block as continuation
36
- # around_run SomeClass.new
37
- #
38
- # end
39
- #
40
- module OperationRunner
41
-
42
- # Contributes the hook DSL methods to classes that include
43
- # the OperationRunner module
44
- module ClassMethods
45
-
46
- # Registers a callable to be executed around operation running.
47
- #
48
- # In its block form, the callable is `instance_exec`uted on the
49
- # runner instance, with the operation passed as first parameter
50
- # and a then_block callable as second parameter (continuation):
51
- #
52
- # around_run do |op,then_block|
53
- # # do whatever you want with the op (already bounded)
54
- # puts op.inspect
55
- #
56
- # # do not forget to call the continuation block
57
- # then_block.call
58
- # end
59
- #
60
- # With a parameter responding to `#call`, the latter is invoked
61
- # with the operation as parameter and a block as continuation:
62
- #
63
- # class Arounder
64
- #
65
- # def call(op)
66
- # # do whatever you want with the op (already bounded)
67
- # puts op.inspect
68
- #
69
- # # do not forget to call the continuation block
70
- # yield
71
- # end
72
- #
73
- # end
74
- #
75
- def around_run(arounder = nil, &bl)
76
- raise ArgumentError, "Arg or block required" unless arounder || bl
77
- arounds(true) << [arounder || bl, arounder.nil?]
78
- end
79
-
80
- private
81
-
82
- def arounds(create = false)
83
- if create
84
- @arounds ||= superclass.respond_to?(:arounds, true) \
85
- ? superclass.send(:arounds, true).dup \
86
- : []
87
- end
88
- @arounds || (superclass.respond_to?(:arounds, true) ? superclass.send(:arounds, true) : [])
89
- end
90
-
91
- end
92
-
93
- # When included by a class/module, install the DSL methods
94
- def self.included(by)
95
- by.extend(ClassMethods)
96
- end
97
-
98
- # Runs `operation`, taking care of binding it and executing
99
- # hooks.
100
- #
101
- # This method is NOT intended to be overriden. Use hooks and
102
- # `operation_world` to impact default behavior.
103
- def run(operation)
104
- op_world = operation_world(operation)
105
- op_bound = operation.bind(op_world)
106
- _run_befores(op_bound)
107
- r = _run_with_arounds(op_bound, self.class.send(:arounds))
108
- _run_afters(op_bound)
109
- r
110
- end
111
-
112
- protected
113
-
114
- # Returns the world to use to bind an operation.
115
- #
116
- # The default implementation returns an empty hash. This is
117
- # intended to be overriden by classes including this module.
118
- def operation_world(op)
119
- {}
120
- end
121
-
122
- private
123
-
124
- def _run_befores(op_bound)
125
- op_bound.before_call if op_bound.respond_to?(:before_call, true)
126
- end
127
-
128
- def _run_with_arounds(operation, arounds = [])
129
- if arounds.empty?
130
- operation.call
131
- else
132
- arounder, iexec = arounds.first
133
- after_first = ->() {
134
- _run_with_arounds(operation, arounds[1..-1])
135
- }
136
- if iexec
137
- self.instance_exec(operation, after_first, &arounder)
138
- else
139
- arounder.call(self, operation, &after_first)
140
- end
141
- end
142
- end
143
-
144
- def _run_afters(op_bound)
145
- op_bound.after_call if op_bound.respond_to?(:after_call, true)
146
- end
147
-
148
- end # module OperationRunner
149
- end # module Support
150
- end # module Startback
@@ -1,157 +0,0 @@
1
- module Startback
2
- module Support
3
- #
4
- # This module provides helper methods for robustness of a software design.
5
- #
6
- # It is included by main Startback abstractions, and can be included by
7
- # specific software components who needs fine-tuning of monitoring, logging
8
- # and error handling.
9
- #
10
- # All public methods here follow the following free args parameters:
11
- #
12
- # 1. First (& second) argument(s) form the log message.
13
- #
14
- # A full log message is a Hash having :op (required), :op_took (optional),
15
- # and :op_data (optional) keys.
16
- #
17
- # If a String (or two) are used instead, a log message will be built taking
18
- # the former as the executer (a class or instance) and the second as a method.
19
- # `{ op: "executer#method" }`
20
- #
21
- # 2. The second (or third) argument should be a Logger instance, a Context,
22
- # or an instance knowing its context. The best logger is extracted from it
23
- # and used for actual logging.
24
- #
25
- # Examples:
26
- #
27
- # log(:info, op: "hello", op_data: {foo: 12}) => logged as such on STDOUT
28
- # log(:info, "A simple message") => { op: "A simple message" } on STDOUT
29
- # log(:info, Startback, "hello") => { op: "Startback#hello" } on STDOUT
30
- # log(:info, Event.new, "hello") => { op: "Event#hello" } on STDOUT
31
- # log(:info, Event.new, "hello", "hello world") => { op: "Event#hello", op_data: { message: "hello world" } } on STDOUT
32
- # log(:info, self, context) => { op: "..." } on context's logger or STDOUT
33
- # log(:info, self, event) => { op: "..." } on event context's logger or STDOUT
34
- # ...
35
- #
36
- module Robustness
37
-
38
- # Included to avoid poluting the space of the including
39
- # classes.
40
- module Tools
41
-
42
- def default_logger
43
- @@default_logger ||= begin
44
- l = ::Logger.new(STDOUT)
45
- l.formatter = LogFormatter.new
46
- l.warn(op: "#{self}", op_data: { msg: "Using default logger to STDOUT" })
47
- @@default_logger = l
48
- end
49
- @@default_logger
50
- end
51
- module_function :default_logger
52
-
53
- def logger_for(arg)
54
- return arg if arg.is_a?(::Logger)
55
- return arg.logger if arg.is_a?(Context) && arg.logger
56
- return logger_for(arg.context) if arg.respond_to?(:context, false)
57
- default_logger
58
- end
59
- module_function :logger_for
60
-
61
- def parse_args(log_msg, method = nil, context = nil, extra = nil)
62
- method, context, extra = nil, method, context unless method.is_a?(String)
63
- context, extra = nil, context if context.is_a?(Hash) || context.is_a?(String) && extra.nil?
64
- extra = { op_data: { message: extra } } if extra.is_a?(String)
65
- logger = logger_for(context) || logger_for(log_msg)
66
- log_msg = if log_msg.is_a?(Hash)
67
- log_msg.dup
68
- elsif log_msg.is_a?(String)
69
- log_msg = { op: "#{log_msg}#{method.nil? ? '' : '#'+method.to_s}" }
70
- elsif log_msg.is_a?(Exception)
71
- log_msg = { error: log_msg }
72
- else
73
- log_msg = log_msg.class unless log_msg.is_a?(Module)
74
- log_msg = { op: "#{log_msg.name}##{method}" }
75
- end
76
- log_msg.merge!(extra) if extra
77
- [ log_msg, logger ]
78
- end
79
- module_function :parse_args
80
-
81
- [:debug, :info, :warn, :error, :fatal].each do |meth|
82
- define_method(meth) do |args, extra = nil, &bl|
83
- act_args = (args + [extra]).compact
84
- log_msg, logger = parse_args(*act_args)
85
- logger.send(meth, log_msg)
86
- end
87
- module_function(meth)
88
- end
89
-
90
- end # module Tools
91
-
92
- # Logs a specific message with a given severity.
93
- #
94
- # Severity can be :debug, :info, :warn, :error or :fatal.
95
- # The args must follow module's conventions, see above.
96
- def log(severity, *args)
97
- Tools.send(severity, args)
98
- end
99
-
100
- # Calls the block and monitors then log its execution time.
101
- #
102
- # The args must follow module's conventions, see above.
103
- def monitor(*args, &bl)
104
- result = nil
105
- took = Benchmark.realtime {
106
- result = bl.call
107
- }
108
- Tools.info(args, op_took: took)
109
- result
110
- end
111
-
112
- # Executes the block without letting errors propagate.
113
- # Errors are logged, though. Nothing is logged if everything
114
- # goes fine.
115
- #
116
- # The args must follow module's conventions, see above.
117
- def stop_errors(*args, &bl)
118
- result = nil
119
- took = Benchmark.realtime {
120
- result = bl.call
121
- }
122
- result
123
- rescue => ex
124
- Tools.fatal(args, op_took: took, error: ex)
125
- nil
126
- end
127
-
128
- # Tries executing the block up to `n` times, until an attempt
129
- # succeeds (then returning the result). Logs the first and last
130
- # fatal error, if any.
131
- #
132
- # The args must follow module's conventions, see above.
133
- def try_max_times(n, *args, &bl)
134
- retried = 0
135
- took = 0
136
- begin
137
- result = nil
138
- took += Benchmark.realtime {
139
- result = bl.call
140
- }
141
- result
142
- rescue => ex
143
- Tools.error(args + [{op_took: took, error: ex}]) if retried == 0
144
- retried += 1
145
- if retried < n
146
- sleep(retried)
147
- retry
148
- else
149
- Tools.fatal(args + [{op_took: took, error: ex}])
150
- raise
151
- end
152
- end
153
- end
154
-
155
- end # module Robustness
156
- end # module Support
157
- end # module Startback
@@ -1,25 +0,0 @@
1
- module Startback
2
- module Support
3
- class TransactionManager
4
-
5
- def initialize(db, method = :transaction)
6
- @db = db
7
- @method = method
8
- end
9
-
10
- def call(runner, op, &then_block)
11
- raise ArgumentError, "A block is required" unless then_block
12
-
13
- before = (op.class.transaction_policy == :before_call)
14
- if before
15
- @db.send(@method) do
16
- then_block.call
17
- end
18
- else
19
- then_block.call
20
- end
21
- end
22
-
23
- end # class TransactionManager
24
- end # module Support
25
- end # module Startback