krakow 0.2.2 → 0.3.0

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 (44) hide show
  1. data/CHANGELOG.md +16 -0
  2. data/CONTRIBUTING.md +25 -0
  3. data/LICENSE +13 -0
  4. data/README.md +62 -9
  5. data/krakow.gemspec +3 -1
  6. data/lib/krakow/command/cls.rb +3 -4
  7. data/lib/krakow/command/fin.rb +13 -4
  8. data/lib/krakow/command/identify.rb +22 -9
  9. data/lib/krakow/command/mpub.rb +14 -4
  10. data/lib/krakow/command/nop.rb +3 -4
  11. data/lib/krakow/command/pub.rb +15 -5
  12. data/lib/krakow/command/rdy.rb +13 -4
  13. data/lib/krakow/command/req.rb +14 -4
  14. data/lib/krakow/command/sub.rb +14 -4
  15. data/lib/krakow/command/touch.rb +13 -4
  16. data/lib/krakow/command.rb +25 -3
  17. data/lib/krakow/connection.rb +286 -60
  18. data/lib/krakow/connection_features/deflate.rb +26 -1
  19. data/lib/krakow/connection_features/snappy_frames.rb +34 -3
  20. data/lib/krakow/connection_features/ssl.rb +43 -1
  21. data/lib/krakow/connection_features.rb +1 -0
  22. data/lib/krakow/consumer.rb +162 -49
  23. data/lib/krakow/discovery.rb +17 -6
  24. data/lib/krakow/distribution/default.rb +61 -33
  25. data/lib/krakow/distribution.rb +107 -57
  26. data/lib/krakow/exceptions.rb +14 -0
  27. data/lib/krakow/frame_type/error.rb +13 -7
  28. data/lib/krakow/frame_type/message.rb +47 -4
  29. data/lib/krakow/frame_type/response.rb +14 -4
  30. data/lib/krakow/frame_type.rb +20 -8
  31. data/lib/krakow/producer/http.rb +95 -6
  32. data/lib/krakow/producer.rb +60 -17
  33. data/lib/krakow/utils/lazy.rb +99 -40
  34. data/lib/krakow/utils/logging.rb +11 -0
  35. data/lib/krakow/utils.rb +3 -0
  36. data/lib/krakow/version.rb +3 -1
  37. data/lib/krakow.rb +1 -0
  38. metadata +11 -11
  39. data/Gemfile +0 -5
  40. data/Gemfile.lock +0 -34
  41. data/test/spec.rb +0 -81
  42. data/test/specs/consumer.rb +0 -49
  43. data/test/specs/http_producer.rb +0 -123
  44. data/test/specs/producer.rb +0 -20
@@ -1,4 +1,8 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
4
+ # Message distribution
5
+ # @abstract
2
6
  class Distribution
3
7
 
4
8
  autoload :Default, 'krakow/distribution/default'
@@ -7,110 +11,147 @@ module Krakow
7
11
 
8
12
  include Celluloid
9
13
  include Utils::Lazy
14
+ # @!parse include Krakow::Utils::Lazy::InstanceMethods
15
+ # @!parse extend Krakow::Utils::Lazy::ClassMethods
16
+
17
+ attr_accessor :ideal, :flight_record, :registry
18
+
19
+ # @!group Attributes
10
20
 
11
- attr_accessor :max_in_flight, :ideal, :flight_record, :registry
21
+ # @!macro [attach] attribute
22
+ # @!method $1
23
+ # @return [$2] the $1 $0
24
+ # @!method $1?
25
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
26
+ attribute :consumer, Krakow::Consumer, :required => true
27
+ attribute :watch_dog_interval, Numeric, :default => 1.0
28
+ attribute :backoff_interval, Numeric
29
+ attribute :max_in_flight, Integer, :default => 1
30
+
31
+ # @!endgroup
12
32
 
13
33
  def initialize(args={})
14
34
  super
15
- optional :watch_dog_interval, :backoff_interval
16
- arguments[:watch_dog_interval] ||= 5
17
- @max_in_flight = arguments[:max_in_flight] || 1
18
35
  @ideal = 0
19
36
  @flight_record = {}
20
37
  @registry = {}
21
38
  end
22
39
 
