faye_tracking 0.2.1 → 0.2.2
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/README.md +8 -2
- data/lib/faye_tracking.rb +17 -23
- data/lib/faye_tracking/faye_extension.rb +4 -2
- data/lib/faye_tracking/store/adapter/namespaced_key_list.rb +40 -0
- data/lib/faye_tracking/tracker.rb +44 -21
- data/lib/faye_tracking/version.rb +1 -1
- data/spec/faye_tracking_spec.rb +35 -16
- metadata +3 -4
- data/lib/faye_tracking/store/abstract_mapping.rb +0 -15
- data/lib/faye_tracking/store/adapter/redis_mapping.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59510a6d0b8840e8d1a023e7688cce9e7dcba4b2
|
4
|
+
data.tar.gz: a2eccf51d9d9ae29d31154ac8debffba9368cdc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98eceda9db22c158a7d46ce1b8998a68b6462304af15ff2a6d61535fee17993666d475d32f16446d97d45680a831c7222cc6023b59556df886addd34a77ffbe3
|
7
|
+
data.tar.gz: be8768b99523474637524d1e24fff8ad4c3e9dd2c05e9dfdf650715d6910db308fe78aa19687b3da910f7ece8055c34194718441eb68f80a5ad2457e3fddedc5
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ end
|
|
37
37
|
|
38
38
|
client.add_extension(FayeTracking.faye_extension)
|
39
39
|
|
40
|
-
FayeTracking.
|
40
|
+
FayeTracking.users_in_channel('/chat/1')
|
41
41
|
FayeTracking.user_in_any_channel?('/user_1')
|
42
42
|
FayeTracking.user_in_channel?('/user_1', '/chat/1')
|
43
43
|
```
|
@@ -54,7 +54,7 @@ FayeTrackingExtension =
|
|
54
54
|
message.ext.faye_tracking_client_id = subscription.user_id
|
55
55
|
callback(message)
|
56
56
|
|
57
|
-
PrivatePub.extensions = [
|
57
|
+
PrivatePub.extensions = [FayeTrackingExtension]
|
58
58
|
|
59
59
|
# To subscribe to a channel
|
60
60
|
subscription["user_id"] = user_id
|
@@ -62,6 +62,12 @@ PrivatePub.sign(subscription)
|
|
62
62
|
PrivatePub.subscribe(subscription.channel, callback)
|
63
63
|
```
|
64
64
|
|
65
|
+
## TODO
|
66
|
+
|
67
|
+
* <del>Allow one application user to have many Faye `clientId` mappings.</del>
|
68
|
+
* Rely on events (instead of extensions) to handle user disconnecting event
|
69
|
+
because it's more reliable. (see http://faye.jcoglan.com/ruby/monitoring.html)
|
70
|
+
|
65
71
|
## Contributing
|
66
72
|
|
67
73
|
1. Fork it ( https://github.com/he9lin/faye_tracking/fork )
|
data/lib/faye_tracking.rb
CHANGED
@@ -4,24 +4,14 @@ require 'logger'
|
|
4
4
|
require "faye_tracking/version"
|
5
5
|
|
6
6
|
module FayeTracking
|
7
|
-
MAPPING_STORE_NAME = 'client_id_to_user'.freeze
|
8
|
-
|
9
7
|
class << self
|
10
|
-
attr_accessor :
|
8
|
+
attr_accessor :logger
|
9
|
+
attr_writer :redis
|
11
10
|
|
12
11
|
def configure(&block)
|
13
12
|
block.call(self)
|
14
13
|
end
|
15
14
|
|
16
|
-
def reset_store
|
17
|
-
raise 'redis is not set' unless redis
|
18
|
-
redis.keys('*').each {|k| redis.del k}
|
19
|
-
end
|
20
|
-
|
21
|
-
def faye_extension
|
22
|
-
@_faye_extension ||= FayeExtension.new(tracker)
|
23
|
-
end
|
24
|
-
|
25
15
|
def user_in_any_channel?(user)
|
26
16
|
!tracker.channels_for_user(user).empty?
|
27
17
|
end
|
@@ -30,30 +20,34 @@ module FayeTracking
|
|
30
20
|
tracker.user_in_channel?(user, channel)
|
31
21
|
end
|
32
22
|
|
33
|
-
def
|
23
|
+
def users_in_channel(channel)
|
34
24
|
tracker.users_in_channel(channel)
|
35
25
|
end
|
36
26
|
|
27
|
+
def reset_store
|
28
|
+
redis.keys('*').each {|k| redis.del k}
|
29
|
+
end
|
30
|
+
|
31
|
+
def faye_extension
|
32
|
+
@_faye_extension ||= FayeExtension.new(tracker)
|
33
|
+
end
|
34
|
+
|
37
35
|
def logger
|
38
36
|
@logger ||= Logger.new(STDOUT)
|
39
37
|
end
|
40
38
|
|
41
|
-
|
39
|
+
def redis
|
40
|
+
@redis || raise('redis is not set')
|
41
|
+
end
|
42
42
|
|
43
43
|
def tracker
|
44
|
-
|
45
|
-
@_tracker ||= begin
|
46
|
-
key_list_store = RedisKeyList.new(redis)
|
47
|
-
mapping_store = RedisMapping.new(redis)
|
48
|
-
Tracker.new(key_list_store, mapping_store)
|
49
|
-
end
|
44
|
+
@_tracker = Tracker.new(redis)
|
50
45
|
end
|
51
46
|
end
|
52
47
|
end
|
53
48
|
|
54
49
|
require "faye_tracking/faye_extension"
|
50
|
+
require "faye_tracking/tracker"
|
55
51
|
require "faye_tracking/store/abstract_key_list"
|
56
|
-
require "faye_tracking/store/abstract_mapping"
|
57
52
|
require "faye_tracking/store/adapter/redis_key_list"
|
58
|
-
require "faye_tracking/store/adapter/
|
59
|
-
require "faye_tracking/tracker"
|
53
|
+
require "faye_tracking/store/adapter/namespaced_key_list"
|
@@ -21,12 +21,14 @@ module FayeTracking
|
|
21
21
|
if app_client_id = ext['faye_tracking_client_id']
|
22
22
|
@tracker.add(subs_channel, client_id, app_client_id)
|
23
23
|
else
|
24
|
-
|
24
|
+
error_message = "missing ext['faye_tracking_client_id']"
|
25
|
+
FayeTracking.logger.debug "error with message: #{error_message}"
|
26
|
+
message['error'] = error_message
|
25
27
|
end
|
26
28
|
when '/meta/unsubscribe'
|
27
29
|
@tracker.remove(subs_channel, client_id)
|
28
30
|
when '/meta/disconnect'
|
29
|
-
@tracker.
|
31
|
+
@tracker.remove_all(client_id)
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module FayeTracking
|
2
|
+
class NamespacedKeyList < AbstractKeyList
|
3
|
+
def initialize(ns, key_list)
|
4
|
+
raise ArgumentError, 'namespace param cannot be blank' if ns.nil? || ns.empty?
|
5
|
+
|
6
|
+
@ns = ns
|
7
|
+
@key_list = key_list
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(key, value)
|
11
|
+
@key_list.add build_key(key), value
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove(key, value)
|
15
|
+
@key_list.remove build_key(key), value
|
16
|
+
end
|
17
|
+
|
18
|
+
def member?(key, value)
|
19
|
+
@key_list.member? build_key(key), value
|
20
|
+
end
|
21
|
+
|
22
|
+
def members(key)
|
23
|
+
@key_list.members build_key(key)
|
24
|
+
end
|
25
|
+
|
26
|
+
def empty?(key)
|
27
|
+
@key_list.empty? build_key(key)
|
28
|
+
end
|
29
|
+
|
30
|
+
def remove_all(key)
|
31
|
+
@key_list.remove_all build_key(key)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def build_key(key)
|
37
|
+
[@ns, key].join(':')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,48 +1,71 @@
|
|
1
1
|
module FayeTracking
|
2
2
|
class Tracker
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
-
@
|
3
|
+
def initialize(redis)
|
4
|
+
@channel_to_client_ids = namespaced_key_list('channel_to_client_ids', redis)
|
5
|
+
@client_id_to_channels = namespaced_key_list('client_id_to_channels', redis)
|
6
|
+
@user_to_client_ids = namespaced_key_list('user_to_client_ids', redis)
|
7
|
+
@client_id_to_users = namespaced_key_list('client_id_to_users', redis)
|
6
8
|
end
|
7
9
|
|
8
10
|
def add(channel, client_id, user)
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
11
|
+
@channel_to_client_ids.add(channel, client_id)
|
12
|
+
@client_id_to_channels.add(client_id, channel)
|
13
|
+
@user_to_client_ids.add(user, client_id)
|
14
|
+
@client_id_to_users.add(client_id, user)
|
12
15
|
end
|
13
16
|
|
14
17
|
def remove(channel, client_id)
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
@channel_to_client_ids.remove(channel, client_id)
|
19
|
+
@client_id_to_channels.remove(client_id, channel)
|
20
|
+
@client_id_to_users.members(client_id).each do |user|
|
21
|
+
@user_to_client_ids.remove(user, client_id)
|
18
22
|
end
|
19
|
-
@
|
23
|
+
@client_id_to_users.remove_all(client_id)
|
20
24
|
end
|
21
25
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
@key_list.remove(channel, user)
|
26
|
-
end
|
27
|
-
@key_list.remove_all(user)
|
26
|
+
def remove_all(client_id)
|
27
|
+
@client_id_to_channels.members(client_id).each do |channel|
|
28
|
+
@channel_to_client_ids.remove(channel, client_id)
|
28
29
|
end
|
29
|
-
@
|
30
|
+
@client_id_to_users.members(client_id).each do |user|
|
31
|
+
@user_to_client_ids.remove(user, client_id)
|
32
|
+
end
|
33
|
+
@client_id_to_users.remove_all(client_id)
|
34
|
+
@client_id_to_channels.remove_all(client_id)
|
30
35
|
end
|
31
36
|
|
32
37
|
def channels_for_user(user)
|
33
|
-
@
|
38
|
+
client_ids = @user_to_client_ids.members(user)
|
39
|
+
client_ids.inject([]) do |acc, client_id|
|
40
|
+
acc += @client_id_to_channels.members(client_id)
|
41
|
+
end.uniq
|
34
42
|
end
|
35
43
|
|
36
44
|
def users_in_channel(channel)
|
37
|
-
@
|
45
|
+
client_ids = @channel_to_client_ids.members(channel)
|
46
|
+
client_ids.inject([]) do |acc, client_id|
|
47
|
+
acc += @client_id_to_users.members(client_id)
|
48
|
+
end.uniq
|
38
49
|
end
|
39
50
|
|
40
51
|
def user_in_channel?(user, channel)
|
41
|
-
@
|
52
|
+
client_ids = @user_to_client_ids.members(user)
|
53
|
+
client_ids.any? do |client_id|
|
54
|
+
@channel_to_client_ids.member? channel, client_id
|
55
|
+
end
|
42
56
|
end
|
43
57
|
|
44
58
|
def channel_has_user?(channel, user)
|
45
|
-
@
|
59
|
+
client_ids = @channel_to_client_ids.members(channel)
|
60
|
+
client_ids.any? do |client_id|
|
61
|
+
@user_to_client_ids.member? user, client_id
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def namespaced_key_list(name, redis)
|
68
|
+
NamespacedKeyList.new(name, RedisKeyList.new(redis))
|
46
69
|
end
|
47
70
|
end
|
48
71
|
end
|
data/spec/faye_tracking_spec.rb
CHANGED
@@ -28,20 +28,22 @@ describe FayeTracking do
|
|
28
28
|
faye_run('/meta/disconnect', nil, client_id, nil)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
31
|
+
describe 'subscribing to a channel' do
|
32
|
+
describe 'multiple users' do
|
33
|
+
before do
|
34
|
+
faye_subscribe 'room', client_id, 'user_1'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'adds user to the subscription channel' do
|
38
|
+
expect(described_class.user_in_any_channel?('user_1')).to be_truthy
|
39
|
+
expect(described_class.user_in_channel?('user_1', 'room')).to be_truthy
|
40
|
+
expect(described_class.user_in_channel?('user_2', 'room')).to be_falsey
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'returns all users in a channel' do
|
44
|
+
faye_subscribe 'room', client_id, 'user_2'
|
45
|
+
expect(described_class.users_in_channel('room')).to match_array(['user_1', 'user_2'])
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
@@ -53,7 +55,7 @@ describe FayeTracking do
|
|
53
55
|
it 'removes a user from a subscription channel' do
|
54
56
|
faye_unsubscribe 'room', client_id
|
55
57
|
expect(described_class.user_in_any_channel?('user_1')).to be_falsey
|
56
|
-
expect(described_class.
|
58
|
+
expect(described_class.users_in_channel('rooom')).to eq([])
|
57
59
|
|
58
60
|
faye_subscribe 'room', client_id, 'user_2'
|
59
61
|
expect(described_class.user_in_any_channel?('user_2')).to be_truthy
|
@@ -66,6 +68,23 @@ describe FayeTracking do
|
|
66
68
|
end
|
67
69
|
end
|
68
70
|
|
71
|
+
describe 'subscribing/unsubscribing same users with different clientIds' do
|
72
|
+
before do
|
73
|
+
faye_subscribe 'room', client_id, 'user_1'
|
74
|
+
faye_subscribe 'room', another_client_id, 'user_1'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'user able to have multiple client ids' do
|
78
|
+
expect(described_class.user_in_channel?('user_1', 'room')).to be_truthy
|
79
|
+
|
80
|
+
faye_unsubscribe 'room', client_id
|
81
|
+
expect(described_class.user_in_channel?('user_1', 'room')).to be_truthy
|
82
|
+
|
83
|
+
faye_unsubscribe 'room', another_client_id
|
84
|
+
expect(described_class.user_in_channel?('user_1', 'room')).to be_falsey
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
69
88
|
context 'disconnecting' do
|
70
89
|
before do
|
71
90
|
faye_subscribe 'room1', client_id, 'user_1'
|
@@ -76,7 +95,7 @@ describe FayeTracking do
|
|
76
95
|
it 'removes the user from all channels' do
|
77
96
|
faye_disconnect(client_id)
|
78
97
|
expect(described_class.user_in_any_channel?('user_1')).to be_falsey
|
79
|
-
expect(described_class.
|
98
|
+
expect(described_class.users_in_channel('room1')).to eq(['user_2'])
|
80
99
|
end
|
81
100
|
end
|
82
101
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faye_tracking
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lin He
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -97,9 +97,8 @@ files:
|
|
97
97
|
- lib/faye_tracking.rb
|
98
98
|
- lib/faye_tracking/faye_extension.rb
|
99
99
|
- lib/faye_tracking/store/abstract_key_list.rb
|
100
|
-
- lib/faye_tracking/store/
|
100
|
+
- lib/faye_tracking/store/adapter/namespaced_key_list.rb
|
101
101
|
- lib/faye_tracking/store/adapter/redis_key_list.rb
|
102
|
-
- lib/faye_tracking/store/adapter/redis_mapping.rb
|
103
102
|
- lib/faye_tracking/tracker.rb
|
104
103
|
- lib/faye_tracking/version.rb
|
105
104
|
- spec/faye_tracking_spec.rb
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module FayeTracking
|
2
|
-
class RedisMapping < AbstractMapping
|
3
|
-
def initialize(redis, name=FayeTracking::MAPPING_STORE_NAME)
|
4
|
-
@name = name
|
5
|
-
@redis = redis
|
6
|
-
end
|
7
|
-
|
8
|
-
def set(key, value)
|
9
|
-
@redis.hset @name, key, value
|
10
|
-
end
|
11
|
-
|
12
|
-
def get(key)
|
13
|
-
@redis.hget @name, key
|
14
|
-
end
|
15
|
-
|
16
|
-
def delete(key)
|
17
|
-
@redis.del @name, key
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|