plezi 0.12.14 → 0.12.15
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.
- 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
|