23
- # Reset flight distributions
40
+ # [Abstract] Reset flight distributions
24
41
  def redistribute!
25
42
  raise NotImplementedError.new 'Custom `#redistrubute!` method must be provided!'
26
43
  end
27
44
 
28
- # connection:: Connection
29
- # Determine RDY value for given connection
30
- def calculate_ready!(connection)
45
+ # [Abstract] Determine RDY value for given connection
46
+ # @param connection_identifier [String]
47
+ # @return [Integer]
48
+ def calculate_ready!(connection_identifier)
31
49
  raise NotImplementedError.new 'Custom `#calculate_ready!` method must be provided!'
32
50
  end
33
51
 
34
- # message:: FrameType::Message or message ID string
35
- # Remove message metadata from registry. Should be used after
36
- # confirmations or requeue.
52
+ # Remove message metadata from registry
53
+ #
54
+ # @param message [Krakow::FrameType::Message, String] message or ID
55
+ # @return [Krakow::Connection]
37
56
  def unregister_message(message)
38
57
  msg_id = message.respond_to?(:message_id) ? message.message_id : message.to_s
39
- connection = flight_record[msg_id]
40
- registry_info = registry_lookup(connection)
58
+ connection = connection_lookup(flight_record[msg_id])
59
+ registry_info = registry_lookup(connection.identifier)
41
60
  flight_record.delete(msg_id)
42
61
  registry_info[:in_flight] -= 1
43
- calculate_ready!(connection)
62
+ calculate_ready!(connection.identifier)
44
63
  connection
45
64
  end
46
65
 
47
- # connection:: Connection
48
66
  # Return the currently configured RDY value for given connnection
49
- def ready_for(connection)
50
- registry_lookup(connection)[:ready]
67
+ #
68
+ # @param connection_identifier [String]
69
+ # @return [Integer]
70
+ def ready_for(connection_identifier)
71
+ registry_lookup(connection_identifier)[:ready]
51
72
  end
52
73
 
53
- # connection:: Connection
74
+
54
75
  # Send RDY for given connection
76
+ #
77
+ # @param connection [Krakow::Connection]
78
+ # @return [Krakow::FrameType::Error,nil]
55
79
  def set_ready_for(connection, *_)
56
80
  connection.transmit(
57
81
  Command::Rdy.new(
58
- :count => ready_for(connection)
82
+ :count => ready_for(connection.identifier)
59
83
  )
60
84
  )
61
85
  end
62
86
 
63
87
  # Initial ready value used for new connections
88
+ #
89
+ # @return [Integer]
64
90
  def initial_ready
65
91
  ideal > 0 ? 1 : 0
66
92
  end
67
93
 
68
- # message:: FrameType::Message
69
- # connection:: Connection
70
94
  # Registers message into registry and configures for distribution
71
- def register_message(message, connection)
72
- registry_info = registry_lookup(connection)
95
+ #
96
+ # @param message [FrameType::Message]
97
+ # @param connection_identifier [String]
98
+ # @return [Integer]
99
+ def register_message(message, connection_identifier)
100
+ registry_info = registry_lookup(connection_identifier)
73
101
  registry_info[:in_flight] += 1
74
- flight_record[message.message_id] = connection_key(connection)
75
- calculate_ready!(connection)
102
+ flight_record[message.message_id] = connection_identifier
103
+ calculate_ready!(connection_identifier)
76
104
  end
77
105
 
78
- # connection:: Connection
79
106
  # Add connection to make available for RDY distribution
107
+ #
108
+ # @param connection [Krakow::Connection]
109
+ # @return [TrueClass]
80
110
  def add_connection(connection)
81
- registry[connection_key(connection)] = {
82
- :ready => initial_ready,
83
- :in_flight => 0,
84
- :failures => 0,
85
- :backoff_until => 0
86
- }
111
+ unless(registry[connection.identifier])
112
+ registry[connection.identifier] = {
113
+ :ready => initial_ready,
114
+ :in_flight => 0,
115
+ :failures => 0,
116
+ :backoff_until => 0
117
+ }
118
+ end
87
119
  true
88
120
  end
89
121
 
90
- # connection:: Connection
91
122
  # Remove connection from RDY distribution
