baton 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/COPYING +8 -0
- data/Gemfile +10 -0
- data/Guardfile +6 -0
- data/README.md +77 -0
- data/Rakefile +10 -0
- data/baton.gemspec +30 -0
- data/bin/batonize +60 -0
- data/lib/baton.rb +13 -0
- data/lib/baton/api.rb +27 -0
- data/lib/baton/channel.rb +47 -0
- data/lib/baton/configuration.rb +63 -0
- data/lib/baton/consumer.rb +89 -0
- data/lib/baton/consumer_manager.rb +67 -0
- data/lib/baton/logging.rb +18 -0
- data/lib/baton/observer.rb +74 -0
- data/lib/baton/server.rb +68 -0
- data/lib/baton/service.rb +55 -0
- data/lib/baton/templates/gem/Gemfile.tt +5 -0
- data/lib/baton/templates/gem/LICENSE.tt +22 -0
- data/lib/baton/templates/gem/README.md.tt +29 -0
- data/lib/baton/templates/gem/Rakefile.tt +6 -0
- data/lib/baton/templates/gem/bin/gem-monitor.tt +10 -0
- data/lib/baton/templates/gem/bin/gem.tt +12 -0
- data/lib/baton/templates/gem/config/gem.cfg.tt +4 -0
- data/lib/baton/templates/gem/gem.gemspec.tt +22 -0
- data/lib/baton/templates/gem/gitignore.tt +17 -0
- data/lib/baton/templates/gem/lib/baton/gem.rb.tt +15 -0
- data/lib/baton/templates/gem/lib/baton/gem/gem-api.rb.tt +17 -0
- data/lib/baton/templates/gem/lib/baton/gem/gem-consumer.rb.tt +26 -0
- data/lib/baton/templates/gem/lib/baton/gem/gem-monitor.rb.tt +32 -0
- data/lib/baton/templates/gem/lib/baton/gem/version.rb.tt +7 -0
- data/lib/baton/version.rb +3 -0
- data/spec/baton/baton_spec.rb +13 -0
- data/spec/baton/configuration_spec.rb +54 -0
- data/spec/baton/consumer_manager_spec.rb +72 -0
- data/spec/baton/consumer_spec.rb +63 -0
- data/spec/baton/server_spec.rb +64 -0
- data/spec/fixtures/config.cfg +4 -0
- data/spec/fixtures/facts.json +1776 -0
- data/spec/fixtures/file +1 -0
- data/spec/fixtures/file.sum +1 -0
- data/spec/fixtures/invalid_facts.json +1774 -0
- data/spec/fixtures/invalid_file +1 -0
- data/spec/fixtures/invalid_file.sum +1 -0
- data/spec/spec_helper.rb +12 -0
- metadata +236 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/COPYING
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
Copyright (c) 2012 Macmillan Digital Science, Ltd.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
8
|
+
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# Baton - Server Orchestration Tool
|
2
|
+
|
3
|
+
[![Build Status](https://secure.travis-ci.org/digital-science/baton.png)](http://travis-ci.org/digital-science/baton)
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
Baton is a general purpose server orchestration tool.
|
8
|
+
|
9
|
+
## Getting Started
|
10
|
+
|
11
|
+
git clone git@github.com:digital-science/baton.git
|
12
|
+
cd baton
|
13
|
+
bundle install
|
14
|
+
|
15
|
+
## Testing
|
16
|
+
|
17
|
+
bundle exec rspec
|
18
|
+
|
19
|
+
## Install
|
20
|
+
|
21
|
+
You can either:
|
22
|
+
|
23
|
+
gem install baton
|
24
|
+
|
25
|
+
Or, in your Gemfile:
|
26
|
+
|
27
|
+
gem 'baton'
|
28
|
+
|
29
|
+
## How to use
|
30
|
+
|
31
|
+
Please check an existing extension, e.g. [baton-ping](https://github.com/digital-science/baton-ping), for more information about how to use and extend baton.
|
32
|
+
Since baton was created as a base for other extensions, it doesn't do anything in particular by itself but provide the structure and a basic setup on top of RabbitMQ and EventMachine.
|
33
|
+
|
34
|
+
## Details and Building Extensions
|
35
|
+
|
36
|
+
Baton relies on [EventMachine](http://rubyeventmachine.com/) and [AMQP](http://rubyamqp.info/) for message passing. The gem defines a basic set of classes operating on top of RabbitMQ. The initial configuration will setup an input exchange and an output exchange.
|
37
|
+
|
38
|
+
On the input exchange, baton will wait for meaningful messages to perform actions (described by each service) and it will output messages to the output exchange.
|
39
|
+
|
40
|
+
### API
|
41
|
+
|
42
|
+
This is the entry point for input messages. One should extend the API class and add meaningful methods that ultimately use `publish` to publish messages to the input exchange. One example can be found [here](https://github.com/digital-science/baton-ping/blob/master/lib/baton/baton-ping/api.rb#L8)
|
43
|
+
|
44
|
+
### Executable script
|
45
|
+
|
46
|
+
Any baton extension should have an executable script that will start the extension service. [Here](https://github.com/digital-science/baton-ping/blob/master/bin/baton-ping) is an example.
|
47
|
+
|
48
|
+
### Service
|
49
|
+
|
50
|
+
The Service is the starting point of any baton extension. The idea of the service is to setup consumers for the input messages arriving from the API. By implementing `setup_consumers` one will allow the consumers to receive messages. [Here](https://github.com/digital-science/baton-ping/blob/master/lib/baton/baton-ping.rb) is an example.
|
51
|
+
|
52
|
+
### Consumer Manager
|
53
|
+
|
54
|
+
This class is an orchestration class that attaches observers to the consumers (like logger, etc), binds the input queues to the correct exchanges, dispatches the received messages to the consumers and updates the observers on changes. One doesn't need to extend this class unless one wants to change it's behaviour.
|
55
|
+
|
56
|
+
### Consumer
|
57
|
+
|
58
|
+
This class must be extended in order to process each received message. One should implement `process_message` at least, in order to give meaning to each received message. One can also override `routing_key` in order to listen to specific messages. [Here](https://github.com/digital-science/baton-ping/blob/master/lib/baton/baton-ping/ping_consumer.rb) is an example of an implementation.
|
59
|
+
|
60
|
+
### Channel
|
61
|
+
|
62
|
+
Like the consumer manager, this class doesn't need to be extended. It provides functionality to setup the exchanges and add consumers.
|
63
|
+
|
64
|
+
### Observer
|
65
|
+
|
66
|
+
The observer class provides methods to notify observers. It is by default included in the consumers so that the output exchange (and possibly loggers, etc) receive the output messages.
|
67
|
+
|
68
|
+
|
69
|
+
## Minimal Extension
|
70
|
+
|
71
|
+
[baton-ping](https://github.com/digital-science/baton-ping) provides what we consider to be a minimal extension to baton. One should note that there is an extra class on `baton-ping` called [monitor](https://github.com/digital-science/baton-ping/blob/master/lib/baton/baton-ping/monitor.rb). This is a good example of what to do with output messages from a baton extension. Together with [baton-ping-monitor](https://github.com/digital-science/baton-ping/blob/master/bin/baton-ping-monitor) it provides a standard way of consuming output messages and do something relevant with them.
|
72
|
+
|
73
|
+
If you would like to create your own extension, simple install baton, as explained above, and run the following:
|
74
|
+
|
75
|
+
batonize gem GEMNAME -b
|
76
|
+
|
77
|
+
This will create a basic gem structure withe the necessary files to create a minimum viable baton extension.
|
data/Rakefile
ADDED
data/baton.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/baton/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["John Griffin", "Carlos Vilhena"]
|
6
|
+
gem.email = ["johnog@gmail.com", "carlosvilhena@gmail.com"]
|
7
|
+
gem.description = "Baton"
|
8
|
+
gem.summary = "Baton"
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n").reject! { |fn| fn.include? ".tgz" }
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n").reject! { |fn| fn.include? ".tgz" }
|
14
|
+
gem.name = "baton"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Baton::VERSION
|
17
|
+
|
18
|
+
gem.add_runtime_dependency "amqp", "~> 0.8.4"
|
19
|
+
gem.add_runtime_dependency "eventmachine", "~> 1.0.0.beta.4"
|
20
|
+
gem.add_runtime_dependency "em-http-request", "1.0.0"
|
21
|
+
gem.add_runtime_dependency "bunny", "~> 0.7.8"
|
22
|
+
gem.add_runtime_dependency "thor"
|
23
|
+
|
24
|
+
gem.add_development_dependency "rspec", "~> 2.7"
|
25
|
+
gem.add_development_dependency "moqueue", "~> 0.1.4"
|
26
|
+
gem.add_development_dependency "fakefs", "~> 0.4.0"
|
27
|
+
gem.add_development_dependency "rake", "~> 0.9.2"
|
28
|
+
gem.add_development_dependency "webmock", "~> 1.7.7"
|
29
|
+
gem.add_development_dependency "minitar", "0.5.3"
|
30
|
+
end
|
data/bin/batonize
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'thor'
|
5
|
+
|
6
|
+
module Baton
|
7
|
+
class CLI < Thor
|
8
|
+
include Thor::Actions
|
9
|
+
|
10
|
+
desc "gem GEMNAME", "Creates a skeleton for creating a rubygem that extends Baton called baton-GEMNAME"
|
11
|
+
|
12
|
+
method_option :bin, :type => :boolean, :default => false, :aliases => '-b', :banner => "Generate a binary for your library."
|
13
|
+
|
14
|
+
def gem(name)
|
15
|
+
name = "baton-#{name.chomp("/")}"
|
16
|
+
target = File.join(Dir.pwd, name)
|
17
|
+
constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
|
18
|
+
constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
|
19
|
+
constant_array = constant_name.split('::')
|
20
|
+
FileUtils.mkdir_p(File.join(target, 'config'))
|
21
|
+
FileUtils.mkdir_p(File.join(target, 'lib', "baton"))
|
22
|
+
FileUtils.mkdir_p(File.join(target, 'lib', 'baton', name))
|
23
|
+
git_user_name = `git config user.name`.chomp
|
24
|
+
git_user_email = `git config user.email`.chomp
|
25
|
+
opts = {
|
26
|
+
:name => name,
|
27
|
+
:constant_name => constant_name,
|
28
|
+
:constant_array => constant_array,
|
29
|
+
:author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
|
30
|
+
:email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email
|
31
|
+
}
|
32
|
+
|
33
|
+
template(File.join("gem/Gemfile.tt"), File.join(target, "Gemfile"), opts)
|
34
|
+
template(File.join("gem/Rakefile.tt"), File.join(target, "Rakefile"), opts)
|
35
|
+
template(File.join("gem/LICENSE.tt"), File.join(target, "LICENSE"), opts)
|
36
|
+
template(File.join("gem/README.md.tt"), File.join(target, "README.md"), opts)
|
37
|
+
template(File.join("gem/gitignore.tt"), File.join(target, ".gitignore"), opts)
|
38
|
+
template(File.join("gem/gem.gemspec.tt"), File.join(target, "#{name}.gemspec"), opts)
|
39
|
+
template(File.join("gem/config/gem.cfg.tt"), File.join(target, "config/#{name}.cfg"), opts)
|
40
|
+
template(File.join("gem/lib/baton/gem.rb.tt"), File.join(target, "lib/baton/#{name}.rb"), opts)
|
41
|
+
template(File.join("gem/lib/baton/gem/version.rb.tt"), File.join(target, "lib/baton/#{name}/version.rb"), opts)
|
42
|
+
template(File.join("gem/lib/baton/gem/gem-consumer.rb.tt"), File.join(target, "lib/baton/#{name}/#{name}-consumer.rb"), opts)
|
43
|
+
template(File.join("gem/lib/baton/gem/gem-monitor.rb.tt"), File.join(target, "lib/baton/#{name}/#{name}-monitor.rb"), opts)
|
44
|
+
template(File.join("gem/lib/baton/gem/gem-api.rb.tt"), File.join(target, "lib/baton/#{name}/#{name}-api.rb"), opts)
|
45
|
+
if options[:bin]
|
46
|
+
template(File.join("gem/bin/gem.tt"), File.join(target, 'bin', name), opts)
|
47
|
+
template(File.join("gem/bin/gem-monitor.tt"), File.join(target, 'bin', "#{name}-monitor"), opts)
|
48
|
+
end
|
49
|
+
|
50
|
+
Dir.chdir(target) { `git init`; `git add .` }
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.source_root
|
54
|
+
File.expand_path(File.join(File.dirname(__FILE__), '../lib/baton/templates'))
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Baton::CLI.start
|
data/lib/baton.rb
ADDED
data/lib/baton/api.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require "baton"
|
2
|
+
require "bunny"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Baton
|
6
|
+
class API
|
7
|
+
|
8
|
+
# Public: Method that publishes a message using Bunny to an exchange.
|
9
|
+
#
|
10
|
+
# message - a json object containing the message
|
11
|
+
# key - the routing key used to forward the message to the right queue(s)
|
12
|
+
#
|
13
|
+
# Examples
|
14
|
+
#
|
15
|
+
# publish("{\"message\":\"a message\",\"type\":\"a type\"}", "server.production")
|
16
|
+
#
|
17
|
+
# Returns nothing.
|
18
|
+
def self.publish(message, key)
|
19
|
+
b = Bunny.new(Baton.configuration.connection_opts)
|
20
|
+
b.start
|
21
|
+
e = b.exchange(Baton.configuration.exchange, :auto_delete => false)
|
22
|
+
e.publish(message, :key => key, :mandatory => true)
|
23
|
+
b.stop
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "baton/consumer"
|
2
|
+
require "baton/logging"
|
3
|
+
|
4
|
+
module Baton
|
5
|
+
class Channel
|
6
|
+
include Baton::Logging
|
7
|
+
|
8
|
+
attr_accessor :channel, :exchange_in, :exchange_out, :connection
|
9
|
+
|
10
|
+
# Public: Initialize a Channel. It creates an AMQP connection, a channel,
|
11
|
+
# an input and an output exchange and finally attaches the handle_channel_exception
|
12
|
+
# callback to the on_error event on the channel.
|
13
|
+
def initialize
|
14
|
+
@connection = AMQP.connect(Baton.configuration.connection_opts)
|
15
|
+
@channel = AMQP::Channel.new(@connection)
|
16
|
+
@exchange_in = channel.direct(Baton.configuration.exchange)
|
17
|
+
@exchange_out = channel.direct(Baton.configuration.exchange_out)
|
18
|
+
@channel.on_error(&method(:handle_channel_exception))
|
19
|
+
end
|
20
|
+
|
21
|
+
# Public: creates a consumer manager with a consumer attached and starts
|
22
|
+
# listening to messages.
|
23
|
+
#
|
24
|
+
# consumer - An instance of Baton::Consumer. it will typically be a extension of
|
25
|
+
# Baton::Consumer (e.g. Baton::DeployConsumer).
|
26
|
+
#
|
27
|
+
# Examples
|
28
|
+
#
|
29
|
+
# add_consumer(consumer)
|
30
|
+
#
|
31
|
+
# Returns nothing.
|
32
|
+
def add_consumer(consumer)
|
33
|
+
Baton::ConsumerManager.new(consumer, channel, exchange_in, exchange_out).start
|
34
|
+
end
|
35
|
+
|
36
|
+
# Public: Callback to handle errors on an AMQP channel.
|
37
|
+
#
|
38
|
+
# channel - An AMQP channel
|
39
|
+
# channel_close -
|
40
|
+
#
|
41
|
+
# Returns nothing.
|
42
|
+
#
|
43
|
+
def handle_channel_exception(channel, channel_close)
|
44
|
+
logger.error "Channel-level exception: code = #{channel_close.reply_code}, message = #{channel_close.reply_text}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "baton/logging"
|
3
|
+
|
4
|
+
module Baton
|
5
|
+
class Configuration
|
6
|
+
include Baton::Logging
|
7
|
+
|
8
|
+
attr_accessor :exchange, :exchange_out, :ohai_file,
|
9
|
+
:host, :vhost, :user, :password,
|
10
|
+
:pusher_app_id, :pusher_key, :pusher_secret, :config_path
|
11
|
+
|
12
|
+
# Public: Loads the config file given as parameter and sets up RabbitMQ's options.
|
13
|
+
#
|
14
|
+
# path - A file path representing a config file
|
15
|
+
#
|
16
|
+
# Examples
|
17
|
+
#
|
18
|
+
# config_file = "/path/to/file"
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
# Raises Errno::ENOENT if file cannot be found.
|
22
|
+
def config_path=(path)
|
23
|
+
config_file = YAML.load_file(path)
|
24
|
+
setup_rabbitmq_opts(config_file)
|
25
|
+
rescue Errno::ENOENT => e
|
26
|
+
self.host = "localhost"
|
27
|
+
logger.error "Could not find a baton configuration file at #{path}"
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Setup RabbitMQ's options from a config file.
|
31
|
+
#
|
32
|
+
# config_file - A hash representing a config file
|
33
|
+
#
|
34
|
+
# Examples
|
35
|
+
#
|
36
|
+
# setup_rabbitmq_opts({
|
37
|
+
# "RABBIT_HOST" => "localhost",
|
38
|
+
# "RABBIT_VHOST" => "baton",
|
39
|
+
# "RABBIT_USER" => "baton",
|
40
|
+
# "RABBIT_PASS" => "password"
|
41
|
+
# })
|
42
|
+
#
|
43
|
+
# Returns nothing.
|
44
|
+
def setup_rabbitmq_opts(config_file)
|
45
|
+
self.host = config_file.fetch("RABBIT_HOST") {"localhost"}
|
46
|
+
self.vhost = config_file["RABBIT_VHOST"]
|
47
|
+
self.user = config_file["RABBIT_USER"]
|
48
|
+
self.password = config_file["RABBIT_PASS"]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Public: Defines the connection options for RabbitMQ as a Hash.
|
52
|
+
#
|
53
|
+
# Examples
|
54
|
+
#
|
55
|
+
# connection_options
|
56
|
+
# # => {:host=>"localhost", :vhost=>"baton", :user=>"baton", :password=>"password"}
|
57
|
+
#
|
58
|
+
# Returns a hash of RabbitMQ connection options.
|
59
|
+
def connection_opts
|
60
|
+
{:host => host, :vhost => vhost, :user => user, :password => password, :pass => password}.delete_if{|k,v| v.nil?}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require "baton/observer"
|
2
|
+
|
3
|
+
module Baton
|
4
|
+
class Consumer
|
5
|
+
include Baton::Observer
|
6
|
+
include Baton::Logging
|
7
|
+
|
8
|
+
attr_accessor :consumer_name, :server, :consumer_manager
|
9
|
+
|
10
|
+
# Public: Initialize a Consumer.
|
11
|
+
#
|
12
|
+
# consumer_name - A String naming the consumer.
|
13
|
+
# server - An instance of Baton::Server.
|
14
|
+
def initialize(consumer_name, server)
|
15
|
+
@consumer_name, @server = consumer_name, server
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Defines the routing key for the consumer. Messages with the
|
19
|
+
# defined routing queue will be consumed by this consumer.
|
20
|
+
#
|
21
|
+
# Examples
|
22
|
+
#
|
23
|
+
# routing_key
|
24
|
+
# # => "central-apu.production"
|
25
|
+
#
|
26
|
+
# Returns the routing key.
|
27
|
+
def routing_key
|
28
|
+
"#{consumer_name}.#{server.environment}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public: Method that wraps a block and notifies when errors occur.
|
32
|
+
#
|
33
|
+
# Examples
|
34
|
+
#
|
35
|
+
# exception_notifier do
|
36
|
+
# <your code>
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# Returns nothing.
|
40
|
+
def exception_notifier
|
41
|
+
yield
|
42
|
+
rescue Exception => e
|
43
|
+
notify_error(e.class, e.message)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Public: Method that decodes a json message and passes it to process_message
|
47
|
+
# to be processed.
|
48
|
+
#
|
49
|
+
# payload - A message in json format
|
50
|
+
#
|
51
|
+
# Examples
|
52
|
+
#
|
53
|
+
# handle_message("{\"message\":\"a message\",\"type\":\"a type\"}")
|
54
|
+
#
|
55
|
+
# Returns nothing.
|
56
|
+
def handle_message(payload)
|
57
|
+
exception_notifier do
|
58
|
+
message = JSON.load(payload)
|
59
|
+
process_message(message)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Public: Method that will be called when handle_message receives a message.
|
64
|
+
# It should be implemented by baton-like gems and it should add logic to
|
65
|
+
# process messages.
|
66
|
+
#
|
67
|
+
# message - A message in ruby-format
|
68
|
+
#
|
69
|
+
# Examples
|
70
|
+
#
|
71
|
+
# process_message({"type" => "current"})
|
72
|
+
#
|
73
|
+
# Returns Output depends on the implementation.
|
74
|
+
def process_message(message)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Public: Method that provides an hash of attributes, if they are needed.
|
78
|
+
#
|
79
|
+
# Examples
|
80
|
+
#
|
81
|
+
# attributes
|
82
|
+
# # => {type: "pong"}.merge(server.attributes)
|
83
|
+
#
|
84
|
+
# Returns Output depends on the implementation.
|
85
|
+
def attributes
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|