pulse-meter 0.4.9 → 0.4.11

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 (192) hide show
  1. data/Rakefile +1 -48
  2. data/lib/pulse-meter.rb +1 -68
  3. data/lib/pulse-meter/visualizer.rb +1 -40
  4. data/pulse-meter.gemspec +4 -26
  5. metadata +10 -558
  6. data/Procfile +0 -3
  7. data/bin/pulse +0 -6
  8. data/examples/basic.ru +0 -145
  9. data/examples/basic_sensor_data.rb +0 -96
  10. data/examples/udp_benchmark.rb +0 -29
  11. data/lib/cmd.rb +0 -171
  12. data/lib/pulse-meter/command_aggregator/async.rb +0 -83
  13. data/lib/pulse-meter/command_aggregator/sync.rb +0 -18
  14. data/lib/pulse-meter/command_aggregator/udp.rb +0 -48
  15. data/lib/pulse-meter/extensions/enumerable.rb +0 -24
  16. data/lib/pulse-meter/mixins/cmd.rb +0 -46
  17. data/lib/pulse-meter/mixins/dumper.rb +0 -87
  18. data/lib/pulse-meter/mixins/utils.rb +0 -155
  19. data/lib/pulse-meter/observer.rb +0 -120
  20. data/lib/pulse-meter/observer/extended.rb +0 -34
  21. data/lib/pulse-meter/sensor.rb +0 -61
  22. data/lib/pulse-meter/sensor/base.rb +0 -88
  23. data/lib/pulse-meter/sensor/configuration.rb +0 -106
  24. data/lib/pulse-meter/sensor/counter.rb +0 -39
  25. data/lib/pulse-meter/sensor/hashed_counter.rb +0 -36
  26. data/lib/pulse-meter/sensor/hashed_indicator.rb +0 -24
  27. data/lib/pulse-meter/sensor/indicator.rb +0 -35
  28. data/lib/pulse-meter/sensor/multi.rb +0 -97
  29. data/lib/pulse-meter/sensor/timeline.rb +0 -236
  30. data/lib/pulse-meter/sensor/timeline_reduce.rb +0 -68
  31. data/lib/pulse-meter/sensor/timelined/average.rb +0 -32
  32. data/lib/pulse-meter/sensor/timelined/counter.rb +0 -23
  33. data/lib/pulse-meter/sensor/timelined/hashed_counter.rb +0 -31
  34. data/lib/pulse-meter/sensor/timelined/hashed_indicator.rb +0 -30
  35. data/lib/pulse-meter/sensor/timelined/indicator.rb +0 -23
  36. data/lib/pulse-meter/sensor/timelined/max.rb +0 -19
  37. data/lib/pulse-meter/sensor/timelined/median.rb +0 -14
  38. data/lib/pulse-meter/sensor/timelined/min.rb +0 -19
  39. data/lib/pulse-meter/sensor/timelined/multi_percentile.rb +0 -34
  40. data/lib/pulse-meter/sensor/timelined/percentile.rb +0 -22
  41. data/lib/pulse-meter/sensor/timelined/uniq_counter.rb +0 -22
  42. data/lib/pulse-meter/sensor/timelined/zset_based.rb +0 -38
  43. data/lib/pulse-meter/sensor/uniq_counter.rb +0 -24
  44. data/lib/pulse-meter/server.rb +0 -0
  45. data/lib/pulse-meter/server/command_line_options.rb +0 -0
  46. data/lib/pulse-meter/server/config_options.rb +0 -0
  47. data/lib/pulse-meter/server/sensors.rb +0 -0
  48. data/lib/pulse-meter/udp_server.rb +0 -45
  49. data/lib/pulse-meter/version.rb +0 -3
  50. data/lib/pulse-meter/visualize/app.rb +0 -78
  51. data/lib/pulse-meter/visualize/base.rb +0 -15
  52. data/lib/pulse-meter/visualize/coffee/application.coffee +0 -40
  53. data/lib/pulse-meter/visualize/coffee/collections/page_info_list.coffee +0 -17
  54. data/lib/pulse-meter/visualize/coffee/collections/sensor_info_list.coffee +0 -4
  55. data/lib/pulse-meter/visualize/coffee/collections/widget_list.coffee +0 -14
  56. data/lib/pulse-meter/visualize/coffee/extensions.coffee +0 -26
  57. data/lib/pulse-meter/visualize/coffee/models/dinamic_widget.coffee +0 -34
  58. data/lib/pulse-meter/visualize/coffee/models/page_info.coffee +0 -2
  59. data/lib/pulse-meter/visualize/coffee/models/sensor_info.coffee +0 -2
  60. data/lib/pulse-meter/visualize/coffee/models/widget.coffee +0 -54
  61. data/lib/pulse-meter/visualize/coffee/presenters/area.coffee +0 -2
  62. data/lib/pulse-meter/visualize/coffee/presenters/gauge.coffee +0 -11
  63. data/lib/pulse-meter/visualize/coffee/presenters/line.coffee +0 -2
  64. data/lib/pulse-meter/visualize/coffee/presenters/pie.coffee +0 -20
  65. data/lib/pulse-meter/visualize/coffee/presenters/series.coffee +0 -44
  66. data/lib/pulse-meter/visualize/coffee/presenters/table.coffee +0 -10
  67. data/lib/pulse-meter/visualize/coffee/presenters/timeline.coffee +0 -13
  68. data/lib/pulse-meter/visualize/coffee/presenters/widget.coffee +0 -65
  69. data/lib/pulse-meter/visualize/coffee/router.coffee +0 -21
  70. data/lib/pulse-meter/visualize/coffee/views/dynamic_chart.coffee +0 -91
  71. data/lib/pulse-meter/visualize/coffee/views/dynamic_widget.coffee +0 -58
  72. data/lib/pulse-meter/visualize/coffee/views/page_title.coffee +0 -17
  73. data/lib/pulse-meter/visualize/coffee/views/page_titles.coffee +0 -15
  74. data/lib/pulse-meter/visualize/coffee/views/sensor_info_list.coffee +0 -19
  75. data/lib/pulse-meter/visualize/coffee/views/widget.coffee +0 -99
  76. data/lib/pulse-meter/visualize/coffee/views/widget_chart.coffee +0 -13
  77. data/lib/pulse-meter/visualize/coffee/views/widget_list.coffee +0 -15
  78. data/lib/pulse-meter/visualize/dsl/base.rb +0 -131
  79. data/lib/pulse-meter/visualize/dsl/errors.rb +0 -40
  80. data/lib/pulse-meter/visualize/dsl/layout.rb +0 -27
  81. data/lib/pulse-meter/visualize/dsl/page.rb +0 -33
  82. data/lib/pulse-meter/visualize/dsl/sensor.rb +0 -20
  83. data/lib/pulse-meter/visualize/dsl/widget.rb +0 -37
  84. data/lib/pulse-meter/visualize/dsl/widgets/area.rb +0 -20
  85. data/lib/pulse-meter/visualize/dsl/widgets/gauge.rb +0 -12
  86. data/lib/pulse-meter/visualize/dsl/widgets/line.rb +0 -21
  87. data/lib/pulse-meter/visualize/dsl/widgets/pie.rb +0 -16
  88. data/lib/pulse-meter/visualize/dsl/widgets/table.rb +0 -19
  89. data/lib/pulse-meter/visualize/layout.rb +0 -79
  90. data/lib/pulse-meter/visualize/page.rb +0 -25
  91. data/lib/pulse-meter/visualize/public/css/application.css +0 -56
  92. data/lib/pulse-meter/visualize/public/css/bootstrap.css +0 -4883
  93. data/lib/pulse-meter/visualize/public/css/bootstrap.min.css +0 -729
  94. data/lib/pulse-meter/visualize/public/css/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  95. data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  96. data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  97. data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  98. data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  99. data/lib/pulse-meter/visualize/public/css/images/ui-bg_glass_75_ffffff_1x400.png +0 -0
  100. data/lib/pulse-meter/visualize/public/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  101. data/lib/pulse-meter/visualize/public/css/images/ui-bg_inset-soft_95_fef1ec_1x100.png +0 -0
  102. data/lib/pulse-meter/visualize/public/css/images/ui-icons_222222_256x240.png +0 -0
  103. data/lib/pulse-meter/visualize/public/css/images/ui-icons_2e83ff_256x240.png +0 -0
  104. data/lib/pulse-meter/visualize/public/css/images/ui-icons_454545_256x240.png +0 -0
  105. data/lib/pulse-meter/visualize/public/css/images/ui-icons_888888_256x240.png +0 -0
  106. data/lib/pulse-meter/visualize/public/css/images/ui-icons_cd0a0a_256x240.png +0 -0
  107. data/lib/pulse-meter/visualize/public/css/images/ui-icons_f6cf3b_256x240.png +0 -0
  108. data/lib/pulse-meter/visualize/public/css/jquery-ui-1.8.16.bootstrap.css +0 -1320
  109. data/lib/pulse-meter/visualize/public/favicon.ico +0 -208
  110. data/lib/pulse-meter/visualize/public/img/glyphicons-halflings-white.png +0 -0
  111. data/lib/pulse-meter/visualize/public/img/glyphicons-halflings.png +0 -0
  112. data/lib/pulse-meter/visualize/public/js/application.js +0 -973
  113. data/lib/pulse-meter/visualize/public/js/backbone-min.js +0 -38
  114. data/lib/pulse-meter/visualize/public/js/bootstrap.js +0 -1835
  115. data/lib/pulse-meter/visualize/public/js/jquery-1.7.2.min.js +0 -4
  116. data/lib/pulse-meter/visualize/public/js/jquery-ui-1.8.16.bootstrap.min.js +0 -791
  117. data/lib/pulse-meter/visualize/public/js/jquery-ui-1.8.23.custom.min.js +0 -21
  118. data/lib/pulse-meter/visualize/public/js/jquery-ui-timepicker-addon.js +0 -1687
  119. data/lib/pulse-meter/visualize/public/js/json2.js +0 -487
  120. data/lib/pulse-meter/visualize/public/js/underscore-min.js +0 -32
  121. data/lib/pulse-meter/visualize/sensor.rb +0 -63
  122. data/lib/pulse-meter/visualize/series_extractor.rb +0 -107
  123. data/lib/pulse-meter/visualize/views/main.haml +0 -30
  124. data/lib/pulse-meter/visualize/views/sensors.haml +0 -76
  125. data/lib/pulse-meter/visualize/views/widgets/area.haml +0 -53
  126. data/lib/pulse-meter/visualize/views/widgets/extend_options.haml +0 -11
  127. data/lib/pulse-meter/visualize/views/widgets/gauge.haml +0 -13
  128. data/lib/pulse-meter/visualize/views/widgets/line.haml +0 -54
  129. data/lib/pulse-meter/visualize/views/widgets/pie.haml +0 -13
  130. data/lib/pulse-meter/visualize/views/widgets/table.haml +0 -45
  131. data/lib/pulse-meter/visualize/widget.rb +0 -38
  132. data/lib/pulse-meter/visualize/widgets/gauge.rb +0 -47
  133. data/lib/pulse-meter/visualize/widgets/pie.rb +0 -36
  134. data/lib/pulse-meter/visualize/widgets/timeline.rb +0 -114
  135. data/spec/pulse_meter/command_aggregator/async_spec.rb +0 -53
  136. data/spec/pulse_meter/command_aggregator/sync_spec.rb +0 -25
  137. data/spec/pulse_meter/command_aggregator/udp_spec.rb +0 -45
  138. data/spec/pulse_meter/extensions/enumerable_spec.rb +0 -58
  139. data/spec/pulse_meter/mixins/cmd_spec.rb +0 -117
  140. data/spec/pulse_meter/mixins/dumper_spec.rb +0 -162
  141. data/spec/pulse_meter/mixins/utils_spec.rb +0 -212
  142. data/spec/pulse_meter/observer/extended_spec.rb +0 -92
  143. data/spec/pulse_meter/observer_spec.rb +0 -207
  144. data/spec/pulse_meter/sensor/base_spec.rb +0 -106
  145. data/spec/pulse_meter/sensor/configuration_spec.rb +0 -103
  146. data/spec/pulse_meter/sensor/counter_spec.rb +0 -54
  147. data/spec/pulse_meter/sensor/hashed_counter_spec.rb +0 -43
  148. data/spec/pulse_meter/sensor/hashed_indicator_spec.rb +0 -39
  149. data/spec/pulse_meter/sensor/indicator_spec.rb +0 -43
  150. data/spec/pulse_meter/sensor/multi_spec.rb +0 -137
  151. data/spec/pulse_meter/sensor/timeline_spec.rb +0 -88
  152. data/spec/pulse_meter/sensor/timelined/average_spec.rb +0 -6
  153. data/spec/pulse_meter/sensor/timelined/counter_spec.rb +0 -6
  154. data/spec/pulse_meter/sensor/timelined/hashed_counter_spec.rb +0 -8
  155. data/spec/pulse_meter/sensor/timelined/hashed_indicator_spec.rb +0 -8
  156. data/spec/pulse_meter/sensor/timelined/indicator_spec.rb +0 -6
  157. data/spec/pulse_meter/sensor/timelined/max_spec.rb +0 -7
  158. data/spec/pulse_meter/sensor/timelined/median_spec.rb +0 -7
  159. data/spec/pulse_meter/sensor/timelined/min_spec.rb +0 -7
  160. data/spec/pulse_meter/sensor/timelined/multi_percentile_spec.rb +0 -21
  161. data/spec/pulse_meter/sensor/timelined/percentile_spec.rb +0 -17
  162. data/spec/pulse_meter/sensor/timelined/uniq_counter_spec.rb +0 -9
  163. data/spec/pulse_meter/sensor/uniq_counter_spec.rb +0 -28
  164. data/spec/pulse_meter/udp_server_spec.rb +0 -36
  165. data/spec/pulse_meter/visualize/app_spec.rb +0 -27
  166. data/spec/pulse_meter/visualize/dsl/layout_spec.rb +0 -64
  167. data/spec/pulse_meter/visualize/dsl/page_spec.rb +0 -62
  168. data/spec/pulse_meter/visualize/dsl/sensor_spec.rb +0 -30
  169. data/spec/pulse_meter/visualize/dsl/widget_spec.rb +0 -6
  170. data/spec/pulse_meter/visualize/dsl/widgets/area_spec.rb +0 -44
  171. data/spec/pulse_meter/visualize/dsl/widgets/gauge_spec.rb +0 -22
  172. data/spec/pulse_meter/visualize/dsl/widgets/line_spec.rb +0 -44
  173. data/spec/pulse_meter/visualize/dsl/widgets/pie_spec.rb +0 -35
  174. data/spec/pulse_meter/visualize/dsl/widgets/table_spec.rb +0 -36
  175. data/spec/pulse_meter/visualize/layout_spec.rb +0 -54
  176. data/spec/pulse_meter/visualize/page_spec.rb +0 -153
  177. data/spec/pulse_meter/visualize/sensor_spec.rb +0 -120
  178. data/spec/pulse_meter/visualize/series_extractor_spec.rb +0 -80
  179. data/spec/pulse_meter/visualize/widgets/area_spec.rb +0 -6
  180. data/spec/pulse_meter/visualize/widgets/gauge_spec.rb +0 -63
  181. data/spec/pulse_meter/visualize/widgets/line_spec.rb +0 -6
  182. data/spec/pulse_meter/visualize/widgets/pie_spec.rb +0 -73
  183. data/spec/pulse_meter/visualize/widgets/table_spec.rb +0 -6
  184. data/spec/pulse_meter/visualizer_spec.rb +0 -42
  185. data/spec/pulse_meter_spec.rb +0 -73
  186. data/spec/shared_examples/dsl_widget.rb +0 -106
  187. data/spec/shared_examples/timeline_sensor.rb +0 -439
  188. data/spec/shared_examples/timelined_subclass.rb +0 -23
  189. data/spec/shared_examples/widget.rb +0 -97
  190. data/spec/spec_helper.rb +0 -40
  191. data/spec/support/matchers.rb +0 -34
  192. data/spec/support/observered.rb +0 -40
