ddp-server-rethinkdb 0.0.2 → 0.0.3
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/ddp-server-rethinkdb.gemspec +1 -1
- data/lib/ddp/server/rethinkdb.rb +7 -117
- data/lib/ddp/server/rethinkdb/api.rb +75 -0
- data/lib/ddp/server/rethinkdb/subscription.rb +30 -0
- data/lib/ddp/server/rethinkdb/version.rb +1 -1
- data/lib/ddp/server/rethinkdb/websocket.rb +53 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6388cf68529ae0dd89d4f7ffb09d991ddf3e461e
|
4
|
+
data.tar.gz: fa6e9aa686e7776246ae5f22888855a49fa50274
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4a140f59e7926c624ed8c367dee381ff2f79a0fe0083e3216c0e4dc799c09b03c1f1b082f906347f71a4589928d7d26e2bdeb4a8e3a2aad74bf671632a7617b
|
7
|
+
data.tar.gz: 0afc8680402b614d8c25210802a50995bf7f0f91eabc1ee7d49ba87ac1b5839c911f913c49babda6a6af697b274eff027be2aa99d5a3555431d43f62cb0d2a41
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
|
24
|
-
spec.add_dependency 'ddp-server', '>= 0.0.
|
24
|
+
spec.add_dependency 'ddp-server', '>= 0.0.4'
|
25
25
|
spec.add_dependency 'rethinkdb'
|
26
26
|
spec.add_dependency 'connection_pool'
|
27
27
|
end
|
data/lib/ddp/server/rethinkdb.rb
CHANGED
@@ -1,126 +1,16 @@
|
|
1
|
-
require 'ddp/server'
|
2
|
-
require 'ddp/server/rethinkdb/version'
|
3
1
|
require 'rethinkdb'
|
4
2
|
require 'connection_pool'
|
3
|
+
require 'celluloid'
|
4
|
+
require 'ddp/server'
|
5
|
+
require 'ddp/server/rethinkdb'
|
6
|
+
require 'ddp/server/rethinkdb/api'
|
7
|
+
require 'ddp/server/rethinkdb/subscription'
|
8
|
+
require 'ddp/server/rethinkdb/websocket'
|
5
9
|
|
6
10
|
module DDP
|
7
11
|
module Server
|
8
|
-
# A RethinkDB DDP Server
|
12
|
+
# A RethinkDB DDP Server implementation
|
9
13
|
module RethinkDB
|
10
|
-
# Implementation of the WebSocket DDP::Server
|
11
|
-
class WebSocket < DDP::Server::WebSocket
|
12
|
-
include Celluloid::Logger
|
13
|
-
|
14
|
-
attr_reader :api
|
15
|
-
|
16
|
-
def self.rack(api, config, pool_config = {})
|
17
|
-
super(pool_config.merge(args: [api, config]))
|
18
|
-
end
|
19
|
-
|
20
|
-
def initialize(api_class, config)
|
21
|
-
collections_module = api_class.const_get :Collections
|
22
|
-
rpc_module = api_class.const_get :RPC
|
23
|
-
@collections = collections_module.instance_methods.map(&:to_s)
|
24
|
-
@rpc_methods = rpc_module.instance_methods.map(&:to_s)
|
25
|
-
@api = api_class.new(config)
|
26
|
-
@api.singleton_class.include collections_module
|
27
|
-
@api.singleton_class.include rpc_module
|
28
|
-
@subscriptions = {}
|
29
|
-
end
|
30
|
-
|
31
|
-
def handle_sub(id, name, params)
|
32
|
-
params ||= []
|
33
|
-
return send_nosub(id, error: 'No such collection') unless @collections.include? name
|
34
|
-
query = api.send(name, *params)
|
35
|
-
@subscriptions[id] = Subscription.new(self, id, name, query)
|
36
|
-
end
|
37
|
-
|
38
|
-
def subscription_update(id, change)
|
39
|
-
subscription_name = @subscriptions[id].name
|
40
|
-
old_value = change['old_val']
|
41
|
-
new_value = change['new_val']
|
42
|
-
|
43
|
-
return send_added(subscription_name, new_value['id'], new_value) if old_value.nil?
|
44
|
-
return send_removed(subscription_name, old_value['id']) if new_value.nil?
|
45
|
-
|
46
|
-
cleared = old_value.keys.reject { |key| new_value.include? key }
|
47
|
-
send_changed(subscription.name, old_value['id'], new_value, cleared)
|
48
|
-
end
|
49
|
-
|
50
|
-
def handle_unsub(id)
|
51
|
-
subscription = @subscriptions.delete(id)
|
52
|
-
subscription.stop unless subscription.nil?
|
53
|
-
send_nosub(id)
|
54
|
-
end
|
55
|
-
|
56
|
-
def handle_method(id, method, params)
|
57
|
-
params ||= []
|
58
|
-
raise 'No such method' unless @rpc_methods.include? method
|
59
|
-
result = @api.send(method, *params)
|
60
|
-
send_result(id, result)
|
61
|
-
rescue => e
|
62
|
-
send_error_result(id, e)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# Helper class that users can extend to implement an API that can be passed
|
67
|
-
# as the RPC API parameter to the RethinkDB DDP protocol
|
68
|
-
class API
|
69
|
-
def initialize(config)
|
70
|
-
@connection_pool = ConnectionPool.new(
|
71
|
-
size: config[:connection_pool_size],
|
72
|
-
timeout: config[:connection_pool_timeout]
|
73
|
-
) do
|
74
|
-
::RethinkDB::Connection.new(
|
75
|
-
host: config[:host],
|
76
|
-
port: config[:port]
|
77
|
-
)
|
78
|
-
end
|
79
|
-
@database_name = config[:database]
|
80
|
-
end
|
81
|
-
|
82
|
-
def database
|
83
|
-
::RethinkDB::RQL.new.db(@database_name)
|
84
|
-
end
|
85
|
-
|
86
|
-
def table(name)
|
87
|
-
database.table(name)
|
88
|
-
end
|
89
|
-
|
90
|
-
def with_connection
|
91
|
-
@connection_pool.with do |conn|
|
92
|
-
yield conn
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
# Actor that asynchronously monitors a collection
|
98
|
-
class Subscription
|
99
|
-
include Celluloid
|
100
|
-
include Celluloid::Logger
|
101
|
-
|
102
|
-
attr_reader :name, :stopped
|
103
|
-
alias_method :stopped?, :stopped
|
104
|
-
|
105
|
-
def initialize(listener, id, name, query)
|
106
|
-
@stopped = false
|
107
|
-
@name = name
|
108
|
-
async.read_loop(listener, query, id)
|
109
|
-
end
|
110
|
-
|
111
|
-
def read_loop(listener, query, id)
|
112
|
-
listener.api.with_connection do |conn|
|
113
|
-
query.changes.run(conn).each do |change|
|
114
|
-
listener.subscription_update(id, change)
|
115
|
-
break if stopped?
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def stop
|
121
|
-
@stopped = true
|
122
|
-
end
|
123
|
-
end
|
124
14
|
end
|
125
15
|
end
|
126
16
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module DDP
|
2
|
+
module Server
|
3
|
+
# A RethinkDB DDP Server implementation
|
4
|
+
module RethinkDB
|
5
|
+
# Helper class that users can extend to implement an API that can be passed
|
6
|
+
# as the RPC API parameter to the RethinkDB DDP protocol
|
7
|
+
class API
|
8
|
+
attr_accessor :database_name
|
9
|
+
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
@database_name = config[:database]
|
13
|
+
|
14
|
+
setup_connection_pool
|
15
|
+
setup_rpc
|
16
|
+
setup_collections
|
17
|
+
end
|
18
|
+
|
19
|
+
def invoke_rpc(method, *params)
|
20
|
+
raise 'No such method' unless @rpc_methods.include? method
|
21
|
+
send(method, *params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def collection_query(name, *params)
|
25
|
+
raise 'No such collection' unless @collections.include? name
|
26
|
+
send(name, *params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def database
|
30
|
+
::RethinkDB::RQL.new.db(@database_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def table(name)
|
34
|
+
database.table(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def with_connection
|
38
|
+
@connection_pool.with do |conn|
|
39
|
+
yield conn
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def new_connection
|
44
|
+
::RethinkDB::Connection.new(
|
45
|
+
host: @config[:host],
|
46
|
+
port: @config[:port]
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def setup_connection_pool
|
53
|
+
@connection_pool = ConnectionPool.new(
|
54
|
+
size: @config[:connection_pool_size],
|
55
|
+
timeout: @config[:connection_pool_timeout]
|
56
|
+
) do
|
57
|
+
new_connection
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def setup_rpc
|
62
|
+
rpc_module = self.class.const_get :RPC
|
63
|
+
@rpc_methods = rpc_module.instance_methods.map(&:to_s)
|
64
|
+
singleton_class.include rpc_module
|
65
|
+
end
|
66
|
+
|
67
|
+
def setup_collections
|
68
|
+
collections_module = self.class.const_get :Collections
|
69
|
+
@collections = collections_module.instance_methods.map(&:to_s)
|
70
|
+
singleton_class.include collections_module
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module DDP
|
2
|
+
module Server
|
3
|
+
module RethinkDB
|
4
|
+
# Actor that asynchronously monitors a collection
|
5
|
+
class Subscription
|
6
|
+
include Celluloid
|
7
|
+
|
8
|
+
attr_reader :name, :stopped
|
9
|
+
alias_method :stopped?, :stopped
|
10
|
+
|
11
|
+
def initialize(listener, id, name, query)
|
12
|
+
@stopped = false
|
13
|
+
@name = name
|
14
|
+
async.read_loop(listener, query, id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_loop(listener, query, id)
|
18
|
+
query.changes.run(listener.api.new_connection).each do |change|
|
19
|
+
listener.subscription_update(id, change)
|
20
|
+
break if stopped?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def stop
|
25
|
+
@stopped = true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module DDP
|
2
|
+
module Server
|
3
|
+
module RethinkDB
|
4
|
+
# Implementation of the WebSocket DDP::Server
|
5
|
+
class WebSocket < DDP::Server::WebSocket
|
6
|
+
attr_reader :api
|
7
|
+
|
8
|
+
def self.rack(api, config, pool_config = {})
|
9
|
+
super(pool_config.merge(args: [api, config]))
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(api_class, config)
|
13
|
+
@api = api_class.new(config)
|
14
|
+
@subscriptions = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def handle_sub(id, name, params)
|
18
|
+
params ||= []
|
19
|
+
query = @api.collection_query(name, *params)
|
20
|
+
@subscriptions[id] = Subscription.new(self, id, name, query)
|
21
|
+
rescue => e
|
22
|
+
send_error_result(id, e)
|
23
|
+
end
|
24
|
+
|
25
|
+
def subscription_update(id, change)
|
26
|
+
subscription_name = @subscriptions[id].name
|
27
|
+
old_value = change['old_val']
|
28
|
+
new_value = change['new_val']
|
29
|
+
|
30
|
+
return send_added(subscription_name, new_value['id'], new_value) if old_value.nil?
|
31
|
+
return send_removed(subscription_name, old_value['id']) if new_value.nil?
|
32
|
+
|
33
|
+
cleared = old_value.keys.reject { |key| new_value.include? key }
|
34
|
+
send_changed(subscription.name, old_value['id'], new_value, cleared)
|
35
|
+
end
|
36
|
+
|
37
|
+
def handle_unsub(id)
|
38
|
+
subscription = @subscriptions.delete(id)
|
39
|
+
subscription.stop unless subscription.nil?
|
40
|
+
send_nosub(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle_method(id, method, params)
|
44
|
+
params ||= []
|
45
|
+
result = @api.invoke_rpc(method, *params)
|
46
|
+
send_result(id, result)
|
47
|
+
rescue => e
|
48
|
+
send_error_result(id, e)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddp-server-rethinkdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tinco Andringa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.0.
|
47
|
+
version: 0.0.4
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.0.
|
54
|
+
version: 0.0.4
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rethinkdb
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,7 +97,10 @@ files:
|
|
97
97
|
- ddp-server-rethinkdb.gemspec
|
98
98
|
- examples/messages.rb
|
99
99
|
- lib/ddp/server/rethinkdb.rb
|
100
|
+
- lib/ddp/server/rethinkdb/api.rb
|
101
|
+
- lib/ddp/server/rethinkdb/subscription.rb
|
100
102
|
- lib/ddp/server/rethinkdb/version.rb
|
103
|
+
- lib/ddp/server/rethinkdb/websocket.rb
|
101
104
|
homepage: https://github.com/d-snp/ruby-ddp-server-rethinkdb
|
102
105
|
licenses:
|
103
106
|
- MIT
|