Class: Pokan::Server
- Includes:
- ServerMessages
- Defined in:
- lib/pokan/server.rb
Overview
Gossip server class, using the Pokan::Peer class. This is the main class instantied by user code.
When a server class is created, the user should set:
-
the gossip interval
-
actual data to be stored, and possibly shared with other servers accross the network
-
The server behavior on a defined set of events, declared in an event driven syntax.
The user can also use epoll for faster I/O notification, if the server is running on a Linux system.
Sample usage is shown below:
s = Pokan::Server.new
s.gossip_every(1) #=> tells the server to gossip every second
s.use_epoll #=> I'm in a Linux system
s.store 'k', 'v'
e.on :new_key do |key, value|
puts "What a great key I just got: #{key}!"
end
# more event related code...
e.start #=> last command, blocks execution
Constant Summary collapse
- ON_EVENTS =
[:new_key, :key_changed, :key_removed, :start, :shutdown]
- BEFORE_EVENTS =
[:gossip, :sync]
- AFTER_EVENTS =
[:gossip, :sync]
Instance Attribute Summary collapse
-
#gossip_interval ⇒ Object
readonly
Returns the value of attribute gossip_interval.
Attributes inherited from Entity
Instance Method Summary collapse
-
#after(event, &block) ⇒ Object
Same as the Pokan::Server#before, but it also supports the
:sync
event. -
#before(event, &block) ⇒ Object
Adds behaviour before a given event occurs.
-
#every(seconds, &action) ⇒ Object
Adds behavior to the server, to be executed periodically (every given amount of seconds).
-
#gossip_every(seconds) ⇒ Object
Use this method to specify the time interval you wish to use for changing gossip messages among peers.
-
#initialize(address) ⇒ Server
constructor
Creates a new gossip server.
-
#on(event, &block) ⇒ Object
Defines the behaviour you want the server to have on different events.
-
#start(options = {}) ⇒ Object
This method starts the server, which will bind specified TCP and UDP ports (or 5555 by default).
-
#stop ⇒ Object
Finishes the server.
-
#store(key, value, timestamp = Time.now) ⇒ Object
Stores a key, value pair that will be shared among all the peers in the network.
-
#use_epoll ⇒ Object
Call this method if you want to use epoll in your Linux system.
- #using_epoll? ⇒ Boolean
Methods included from ServerMessages
#digest_message, #goodbye_message, #hello_message
Methods inherited from Peer
#act_as_seed, #address, #address=, #alive?, #dead?, #kill, #peer?, #revive, #role, #role=, #seed?, #status, #status=, #sync_with, #tcp_port, #tcp_port=, #udp_port, #udp_port=
Methods inherited from Entity
#destroy, #digest, #keys, #match?, #merge, #newer, #older, #reload, #save, #timestamp, #value, #values
Constructor Details
#initialize(address) ⇒ Server
Creates a new gossip server. You must pass the machine’s IP address in the network. This information will be used when changing information with other peers running Pokan. This also set some defaults, namely:
-
server will bind TCP and UDP port number 5555. If you have something else running, you must set them like:
server.tcp_port = 9876 server.udp_port = 9989
-
epoll
will not be used (you might want to set it if you are in a Linux system. See Pokan::Server#use_epoll -
The server will comunicate with other peers _every second_
Of course, all of these are customizable to your particular needs.
62 63 64 65 66 67 68 69 70 |
# File 'lib/pokan/server.rb', line 62 def initialize(address) @event_handler = EventHandler.new @seed_address, @seed_port = '', '' @periodics = [] self.address = address self.udp_port = 5555 super() initialize_ivs end |
Instance Attribute Details
#gossip_interval ⇒ Object (readonly)
Returns the value of attribute gossip_interval.
38 39 40 |
# File 'lib/pokan/server.rb', line 38 def gossip_interval @gossip_interval end |
Instance Method Details
#after(event, &block) ⇒ Object
Same as the Pokan::Server#before, but it also supports the :sync
event. Use this method to run some code after the server gossips with a random peer or after it syncs with a seed (if you passed one on initialization. See Pokan::Server#start).
133 134 135 136 |
# File 'lib/pokan/server.rb', line 133 def after(event, &block) event_name = prepend('after_', event) register_event(event_name, &block) if AFTER_EVENTS.include? event end |
#before(event, &block) ⇒ Object
Adds behaviour before a given event occurs. For now, the only event supported is :gossip
. Use this method if you want some code to run every time before the server gossips with a random peer.
124 125 126 127 |
# File 'lib/pokan/server.rb', line 124 def before(event, &block) event_name = prepend('before_', event) register_event(event_name, &block) if BEFORE_EVENTS.include? event end |
#every(seconds, &action) ⇒ Object
Adds behavior to the server, to be executed periodically (every given amount of seconds).
server.every 2 do
puts "Heya!"
end
Every 2 seconds “Heya!” will be printed out.
147 148 149 |
# File 'lib/pokan/server.rb', line 147 def every(seconds, &action) @periodics << { :period => seconds, :action => action } end |
#gossip_every(seconds) ⇒ Object
Use this method to specify the time interval you wish to use for changing gossip messages among peers. Default is 1 second.
86 87 88 |
# File 'lib/pokan/server.rb', line 86 def gossip_every(seconds) @gossip_interval = seconds end |
#on(event, &block) ⇒ Object
Defines the behaviour you want the server to have on different events. For now, you can define your behaviour for the following events:
-
:new_key
- This will be called whenever a new_key is inserted (and there was no previous value for that) -
:key_changed
- This is called when a value for a certain key is updated (a value with greater timestamp) -
:key_removed
- The name speaks for itself
For all the events, both the key and the value are passed to the block.
Example:
server = Pokan::Server.new('10.10.10.8')
server.on :new_key do |key, value|
puts "New key #{key} was inserted with value #{value}!"
end
117 118 119 |
# File 'lib/pokan/server.rb', line 117 def on(event, &block) register_event(event, &block) if ON_EVENTS.include? event end |
#start(options = {}) ⇒ Object
This method starts the server, which will bind specified TCP and UDP ports (or 5555 by default). Optionally, you can pass the address of another pokan instance (a seed), and the server will automatically send a message to the seed and update its data. If no seed information is passed, the server will start with no data and assume it is a seed.
Example:
server = Pokan::Server.new('10.10.10.8')
server.start :gossip_with => '10.10.10.9:5555'
In the example above, the server will try to contact (via TCP) a pokan server running on 10.10.10.9
, port 5555
, and update its data accordingly.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/pokan/server.rb', line 166 def start( = {}) seed = [:gossip_with] if seed.nil? act_as_seed else @seed_address, @seed_port = parse_host_and_port(seed) say_hello(@seed_address, @seed_port) build_trap @event_handler.emit :before_gossip, :with => [@seed_address, [:redis]] sync_with(@seed_address, [:redis]) @event_handler.emit :after_sync, :with => [1] end start_event_loop end |
#stop ⇒ Object
Finishes the server
185 186 187 188 |
# File 'lib/pokan/server.rb', line 185 def stop kill EventMachine.stop end |
#store(key, value, timestamp = Time.now) ⇒ Object
Stores a key, value pair that will be shared among all the peers in the network.
92 93 94 95 96 |
# File 'lib/pokan/server.rb', line 92 def store(key, value, =Time.now) super save @event_handler.emit :new_key, :with => [key, value] end |
#use_epoll ⇒ Object
Call this method if you want to use epoll in your Linux system. Warning: this will not throw an exception nor will warn you if you use this method in a non-Linux machine. You might face errors when you try to start the server, though.
76 77 78 |
# File 'lib/pokan/server.rb', line 76 def use_epoll @epoll = true end |
#using_epoll? ⇒ Boolean
80 81 82 |
# File 'lib/pokan/server.rb', line 80 def using_epoll? @epoll end |