board-linuxfr 0.0.1
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.
- data/bin/board-linuxfr +3 -0
- data/lib/board-linuxfr.rb +33 -0
- data/lib/board-linuxfr/cache.rb +35 -0
- data/lib/board-linuxfr/redis_plugin.rb +40 -0
- data/lib/board-linuxfr/version.rb +3 -0
- metadata +105 -0
data/bin/board-linuxfr
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "goliath"
|
2
|
+
require "yajl"
|
3
|
+
|
4
|
+
|
5
|
+
class BoardLinuxfr < Goliath::API
|
6
|
+
autoload :Cache, "board-linuxfr/cache"
|
7
|
+
autoload :RedisPlugin, "board-linuxfr/redis_plugin"
|
8
|
+
autoload :VERSION, "board-linuxfr/version"
|
9
|
+
|
10
|
+
plugin RedisPlugin
|
11
|
+
|
12
|
+
def response(env)
|
13
|
+
env.logger.info "New client: #{env['PATH_INFO']}"
|
14
|
+
send_msg = ->(args) {
|
15
|
+
id, msg = *args
|
16
|
+
env.logger.debug " -> #{id}. #{msg}"
|
17
|
+
env.stream_send("data: #{args.last}\nid: #{args.first}\n\n")
|
18
|
+
}
|
19
|
+
event_id = env['HTTP_LAST_EVENT_ID']
|
20
|
+
chan_name = env['PATH_INFO'].split('/', 3).last
|
21
|
+
env['cache'] = status[:cache][chan_name]
|
22
|
+
env['chan'] = status[:channels][chan_name]
|
23
|
+
env['sid'] = env['chan'].subscribe &send_msg
|
24
|
+
env['timer'] = EM.add_periodic_timer(15) { env.stream_send "::\n\n" }
|
25
|
+
EM.next_tick { env['cache'].from(event_id, &send_msg) } if event_id
|
26
|
+
streaming_response(200, {'Content-Type' => 'text/event-stream'})
|
27
|
+
end
|
28
|
+
|
29
|
+
def on_close(env)
|
30
|
+
env['chan'].unsubscribe env['sid'] if env['sid']
|
31
|
+
env['timer'].cancel if env['timer']
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class BoardLinuxfr
|
2
|
+
class Cache
|
3
|
+
CAPACITY = 10
|
4
|
+
|
5
|
+
class Entry < Array
|
6
|
+
def push(item)
|
7
|
+
super item
|
8
|
+
shift if size > CAPACITY
|
9
|
+
end
|
10
|
+
|
11
|
+
def from(id, &blk)
|
12
|
+
found = false
|
13
|
+
each do |item|
|
14
|
+
blk.call item if found
|
15
|
+
found ||= item[:id] == id
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
@keys = Entry.new
|
22
|
+
@vals = Entry.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](key)
|
26
|
+
n = @keys.index(key)
|
27
|
+
unless n
|
28
|
+
@keys.push key
|
29
|
+
@vals.push Entry.new
|
30
|
+
n = @keys.length - 1
|
31
|
+
end
|
32
|
+
@vals[n]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "hiredis"
|
2
|
+
require "em-synchrony"
|
3
|
+
require "redis"
|
4
|
+
require "redis/connection/synchrony"
|
5
|
+
require "board-linuxfr/cache"
|
6
|
+
|
7
|
+
|
8
|
+
class BoardLinuxfr
|
9
|
+
class RedisPlugin
|
10
|
+
def initialize(port, config, status, logger)
|
11
|
+
logger.info "Initializing the Redis plugin"
|
12
|
+
@logger = logger
|
13
|
+
@chans = status[:channels] = Hash.new { |h,k| h[k] = EM::Channel.new }
|
14
|
+
@cache = status[:cache] = Cache.new
|
15
|
+
@redis = Redis.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
EM.synchrony do
|
20
|
+
@redis.psubscribe("b/*") do |on|
|
21
|
+
on.psubscribe do |pattern, total|
|
22
|
+
@logger.info "Psubscribe to redis: #{pattern} (#{total})"
|
23
|
+
end
|
24
|
+
|
25
|
+
on.pmessage do |pattern, chan, msg|
|
26
|
+
_, chan, id = *chan.split('/')
|
27
|
+
@logger.info "New message: [#{chan.inspect}] #{id}. #{msg}"
|
28
|
+
[@chans, @cache].each do |storage|
|
29
|
+
storage[chan].push [id, msg]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
on.punsubscribe do |pattern, total|
|
34
|
+
@logger.info "Punsubscribe to redis: #{pattern} (#{total})"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: board-linuxfr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bruno Michel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-10 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: goliath
|
16
|
+
requirement: &90778890 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.9'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *90778890
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hiredis
|
27
|
+
requirement: &90778470 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.3'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *90778470
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: redis
|
38
|
+
requirement: &90778010 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.2'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *90778010
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: yajl-ruby
|
49
|
+
requirement: &90777520 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *90777520
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: minitest
|
60
|
+
requirement: &90777100 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '2.3'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *90777100
|
69
|
+
description: Push notifications for the board of LinuxFr.org via Server-Sent Events
|
70
|
+
email: nono@linuxfr.org
|
71
|
+
executables:
|
72
|
+
- board-linuxfr
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- bin/board-linuxfr
|
77
|
+
- lib/board-linuxfr.rb
|
78
|
+
- lib/board-linuxfr/cache.rb
|
79
|
+
- lib/board-linuxfr/redis_plugin.rb
|
80
|
+
- lib/board-linuxfr/version.rb
|
81
|
+
homepage: https://github.com/nono/board-sse-linuxfr.org
|
82
|
+
licenses: []
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.8.10
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Push notifications for the board of LinuxFr.org via Server-Sent Events
|
105
|
+
test_files: []
|