92
- def remove_connection(connection)
123
+ #
124
+ # @param connection_identifier [String]
125
+ # @return [TrueClass]
126
+ def remove_connection(connection_identifier, *args)
93
127
  # remove connection from registry
94
- registry.delete(connection_key(connection))
128
+ registry.delete(connection_identifier)
95
129
  # remove any in flight messages
96
130
  flight_record.delete_if do |k,v|
97
- v == connection_key(connection)
131
+ if(k == connection_identifier)
132
+ warn "Removing in flight reference due to failed connection: #{k}"
133
+ true
134
+ end
98
135
  end
99
136
  true
100
137
  end
101
138
 
102
- # connection:: Connection
103
- # Return lookup key (actor reference)
104
- def connection_key(connection)
105
- connection
139
+ # Return connection associated with given registry key
140
+ #
141
+ # @param identifier [String] connection identifier
142
+ # @return [Krakow::Connection, nil]
143
+ def connection_lookup(identifier)
144
+ consumer.connection(identifier)
106
145
  end
107
146
 
108
- # msg_id:: Message ID string
109
- # Return source connection of given `msg_id`. If block is
110
- # provided, the connection instance will be yielded to the block
111
- # and the result returned.
147
+ # Return source connection for given message ID
148
+ #
149
+ # @param msg_id [String]
150
+ # @yield execute with connection
151
+ # @yieldparam connection [Krakow::Connection]
152
+ # @return [Krakow::Connection, Object]
112
153
  def in_flight_lookup(msg_id)
113
- connection = flight_record[msg_id]
154
+ connection = connection_lookup(flight_record[msg_id])
114
155
  unless(connection)
115
156
  abort Krakow::Error::LookupFailed.new("Failed to locate in flight message (ID: #{msg_id})")
116
157
  end
@@ -121,34 +162,42 @@ module Krakow
121
162
  end
122
163
  end
123
164
 
124
- # connection:: Connection
125
165
  # Return registry information for given connection
126
- def registry_lookup(connection)
127
- registry[connection_key(connection)] ||
128
- abort(Krakow::Error::LookupFailed.new("Failed to locate connection information in registry (#{connection})"))
166
+ # @param connection_identifier [String]
167
+ # @return [Hash] registry information
168
+ # @raise [Krakow::Error::LookupFailed]
169
+ def registry_lookup(connection_identifier)
170
+ registry[connection_identifier] ||
171
+ abort(Krakow::Error::LookupFailed.new("Failed to locate connection information in registry (#{connection_identifier})"))
129
172
  end
130
173
 
131
- # Return list of all connections in registry
174
+ # @return [Array<Krakow::Connection>] connections in registry
132
175
  def connections
133
- registry.keys
176
+ registry.keys.map do |identifier|
177
+ connection_lookup(identifier)
178
+ end.compact
134
179
  end
135
180
 
136
- # connection:: Connection
137
181
  # Log failure of processed message
138
- def failure(connection)
182
+ #
183
+ # @param connection_identifier [String]
184
+ # @return [TrueClass]
185
+ def failure(connection_identifier)
139
186
  if(backoff_interval)
140
- registry_info = registry_lookup(connection)
187
+ registry_info = registry_lookup(connection_identifier)
141
188
  registry_info[:failures] += 1
142
189
  registry_info[:backoff_until] = Time.now.to_i + (registry_info[:failures] * backoff_interval)
143
190
  end
144
191
  true
145
192
  end
146
193
 
147
- # connection:: Connection
148
194
  # Log success of processed message
149
- def success(connection)
195
+ #
196
+ # @param connection_identifier [String]
197
+ # @return [TrueClass]
198
+ def success(connection_identifier)
150
199
  if(backoff_interval)
151
- registry_info = registry_lookup(connection)
200
+ registry_info = registry_lookup(connection_identifier)
152
201
  if(registry_info[:failures] > 1)
153
202
  registry_info[:failures] -= 1
154
203
  registry_info[:backoff_until] = Time.now.to_i + (registry_info[:failures] * backoff_interval)
@@ -156,6 +205,7 @@ module Krakow
156
205
  registry_info[:failures] = 0
157
206
  end
158
207
  end
208
+ true
159
209
  end
160
210
 
161
211
  end
@@ -1,13 +1,27 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
4
+ # Base error type
2
5
  class Error < StandardError
