plezi 0.12.14 → 0.12.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/plezi/common/redis.rb +2 -2
- data/lib/plezi/handlers/ws_identity.rb +60 -13
- data/lib/plezi/handlers/ws_object.rb +6 -1
- data/lib/plezi/helpers/http_sender.rb +6 -1
- data/lib/plezi/helpers/mime_types.rb +1 -1
- data/lib/plezi/version.rb +1 -1
- data/plezi.gemspec +1 -1
- data/resources/redis_config.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e2ced994d1b21af157a084e747c60c2fd113a5c
|
4
|
+
data.tar.gz: 6828e742abc6eb612cf70bfbe0c6f2f6da1cac1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7f1d3f579ae87afdf56028e80e093c00ae1f9bd01f155e424c71cb2d846cf418f109c82ee559d21454836345ebe219d614a6af0f11d94e81665fee40856e203
|
7
|
+
data.tar.gz: 23a7279397df8ea1326bfe2da342b5c9c3ab5f85bb3970aae34bbc6c265e01b34392e292a2638e5b48596d720af2a1eb58ae588c624d63324b357c56c01b676f
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,16 @@
|
|
2
2
|
|
3
3
|
***
|
4
4
|
|
5
|
+
Change log v.0.12.15
|
6
|
+
|
7
|
+
**Fix**: fixed the Redis connection, which was failing after DB selection support was added.
|
8
|
+
|
9
|
+
**Fix**: Iodine update fixes an issue where unicasting might fail when connection is still very new.
|
10
|
+
|
11
|
+
**Fixe**: fixed an issue with the Identity API where Redis emulation would loose the historic messages due to unicasting failure for the unregistered (super new) connection.
|
12
|
+
|
13
|
+
***
|
14
|
+
|
5
15
|
Change log v.0.12.14
|
6
16
|
|
7
17
|
**Update**: `Controller#redirect_to` will now attempt to guess the URL using `url_for`, unless the URL given is a String. It also leverages the new `redirect_to` Iodine::Response method, allowing you to set the FUTURE response's status_code.
|
data/lib/plezi/common/redis.rb
CHANGED
@@ -11,11 +11,11 @@ module Plezi
|
|
11
11
|
@redis_locker.synchronize do
|
12
12
|
return @redis if (@redis_sub_thread && @redis_sub_thread.alive?) && @redis # repeat the test once syncing is done.
|
13
13
|
@redis.quit if @redis
|
14
|
-
@redis = ::Redis.new(ENV['PL_REDIS_URL'])
|
14
|
+
@redis = ::Redis.new(url: ENV['PL_REDIS_URL'])
|
15
15
|
raise "Redis connction failed for: #{ENV['PL_REDIS_URL']}" unless @redis
|
16
16
|
@redis_sub_thread = Thread.new do
|
17
17
|
begin
|
18
|
-
::Redis.new(ENV['PL_REDIS_URL']).subscribe(Plezi::Settings.redis_channel_name, Plezi::Settings.uuid) do |on|
|
18
|
+
::Redis.new(url: ENV['PL_REDIS_URL']).subscribe(Plezi::Settings.redis_channel_name, Plezi::Settings.uuid) do |on|
|
19
19
|
on.message do |channel, msg|
|
20
20
|
::Plezi::Base::WSObject.forward_message ::Plezi::Base::WSObject.translate_message(msg)
|
21
21
|
end
|
@@ -39,6 +39,18 @@ module Plezi
|
|
39
39
|
@cache[key].count
|
40
40
|
end
|
41
41
|
end
|
42
|
+
def lpop key
|
43
|
+
sync do
|
44
|
+
@cache[key] ||= []
|
45
|
+
@cache[key].shift
|
46
|
+
end
|
47
|
+
end
|
48
|
+
def lrem key, count, value
|
49
|
+
sync do
|
50
|
+
@cache[key] ||= []
|
51
|
+
@cache[key].delete(value)
|
52
|
+
end
|
53
|
+
end
|
42
54
|
def rpush key, value
|
43
55
|
sync do
|
44
56
|
@cache[key] ||= []
|
@@ -95,8 +107,7 @@ module Plezi
|
|
95
107
|
# @!visibility public
|
96
108
|
# The following method registers the connections as a unique global identity.
|
97
109
|
#
|
98
|
-
#
|
99
|
-
# to be set up. See {Plezi#redis} for more information.
|
110
|
+
# The Identity API works best when a Redis server is used. See {Plezi#redis} for more information.
|
100
111
|
#
|
101
112
|
# By default, only one connection at a time can respond to identity events. If the same identity
|
102
113
|
# connects more than once, only the last connection will receive the notifications.
|
@@ -110,9 +121,19 @@ module Plezi
|
|
110
121
|
# lifetime:: sets how long the identity can survive. defaults to `604_800` seconds (7 days).
|
111
122
|
# max_connections:: sets the amount of concurrent connections an identity can have (akin to open browser tabs receiving notifications). defaults to 1 (a single connection).
|
112
123
|
#
|
124
|
+
# Lifetimes are renewed with each registration and when a connected Identoty receives a notification.
|
125
|
+
# Identities should have a reasonable lifetime. For example, a 10 minutes long lifetime (60*10)
|
126
|
+
# may prove ineffective. When using such short lifetimes, consider the possibility that `unicast` might provide be a better alternative.
|
127
|
+
#
|
128
|
+
# A lifetime cannot (by design) be shorter than 10 minutes.
|
129
|
+
#
|
113
130
|
# Calling this method will also initiate any events waiting in the identity's queue.
|
114
131
|
# make sure that the method is only called once all other initialization is complete.
|
115
132
|
#
|
133
|
+
# i.e.
|
134
|
+
#
|
135
|
+
# register_as session.id, lifetime: 60*60*24, max_connections: 4
|
136
|
+
#
|
116
137
|
# Do NOT call this method asynchronously unless Plezi is set to run as in a single threaded mode - doing so
|
117
138
|
# will execute any pending events outside the scope of the IO's mutex lock, thus introducing race conditions.
|
118
139
|
def register_as identity, options = {}
|
@@ -120,19 +141,21 @@ module Plezi
|
|
120
141
|
options[:max_connections] ||= 1
|
121
142
|
options[:max_connections] = 1 if options[:max_connections].to_i < 1
|
122
143
|
options[:lifetime] ||= 604_800
|
144
|
+
options[:lifetime] = 600 if options[:lifetime].to_i < 600
|
123
145
|
identity = identity.to_s.freeze
|
124
|
-
@___identity ||=
|
125
|
-
@___identity
|
126
|
-
redis.
|
146
|
+
@___identity ||= {}
|
147
|
+
@___identity[identity] = options
|
148
|
+
redis.multi do
|
149
|
+
redis.lpop(identity)
|
150
|
+
redis.lpush(identity, ''.freeze)
|
151
|
+
redis.lrem "#{identity}_uuid".freeze, 0, uuid
|
127
152
|
redis.lpush "#{identity}_uuid".freeze, uuid
|
128
153
|
redis.ltrim "#{identity}_uuid".freeze, 0, (options[:max_connections]-1)
|
129
|
-
end
|
130
|
-
redis.lpush(identity, ''.freeze) unless redis.llen(identity) > 0
|
131
|
-
___review_identity identity
|
132
|
-
redis.pipelined do
|
133
154
|
redis.expire identity, options[:lifetime]
|
134
155
|
redis.expire "#{identity}_uuid".freeze, options[:lifetime]
|
135
156
|
end
|
157
|
+
___review_identity identity
|
158
|
+
identity
|
136
159
|
end
|
137
160
|
|
138
161
|
# @!visibility public
|
@@ -153,21 +176,44 @@ module Plezi
|
|
153
176
|
def ___review_identity identity
|
154
177
|
redis = Plezi.redis || ::Plezi::Base::WSObject::RedisEmultaion
|
155
178
|
identity = identity.to_s.freeze
|
156
|
-
return Iodine.warn("Identity message reached wrong target (ignored).").clear unless @___identity
|
179
|
+
return Iodine.warn("Identity message reached wrong target (ignored).").clear unless @___identity[identity]
|
157
180
|
messages = redis.multi do
|
158
181
|
redis.lrange identity, 1, -1
|
159
182
|
redis.ltrim identity, 0, 0
|
183
|
+
redis.expire identity, @___identity[identity][:lifetime]
|
184
|
+
redis.expire "#{identity}_uuid".freeze, @___identity[identity][:lifetime]
|
160
185
|
end[0]
|
161
186
|
targets = redis.lrange "#{identity}_uuid", 0, -1
|
187
|
+
targets.delete(uuid)
|
162
188
|
while msg = messages.shift
|
163
189
|
msg = ::Plezi::Base::WSObject.translate_message(msg)
|
164
190
|
next unless msg
|
165
191
|
Iodine.error("Notification recieved but no method can handle it - dump:\r\n #{msg.to_s}") && next unless self.class.has_super_method?(msg[:method])
|
166
|
-
|
167
|
-
|
168
|
-
|
192
|
+
Iodine.run do
|
193
|
+
targets.each {|target| unicast(target, msg[:method], *msg[:data]) }
|
194
|
+
end
|
195
|
+
self.method(msg[:method]).call(*msg[:data])
|
169
196
|
end
|
197
|
+
# ___extend_lifetime identity
|
170
198
|
end
|
199
|
+
|
200
|
+
# # re-registers the Identity, extending it's lifetime
|
201
|
+
# # and making sure it's still valid.
|
202
|
+
# def ___extend_lifetime identity
|
203
|
+
# return unless @___identity
|
204
|
+
# redis = Plezi.redis || ::Plezi::Base::WSObject::RedisEmultaion
|
205
|
+
# options = @___identity[identity]
|
206
|
+
# return unless options
|
207
|
+
# redis.multi do
|
208
|
+
# # redis.lpop(identity)
|
209
|
+
# # redis.lpush(identity, ''.freeze)
|
210
|
+
# # redis.lrem "#{identity}_uuid".freeze, 0, uuid
|
211
|
+
# # redis.lpush "#{identity}_uuid".freeze, uuid
|
212
|
+
# # redis.ltrim "#{identity}_uuid".freeze, 0, (options[:max_connections]-1)
|
213
|
+
# redis.expire identity, options[:lifetime]
|
214
|
+
# redis.expire "#{identity}_uuid".freeze, options[:lifetime]
|
215
|
+
# end
|
216
|
+
# end
|
171
217
|
end
|
172
218
|
|
173
219
|
module SuperClassMethods
|
@@ -180,6 +226,7 @@ module Plezi
|
|
180
226
|
return false unless redis.llen(identity).to_i > 0
|
181
227
|
redis.rpush identity, ({method: event_name, data: args}).to_yaml
|
182
228
|
redis.lrange("#{identity}_uuid".freeze, 0, -1).each {|target| unicast target, :___review_identity, identity }
|
229
|
+
# puts "pushed notification #{event_name}"
|
183
230
|
true
|
184
231
|
end
|
185
232
|
|
@@ -97,16 +97,19 @@ module Plezi
|
|
97
97
|
|
98
98
|
protected
|
99
99
|
|
100
|
+
# @!visibility public
|
100
101
|
# allows writing of data to the websocket (if opened). Otherwise appends the message to the Http response.
|
101
102
|
def write data
|
102
103
|
(@ws_io || @response) << data
|
103
104
|
end
|
104
105
|
|
106
|
+
# @!visibility public
|
105
107
|
# Performs a websocket unicast to the specified target.
|
106
108
|
def unicast target_uuid, method_name, *args
|
107
109
|
self.class.unicast target_uuid, method_name, *args
|
108
110
|
end
|
109
111
|
|
112
|
+
# @!visibility public
|
110
113
|
# Use this to brodcast an event to all 'sibling' objects (websockets that have been created using the same Controller class).
|
111
114
|
#
|
112
115
|
# Accepts:
|
@@ -119,6 +122,8 @@ module Plezi
|
|
119
122
|
return false unless self.class.has_method? method_name
|
120
123
|
self.class._inner_broadcast({ method: method_name, data: args, type: self.class}, __get_io )
|
121
124
|
end
|
125
|
+
|
126
|
+
# @!visibility public
|
122
127
|
# Use this to multicast an event to ALL websocket connections on EVERY controller, including Placebo controllers.
|
123
128
|
#
|
124
129
|
# Accepts:
|
@@ -238,7 +243,7 @@ module Plezi
|
|
238
243
|
# sends the broadcast
|
239
244
|
def _inner_broadcast data, ignore_io = nil
|
240
245
|
if data[:target]
|
241
|
-
if data[:
|
246
|
+
if data[:to_server] == Plezi::Settings.uuid
|
242
247
|
return ( ::Iodine::Http::Websockets.unicast( data[:target], data ) || ___faild_unicast( data ) )
|
243
248
|
end
|
244
249
|
return ( data[:to_server].nil? && ::Iodine::Http::Websockets.unicast(data[:target], data) ) || ( Plezi::Base::AutoRedis.away?(data[:to_server]) && ___faild_unicast( data ) ) || __inner_redis_broadcast(data)
|
@@ -1,9 +1,14 @@
|
|
1
1
|
module Plezi
|
2
2
|
module Base
|
3
3
|
|
4
|
+
|
4
5
|
# Sends common basic HTTP responses.
|
5
6
|
module HTTPSender
|
6
|
-
class
|
7
|
+
# makes sure to methods are injected to class Class
|
8
|
+
class Container
|
9
|
+
end
|
10
|
+
# the Error Controller, for rendering error templates.
|
11
|
+
class ErrorCtrl < Container
|
7
12
|
include ::Plezi::Base::ControllerCore
|
8
13
|
include ::Plezi::ControllerMagic
|
9
14
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Plezi
|
2
2
|
# This module holds the mime dictionary.
|
3
3
|
module MimeTypeHelper
|
4
|
-
# thank you Apache group (and many more), for compiling mime-type
|
4
|
+
# thank you Apache group (and many more), for compiling mime-type lists for me to search through.
|
5
5
|
MIME_DICTIONARY = { ".123"=>"application/vnd.lotus-1-2-3".freeze,
|
6
6
|
".3dml"=>"text/vnd.in3d.3dml".freeze,
|
7
7
|
".3ds"=>"image/x-3ds".freeze,
|
data/lib/plezi/version.rb
CHANGED
data/plezi.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_dependency "iodine", "~> 0.1.
|
21
|
+
spec.add_dependency "iodine", "~> 0.1.15"
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.7"
|
23
23
|
spec.add_development_dependency "rake", "~> 10.0"
|
24
24
|
|
data/resources/redis_config.rb
CHANGED
@@ -29,7 +29,7 @@ if defined? Redis
|
|
29
29
|
# ## the following is only sample code for you to change:
|
30
30
|
# RADIS_CHANNEL = 'appsecret'
|
31
31
|
# RADIS_URI = ENV['REDIS_URL'] || ENV['REDISCLOUD_URL'] || "redis://:password@my.host:6389/0"
|
32
|
-
# RADIS_CONNECTION = Redis.new(RADIS_URI)
|
32
|
+
# RADIS_CONNECTION = Redis.new(url: RADIS_URI)
|
33
33
|
# RADIS_THREAD = Thread.new do
|
34
34
|
# Redis.new(RADIS_URI).subscribe(RADIS_CHANNEL) do |on|
|
35
35
|
# on.message do |channel, msg|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plezi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
4
|
+
version: 0.12.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Boaz Segev
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.1.
|
19
|
+
version: 0.1.15
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.1.
|
26
|
+
version: 0.1.15
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|