@@ -1,83 +0,0 @@
1
- require 'singleton'
2
- require 'thread'
3
-
4
- module PulseMeter
5
- module CommandAggregator
6
- class Async
7
- include Singleton
8
-
9
- MAX_QUEUE_LENGTH = 10_000
10
-
11
- attr_reader :max_queue_length
12
-
13
- def initialize
14
- @max_queue_length = MAX_QUEUE_LENGTH
15
- @queue = Queue.new
16
- @buffer = []
17
- @in_multi = false
18
- @consumer_thread = run_consumer
19
- at_exit{ wait_for_pending_events }
20
- end
21
-
22
- def multi
23
- @in_multi = true
24
- yield
25
- ensure
26
- @in_multi = false
27
- send_buffer_to_queue
28
- end
29
-
30
- def method_missing(*args)
31
- @buffer << args
32
- send_buffer_to_queue unless @in_multi
33
- end
34
-
35
- def wait_for_pending_events(max_seconds = 1)
36
- left_to_wait = max_seconds.to_f
37
- sleep_step = 0.01
38
- while has_pending_events? && left_to_wait > 0
39
- left_to_wait -= sleep_step
40
- sleep(sleep_step)
41
- end
42
- end
43
-
44
- private
45
-
46
- def has_pending_events?
47
- !@queue.empty?
48
- end
49
-
50
- def send_buffer_to_queue
51
- if @queue.size < @max_queue_length
52
- @queue << @buffer
53
- end
54
- @buffer = []
55
- end
56
-
57
- def redis
58
- PulseMeter.redis
59
- end
60
-
61
- def consume_commands
62
- # redis and @queue are threadsafe
63
- while commands = @queue.pop
64
- begin
65
- redis.multi do
66
- commands.each do |command|
67
- redis.send(*command)
68
- end
69
- end
70
- rescue StandardError => e
71
- PulseMeter.error "error in consumer thread: #{e}, #{e.backtrace.join("\n")}"
72
- end
73
- end
74
- end
75
-
76
- def run_consumer
77
- Thread.new do
78
- consume_commands
79
- end
80
- end
81
- end
82
- end
83
- end
@@ -1,18 +0,0 @@
1
- require 'singleton'
2
-
3
- module PulseMeter
4
- module CommandAggregator
5
- class Sync
6
- include Singleton
7
-
8
- def redis
9
- PulseMeter.redis
10
- end
11
-
12
- def method_missing(*args, &block)
13
- redis.send(*args, &block)
14
- end
15
- end
16
- end
17
- end
18
-
@@ -1,48 +0,0 @@
1
- require 'socket'
2
- require 'fcntl'
3
-
4
- module PulseMeter
5
- module CommandAggregator
6
- class UDP
7
-
8
- def initialize(host, port = nil)
9
- @servers = if host.is_a?(Array)
10
- host
11
- else
12
- [[host, port]]
13
- end
14
- raise ArgumentError, "No servers specified" if @servers.empty?
15
- @buffer = []
16
- @in_multi = false
17
- @sock = UDPSocket.new
18
- @sock.fcntl(Fcntl::F_SETFL, @sock.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)
19
- end
20
-
21
- def multi
22
- @in_multi = true
23
- yield
24
- ensure
25
- @in_multi = false
26
- send_buffer
27
- end
28
-
29
- def method_missing(*args)
30
- @buffer << args
31
- send_buffer unless @in_multi
32
- end
33
-
34
- private
35
-
36
- def send_buffer
37
- data = @buffer.to_json
38
- @sock.send(data, 0, *@servers.sample)
39
- rescue StandardError => e
40
- PulseMeter.error "error sending data: #{e}, #{e.backtrace.join("\n")}"
41
- ensure
42
- @buffer = []
43
- end
44
-
45
- end
46
- end
47
- end
48
-
@@ -1,24 +0,0 @@
1
- module Enumerable
2
- require 'csv'
3
- require 'terminal-table'
4
-
5
- def convert_time
6
- map {|el| el.is_a?(Time) ? el.to_i : el}
7
- end
8
-
9
- def to_table(format = nil)
10
- if "csv" == format.to_s
11
- CSV.generate(:col_sep => ';') do |csv|
12
- self.each {|row| csv << row.convert_time}
13
- end
14
- else
15
- self.each_with_object(Terminal::Table.new) do |row, table|
16
- table << if row.respond_to?(:map)
17
- row.map(&:to_s)
18
- else
19
- row
20
- end
21
- end
22
- end
23
- end
24
- end
@@ -1,46 +0,0 @@
1
- require 'pulse-meter/extensions/enumerable'
2
-
3
- module PulseMeter
4
- module Mixins
5
- # Mixin with command-line utilities
6
- module Cmd
7
- def with_redis
8
- PulseMeter.redis = create_redis
9
- yield
10
- end
11
-
12
- def with_safe_restore_of(name, &block)
13
- with_redis do
14
- sensor = PulseMeter::Sensor::Base.restore(name)
15
- block.call(sensor)
16
- end
17
- rescue PulseMeter::RestoreError
18
- fail! "Sensor #{name} is unknown or cannot be restored"
19
- end
20
-
21
- def all_sensors
22
- PulseMeter::Sensor::Timeline.list_objects
23
- end
24
-
25
- def all_sensors_table(format = nil)
26
- data = [
27
- ["Name", "Class", "ttl", "raw data ttl", "interval", "reduce delay"],
28
- ]
29
- data << :separator unless 'csv' == format.to_s
30
- all_sensors.each do |s|
31
- if s.kind_of? PulseMeter::Sensor::Timeline
32
- data << [s.name, s.class, s.ttl, s.raw_data_ttl, s.interval, s.reduce_delay]
33
- else
34
- data << [s.name, s.class] + [''] * 4
35
- end
36
- end
37
- data.to_table(format)
38
- end
39
-
40
- def fail!(description = nil)
41
- puts description if description
42
- exit 1
43
- end
44
- end
45
- end
46
- end
@@ -1,87 +0,0 @@
1
- require 'yaml'
2
-
3
- module PulseMeter
4
- module Mixins
5
- # Mixin with dumping utilities
6
- module Dumper
7
- # Prefix for Redis keys with dumped sensors' metadata
8
- DUMP_REDIS_KEY = "pulse_meter:dump"
9
-
10
- module InstanceMethods
11
- # Serializes object and saves it to Redis
12
- # @param safe [Boolean] forbids dump if sensor has already been dumped
13
- # @raise [DumpConflictError] if object class conflicts with stored object class
14
- # @raise [DumpError] if dumping fails for any reason
15
- def dump!(safe = true)
16
- ensure_storability!
17
- serialized_obj = to_yaml
18
- if safe
19
- unless redis.hsetnx(DUMP_REDIS_KEY, name, serialized_obj)
20
- stored = self.class.restore(name)
21
- unless stored.class == self.class
22
- raise DumpConflictError, "Attempt to create sensor #{name} of class #{self.class} but it already has class #{stored.class}"
23
- end
24
- end
25
- else
26
- redis.hset(DUMP_REDIS_KEY, name, serialized_obj)
27
- end
28
- rescue DumpError, RestoreError => exc
29
- raise exc
30
- rescue StandardError => exc
31
- raise DumpError, "object cannot be dumped: #{exc}"
32
- end
33
-
34
- # Ensures that object is dumpable
35
- # @raise [DumpError] if object cannot be dumped
36
- def ensure_storability!
37
- raise DumpError, "#name attribute must be readable" unless self.respond_to?(:name)
38
- raise DumpError, "#redis attribute must be available" unless self.respond_to?(:redis) && self.redis
39
- end
40
-
41
- # Cleans up object dump in Redis
42
- def cleanup_dump
43
- redis.hdel(DUMP_REDIS_KEY, self.name)
44
- end
45
- end
46
-
47
- module ClassMethods
48
- # Restores object from Redis
49
- # @param name [String] object name
50
- # @return [Object]
51
- # @raise [RestoreError] if object cannot be restored for any reason
52
- def restore(name)
53
- serialized_obj = PulseMeter.redis.hget(DUMP_REDIS_KEY, name)
54
- YAML::load(serialized_obj)
55
- rescue
56
- raise RestoreError, "cannot restore #{name}"
57
- end
58
-
59
- # Lists all dumped objects' names
60
- # @return [Array<String>]
61
- # @raise [RestoreError] if list cannot be retrieved for any reason
62
- def list_names
63
- PulseMeter.redis.hkeys(DUMP_REDIS_KEY)
64
- rescue
65
- raise RestoreError, "cannot get data from redis"
66
- end
67
-
68
- # Safely restores all dumped objects
69
- # @return [Array<Object>]
70
- def list_objects
71
- list_names.each_with_object([]) do |name, objects|
72
- begin
73
- objects << restore(name)
74
- rescue
75
- end
76
- end
77
- end
78
- end
79
-
80
- def self.included(base)
81
- base.send :include, InstanceMethods
82
- base.send :extend, ClassMethods
83
- end
84
-
85
- end
86
- end
87
- end
@@ -1,155 +0,0 @@
1
- require 'securerandom'
2
-
3
- module PulseMeter
4
- module Mixins
5
- # Mixin with various useful functions
6
- module Utils
7
- # Tries to find a class with the name specified in the argument string
8
- # @param const_name [String] class name
9
- # @return [Class] if given class definde
10
- # @return [NilClass] if given class is not defined
11
- def constantize(const_name)
12
- return unless const_name.respond_to?(:to_s)
13
- const_name.to_s.split('::').reduce(Module, :const_get)
14
- rescue NameError
15
- nil
16
- end
17
-
18
- # Ensures that hash value specified by key is Array
19
- # @param options [Hash] hash to be looked at
20
- # @param key [Object] hash key
21
- # @param default [Object] default value to be returned
22
- # @raise [ArgumentError] unless value is Array
23
- # @return [Array]
24
- def assert_array!(options, key, default = nil)
25
- value = options[key] || default
26
- raise ArgumentError, "#{key} should be defined" unless value
27
- raise ArgumentError, "#{key} should be array" unless value.is_a?(Array)
28
- value
29
- end
30
-
31
- # Ensures that hash value specified by key can be converted to positive integer.
32
- # In case it can makes in-place conversion and returns the value.
33
- # @param options [Hash] hash to be looked at
34
- # @param key [Object] hash key
35
- # @param default [Object] default value to be returned
36
- # @raise [ArgumentError] unless value is positive integer
37
- # @return [Fixnum]
38
- def assert_positive_integer!(options, key, default = nil)
39
- value = options[key] || default
40
- raise ArgumentError, "#{key} should be defined" unless value
41
- raise ArgumentError, "#{key} should be integer" unless value.respond_to?(:to_i)
42
- raise ArgumentError, "#{key} should be positive" unless value.to_i > 0
43
- options[key] = value.to_i
44
- end
45
-
46
- # Ensures that hash value specified by key is can be converted to float
47
- # and it is within given range.
48
- # In case it can makes in-place conversion and returns the value.
49
- # @param options [Hash] hash to be looked at
50
- # @param key [Object] hash key
51
- # @param from [Float] lower bound
52
- # @param to [Float] upper bound
53
- # @raise [ArgumentError] unless value is float within given range
54
- # @return [Float]
55
- def assert_ranged_float!(options, key, from, to)
56
- f = options[key]
57
- raise ArgumentError, "#{key} should be defined" unless f
58
- raise ArgumentError, "#{key} should be float" unless f.respond_to?(:to_f)
59
- f = f.to_f
60
- raise ArgumentError, "#{key} should be between #{from} and #{to}" unless f >= from && f <= to
61
- options[key] = f
62
- end
63
-
64
- # Generates uniq random string
65
- # @return [String]
66
- def uniqid
67
- SecureRandom.hex(32)
68
- end
69
-
70
- # Capitalizes the first letter of each word in string
71
- # @param str [String]
72
- # @return [String]
73
- # @raise [ArgumentError] unless passed value responds to to_s
74
- def titleize(str)
75
- raise ArgumentError unless str.respond_to?(:to_s)
76
- str.to_s.split(/[\s_]+/).map(&:capitalize).join(' ')
77
- end
78
-
79
- # Converts string from snake_case to CamelCase
80
- # @param str [String] string to be camelized
81
- # @param first_letter_upper [TrueClass, FalseClass] says if the first letter must be uppercased
82
- # @return [String]
83
- # @raise [ArgumentError] unless passed value responds to to_s
84
- def camelize(str, first_letter_upper = false)
85
- raise ArgumentError unless str.respond_to?(:to_s)
86
- terms = str.to_s.split(/_/)
87
- first = terms.shift
88
- (first_letter_upper ? first.capitalize : first.downcase) + terms.map(&:capitalize).join
89
- end
90
-
91
- # Converts string from CamelCase to snake_case
92
- # @param str [String] string to be underscore
93
- # @return [String]
94
- # @raise [ArgumentError] unless passed value responds to to_s
95
- def underscore(str)
96
- raise ArgumentError unless str.respond_to?(:to_s)
97
- str.to_s.gsub(/::/, '/').
98
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
99
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
100
- tr("-", "_").
101
- downcase
102
- end
103
-
104
- # Converts string of the form YYYYmmddHHMMSS (considered as UTC) to Time
105
- # @param str [String] string to be converted
106
- # @return [Time]
107
- # @raise [ArgumentError] unless passed value responds to to_s
108
- def parse_time(str)
109
- raise ArgumentError unless str.respond_to?(:to_s)
110
- m = str.to_s.match(/\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\z/)
111
- if m
112
- Time.gm(*m.captures.map(&:to_i))
113
- else
114
- raise ArgumentError, "`#{str}' is not a YYYYmmddHHMMSS time"
115
- end
116
- end
117
-
118
- # Symbolizes hash keys
119
- def symbolize_keys(h)
120
- h.each_with_object({}) do |(k, v), acc|
121
- new_k = if k.respond_to?(:to_sym)
122
- k.to_sym
123
- else
124
- k
125
- end
126
- acc[new_k] = v
127
- end
128
- end
129
-
130
- # Deeply capitalizes Array values or Hash keys
131
- def camelize_keys(item)
132
- case item
133
- when Array
134
- item.map{|i| camelize_keys(i)}
135
- when Hash
136
- item.each_with_object({}) { |(k, v), h| h[camelize(k)] = camelize_keys(v)}
137
- else
138
- item
139
- end
140
- end
141
-
142
- # Yields block for each subset of given array
143
- # @param array [Array] given array
144
- def each_subset(array)
145
- subsets_of(array).each {|subset| yield(subset)}
146
- end
147
-
148
- # Returs all array's subsets
149
- # @param array [Array]
150
- def subsets_of(array)
151
- 0.upto(array.length).flat_map { |n| array.combination(n).to_a }
152
- end
153
- end
154
- end
155
- end