3
6
 
7
+ # Failed to enable required feature on connection
4
8
  class ConnectionFeatureFailure < Error; end
9
+ # Failed to perform lookup (not found)
5
10
  class LookupFailed < Error; end
11
+ # Connection has failed
6
12
  class ConnectionFailure < Error; end
13
+ # Configuration is not in valid state
7
14
  class ConfigurationError < Error; end
15
+ # Connection is temporarily unavailable
16
+ class ConnectionUnavailable < Error; end
17
+ # Consumer was not set
18
+ class OriginNotFound < Error; end
8
19
 
20
+ # Invalid response
9
21
  class BadResponse < Error
22
+ # @return [Response] error response
10
23
  attr_accessor :result
24
+ # No response received
11
25
  class NoResponse < BadResponse
12
26
  end
13
27
  end
@@ -1,16 +1,22 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
2
4
  class FrameType
5
+ # Error from server
3
6
  class Error < FrameType
4
7
 
5
- def initialize(args={})
6
- super
7
- required! :error
8
- end
8
+ # @!group Attributes
9
9
 
10
- def error
11
- arguments[:error]
12
- end
10
+ # @!macro [attach] attribute
11
+ # @!method $1
12
+ # @return [$2] the $1 $0
13
+ # @!method $1?
14
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
15
+ attribute :error, String, :required => true
16
+
17
+ # @!endgroup
13
18
 
19
+ # @return [String] content of error
14
20
  def content
15
21
  error
16
22
  end
@@ -1,16 +1,59 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
2
4
  class FrameType
5
+ # Message received from server
3
6
  class Message < FrameType
4
7
 
5
- def initialize(args={})
6
- super
7
- required! :attempts, :timestamp, :message_id, :message
8
- end
8
+ # @return [Krakow::Consumer]
9
+ attr_accessor :origin
10
+
11
+ # @!group Attributes
12
+
13
+ # @!macro [attach] attribute
14
+ # @!method $1
15
+ # @return [$2] the $1 $0
16
+ # @!method $1?
17
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
18
+ attribute :attempts, Integer, :required => true
19
+ attribute :timestamp, Integer, :required => true
20
+ attribute :message_id, String, :required => true
21
+ attribute :message, String, :required => true
9
22
 
23
+ # @!endgroup
24
+
25
+ # Message content
26
+ #
27
+ # @return [String]
10
28
  def content
11
29
  message
12
30
  end
13
31
 
32
+ # @return [Krakow::Consumer]
33
+ def origin
34
+ unless(@origin)
35
+ error 'No origin has been specified for this message'
36
+ abort Krakow::Error::OriginNotFound.new('No origin specified for this message')
37
+ end
38
+ @origin
39
+ end
40
+
41
+ # Proxy to [Krakow::Consumer#confirm]
42
+ def confirm(*args)
43
+ origin.confirm(*[self, *args].compact)
44
+ end
45
+ alias_method :finish, :confirm
46
+
47
+ # Proxy to [Krakow::Consumer#requeue]
48
+ def requeue(*args)
49
+ origin.requeue(*[self, *args].compact)
50
+ end
51
+
52
+ # Proxy to [Krakow::Consumer#touch]
53
+ def touch(*args)
54
+ origin.touch(*[self, *args].compact)
55
+ end
56
+
14
57
  end
15
58
  end
16
59
  end
@@ -1,12 +1,22 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
2
4
  class FrameType
5
+ # Response from server
3
6
  class Response < FrameType
4
7
 
5
- def initialize(args={})
6
- super
7
- required! :response
8
- end
8
+ # @!group Attributes
9
+
10
+ # @!macro [attach] attribute
11
+ # @!method $1
12
+ # @return [$2] the $1 $0
13
+ # @!method $1?
14
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
15
+ attribute :response, String, :required => true
16
+
17
+ # @!endgroup
9
18
 
19
+ # @return [String] content of response
10
20
  def content
11
21
  response
12
22
  end
@@ -1,4 +1,8 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
4
+ # Received message
5
+ # @abstract
2
6
  class FrameType
3
7
 
4
8
  autoload :Error, 'krakow/frame_type/error'
@@ -6,25 +10,34 @@ module Krakow
6
10
  autoload :Response, 'krakow/frame_type/response'
