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
:syncevent. -
#before(event, &block) ⇒ Object
Adds behaviour before a given event occurs.
-
#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 -
epollwill 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 |
# File 'lib/pokan/server.rb', line 62 def initialize(address) @event_handler = EventHandler.new @seed_address, @seed_port = '', '' 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).
132 133 134 135 |
# File 'lib/pokan/server.rb', line 132 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.
123 124 125 126 |
# File 'lib/pokan/server.rb', line 123 def before(event, &block) event_name = prepend('before_', event) register_event(event_name, &block) if BEFORE_EVENTS.include? event 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.
85 86 87 |
# File 'lib/pokan/server.rb', line 85 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
116 117 118 |
# File 'lib/pokan/server.rb', line 116 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.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/pokan/server.rb', line 152 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
171 172 173 174 |
# File 'lib/pokan/server.rb', line 171 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.
91 92 93 94 95 |
# File 'lib/pokan/server.rb', line 91 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.
75 76 77 |
# File 'lib/pokan/server.rb', line 75 def use_epoll @epoll = true end |
#using_epoll? ⇒ Boolean
79 80 81 |
# File 'lib/pokan/server.rb', line 79 def using_epoll? @epoll end |