-
Notifications
You must be signed in to change notification settings - Fork 0
/
collabhub.rb
76 lines (61 loc) · 1.46 KB
/
collabhub.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
require 'rubygems'
require 'sinatra'
require 'environment'
class CollabHub < Sinatra::Base
register Sinatra::Async
set :app_file, __FILE__
enable :static
PushTimeout = 0.05
get '/' do
@messages = datastore.query
erb :index
end
aget '/grab' do
message_buffer = []
timer = nil
sid = channel.subscribe { |message|
message_buffer << message
timer ||= EM::Timer.new(PushTimeout) {
json_response = {}
json_response[:messages] = []
message_buffer.each do |message|
json_response[:messages] << { :id => message_buffer.index(message), :body => message, :created_at => Time.now }
end
json = json_response.to_json
body json
}
}
closer = lambda {
channel.unsubscribe sid
timer.cancel if timer
}
d = env['async.close']
d.callback &closer
d.errback &closer
end
post '/post' do
m = params[:msg]
return if m.nil? || m.empty?
datastore[ datastore.genuid.to_s ] = { 'body' => m }
channel << m
nil
end
# EventMachine Channel
def self.channel
@channel ||= EM::Channel.new
end
def channel
self.class.channel
end
# Tokyo Tyrant Table DataStore
def self.datastore
if TyrantHost && TyrantPort && UseTokyo
@datastore ||= Rufus::Tokyo::TyrantTable.new( TyrantHost, TyrantPort )
else
@datastore ||= FakeDataStore.new
end
end
def datastore
self.class.datastore
end
end