7
11
 
8
12
  include Utils::Lazy
13
+ # @!parse include Krakow::Utils::Lazy::InstanceMethods
14
+ # @!parse extend Krakow::Utils::Lazy::ClassMethods
9
15
 
16
+ # Registered frame types
10
17
  FRAME_TYPE_MAP = [
11
18
  FrameType::Response,
12
19
  FrameType::Error,
13
20
  FrameType::Message
14
21
  ]
22
+ # Size bytes
15
23
  SIZE_BYTES = 4
16
24
 
17
25
  class << self
18
26
 
19
- # bytes:: 8 bytes
20
- # Return information about incoming frame
27
+ # Information about incoming frame
28
+ # @param bytes [String]
29
+ # @return [Hash]
21
30
  def decode(bytes)
22
31
  size, type = bytes.unpack('l>l>')
23
32
  {:size => size - SIZE_BYTES, :type => type}
24
33
  end
25
34
 
26
- # args:: arguments (:type, :data, :size)
27
35
  # Build proper FrameType instance based on args
36
+ # @param args [Hash]
37
+ # @option args [FrameType] :type class of frame
38
+ # @option args [String] :data
39
+ # @option args [Integer] :size
40
+ # @return [FrameType]
28
41
  def build(args={})
29
42
  klass = FRAME_TYPE_MAP[args[:type].to_i]
30
43
  if(klass == FrameType::Response)
@@ -42,12 +55,11 @@ module Krakow
42
55
  end
43
56
  end
44
57
 
45
- def initialize(args={})
46
- super
47
- end
48
-
58
+ # Content of message
59
+ #
60
+ # @return [String]
49
61
  def content
50
- raise NoMethodError.new 'Content method not properly defined!'
62
+ raise NotImplementedError.new 'Content method not properly defined!'
51
63
  end
52
64
 
53
65
  end
@@ -2,35 +2,85 @@ require 'http'
2
2
  require 'uri'
3
3
  require 'ostruct'
4
4
 
5
+ require 'cgi'
6
+ # NOTE: Prevents weird "first" run behavior
7
+ begin
8
+ require 'json'
9
+ rescue LoadError
10
+ # ignore (maybe log?)
11
+ end
12
+
13
+ require 'krakow'
14
+
5
15
  module Krakow
6
16
  class Producer
17
+
18
+ # HTTP based producer
7
19
  class Http
8
20
 
21
+ include Utils::Lazy
22
+ # @!parse include Krakow::Utils::Lazy::InstanceMethods
23
+ # @!parse extend Krakow::Utils::Lazy::ClassMethods
24
+
25
+ # Wrapper for HTTP response hash
9
26
  class Response < OpenStruct
10
27
  end
11
28
 
12
- include Utils::Lazy
13
-
14
29
  attr_reader :uri
15
30
 
31
+ # @!group Attributes
32
+
33
+ # @!macro [attach] attribute
34
+ # @!method $1
35
+ # @return [$2] the $1 $0
36
+ # @!method $1?
37
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
38
+ attribute :endpoint, String, :required => true
39
+ attribute :topic, String, :required => true
40
+ attribute :config, Hash, :default => ->{ Hash.new }
41
+ attribute :ssl_context, Hash
42
+
43
+ # @!endgroup
44
+
16
45
  def initialize(args={})
17
46
  super
18
- required! :endpoint, :topic
47
+ build_ssl_context if ssl_context
19
48
  @uri = URI.parse(endpoint)
20
49
  end
21
50
 
51
+ # Create a new SSL context
52
+ #
53
+ # @return [OpenSSL::SSL::SSLContext]
54
+ def build_ssl_context
55
+ require 'openssl'
56
+ context = OpenSSL::SSL::SSLContext.new
57
+ context.cert = OpenSSL::X509::Certificate.new(File.open(ssl_context[:certificate]))
58
+ context.key = OpenSSL::PKey::RSA.new(File.open(ssl_context[:key]))
59
+ config[:ssl_context] = context
60
+ end
61
+
62
+ # Send a message via HTTP
63
+ #
64
+ # @param method [String, Symbol] HTTP method to use (:get, :put, etc)
65
+ # @param path [String] URI path
66
+ # @param args [Hash] payload hash
67
+ # @return [Response]
22
68
  def send_message(method, path, args={})
