board-linuxfr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "board-linuxfr"
@@ -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
@@ -0,0 +1,3 @@
1
+ class BoardLinuxfr
2
+ VERSION = "0.0.1"
3
+ 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: []