startback-websocket 0.14.0 → 0.14.1

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 (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