23
69
  build = uri.dup
24
70
  build.path = "/#{path}"
25
- response = HTTP.send(method, build.to_s, args)
71
+ response = HTTP.send(method, build.to_s, args.merge(config))
26
72
  begin
27
- response = MultiJson.load(response.response.body)
73
+ response = MultiJson.load(response.body.to_s)
28
74
  rescue MultiJson::LoadError
29
- response = {'status_code' => response == 'OK' ? 200 : nil, 'status_txt' => response, 'data' => nil}
75
+ response = {'status_code' => response.code, 'status_txt' => response.body.to_s, 'data' => nil}
30
76
  end
31
77
  Response.new(response)
32
78
  end
33
79
 
80
+ # Send messages
81
+ #
82
+ # @param payload [String] message
83
+ # @return [Response]
34
84
  def write(*payload)
35
85
  if(payload.size == 1)
36
86
  payload = payload.first
@@ -46,18 +96,28 @@ module Krakow
46
96
  end
47
97
  end
48
98
 
99
+ # Create the topic
100
+ #
101
+ # @return [Response]
49
102
  def create_topic
50
103
  send_message(:post, :create_topic,
51
104
  :params => {:topic => topic}
52
105
  )
53
106
  end
54
107
 
108
+ # Delete the topic
109
+ #
110
+ # @return [Response]
55
111
  def delete_topic
56
112
  send_message(:post, :delete_topic,
57
113
  :params => {:topic => topic}
58
114
  )
59
115
  end
60
116
 
117
+ # Create channel on topic
118
+ #
119
+ # @param chan [String] channel name
120
+ # @return [Response]
61
121
  def create_channel(chan)
62
122
  send_message(:post, :create_channel,
63
123
  :params => {
@@ -67,6 +127,10 @@ module Krakow
67
127
  )
68
128
  end
69
129
 
130
+ # Delete channel on topic
131
+ #
132
+ # @param chan [String] channel name
133
+ # @return [Response]
70
134
  def delete_channel(chan)
71
135
  send_message(:post, :delete_channel,
72
136
  :params => {
@@ -76,12 +140,19 @@ module Krakow
76
140
  )
77
141
  end
78
142
 
143
+ # Remove all messages from topic
144
+ #
145
+ # @return [Response]
79
146
  def empty_topic
80
147
  send_message(:post, :empty_topic,
81
148
  :params => {:topic => topic}
82
149
  )
83
150
  end
84
151
 
152
+ # Remove all messages from given channel on topic
153
+ #
154
+ # @param chan [String] channel name
155
+ # @return [Response]
85
156
  def empty_channel(chan)
86
157
  send_message(:post, :empty_channel,
87
158
  :params => {
@@ -91,6 +162,10 @@ module Krakow
91
162
  )
92
163
  end
93
164
 
165
+ # Pause messages on given channel
166
+ #
167
+ # @param chan [String] channel name
168
+ # @return [Response]
94
169
  def pause_channel(chan)
95
170
  send_message(:post, :pause_channel,
96
171
  :params => {
@@ -100,6 +175,10 @@ module Krakow
100
175
  )
101
176
  end
102
177
 
178
+ # Resume messages on a given channel
179
+ #
180
+ # @param chan [String] channel name
181
+ # @return [Response]
103
182
  def unpause_channel(chan)
104
183
  send_message(:post, :unpause_channel,
105
184
  :params => {
@@ -109,6 +188,10 @@ module Krakow
109
188
  )
110
189
  end
111
190
 
191
+ # Server stats
192
+ #
193
+ # @param format [String] format of data
194
+ # @return [Response]
112
195
  def stats(format='json')
113
196
  send_message(:get, :stats,
114
197
  :params => {
@@ -117,10 +200,16 @@ module Krakow
117
200
  )
118
201
  end
119
202
 
203
+ # Ping the server
204
+ #
205
+ # @return [Response]
120
206
  def ping
121
207
  send_message(:get, :ping)
122
208
  end
123
209
 
210
+ # Server information
211
+ #
212
+ # @return [Response]
124
213
  def info
125
214
  send_message(:get, :info)
126
215
  end