oversip-mod-mysql 0.0.1
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.
- data/AUTHORS +5 -0
- data/LICENSE +25 -0
- data/README.md +176 -0
- data/lib/oversip-mod-mysql.rb +71 -0
- data/lib/oversip-mod-mysql/mysql2_em_client.rb +8 -0
- data/lib/oversip-mod-mysql/version.rb +17 -0
- metadata +78 -0
data/AUTHORS
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Name: oversip-mod-mysql
|
2
|
+
Maintainer: Iñaki Baz Castillo <ibc@aliax.net>
|
3
|
+
Copyright (c) 2012 Iñaki Baz Castillo <ibc@aliax.net>
|
4
|
+
|
5
|
+
|
6
|
+
License: The MIT License
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
a copy of this software and associated documentation files (the
|
10
|
+
"Software"), to deal in the Software without restriction, including
|
11
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
+
permit persons to whom the Software is furnished to do so, subject to
|
14
|
+
the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be
|
17
|
+
included in all copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
20
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
22
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
23
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
24
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
25
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
# oversip-mod-mysql
|
2
|
+
|
3
|
+
`oversip-mod-mysql` provides an easy to use MySQL connector for [OverSIP](http://www.oversip.net) proxy based on [mysql2](https://github.com/brianmario/mysql2) driver. The library allows both pure async style (via callbacks) or serial style (by using [em-synchrony](https://github.com/igrigorik/em-synchrony/) Gem).
|
4
|
+
|
5
|
+
Check the [mysql2 documentation](https://github.com/brianmario/mysql2/blob/master/README.md) for the exact syntax and usage of the MySQL queries.
|
6
|
+
|
7
|
+
|
8
|
+
## API
|
9
|
+
|
10
|
+
|
11
|
+
### Method `OverSIP:M:Mysql.add_pool(options, db_data)`
|
12
|
+
|
13
|
+
Creates a MySQL connection pool. Parameters:
|
14
|
+
|
15
|
+
* `options`: A mandatory `Hash` with the following fields:
|
16
|
+
* `:name`: Mandatory field. Must be a `Symbol` with the name for this pool.
|
17
|
+
* `:pool_size`: The number of parallel MySQL connections to perform. By default 10.
|
18
|
+
* `:synchrony`: Whether to use [em-synchrony](https://github.com/igrigorik/em-synchrony/) or not. By default `false`.
|
19
|
+
|
20
|
+
* `db_data`: A mandatory `Hash` that will be passed to [`Mysql2::EM::Client.new`](https://github.com/brianmario/mysql2#connection-options).
|
21
|
+
|
22
|
+
*NOTE:* There is no need to pass the option `:async => true` in `db_data`. That is automatically done by the library.
|
23
|
+
|
24
|
+
|
25
|
+
### Method `OverSIP:M:Mysql.pool(name)`
|
26
|
+
|
27
|
+
Retrieves a previously created pool with the given name. Raises an `ArgumentError` if the given name does not exist in the list of created pools.
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
## Pure async style usage
|
33
|
+
|
34
|
+
When creating a pool with `options[:synchrony] => false` (default behaviour) the obtained pool is a [`EventMachine::Pool`](https://github.com/ibc/EventMachine-LE/blob/master/lib/em/pool.rb) instance and thus, it requires the following usage:
|
35
|
+
|
36
|
+
|
37
|
+
### Example
|
38
|
+
|
39
|
+
On top of `/etc/oversip/server.rb`:
|
40
|
+
|
41
|
+
```
|
42
|
+
require "oversip-mod-mysql"
|
43
|
+
|
44
|
+
def (OverSIP::SystemEvents).on_initialize
|
45
|
+
OverSIP::M::Mysql.add_pool(
|
46
|
+
{
|
47
|
+
:name => :my_async_db,
|
48
|
+
:pool_size => 5,
|
49
|
+
:synchrony => false
|
50
|
+
},
|
51
|
+
{
|
52
|
+
:host => "localhost",
|
53
|
+
:username => "oversip",
|
54
|
+
:password => "xxxxxx",
|
55
|
+
:database => "oversip",
|
56
|
+
:cast_booleans => true,
|
57
|
+
:symbolize_keys => true
|
58
|
+
}
|
59
|
+
)
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
Somewhere within the `OverSIP::SipEvents.on_request()` method in `/etc/oversip/server.rb`:
|
64
|
+
|
65
|
+
```
|
66
|
+
pool = OverSIP::M::Mysql.pool(:my_async_db)
|
67
|
+
|
68
|
+
begin
|
69
|
+
pool.perform do |db_conn|
|
70
|
+
query = db_conn.aquery "SELECT * FROM users WHERE user = \'#{request.from.user}\'"
|
71
|
+
|
72
|
+
query.callback do |result|
|
73
|
+
log_info "DB async query result: #{result.to_a.inspect}"
|
74
|
+
if result.any?
|
75
|
+
# Add a X-Header with value the 'custom_header' field of the table row:
|
76
|
+
request.set_header "X-Header", result.first["custom_header"]
|
77
|
+
proxy = ::OverSIP::SIP::Proxy.new
|
78
|
+
proxy.route request
|
79
|
+
else
|
80
|
+
request.reply 404, "User not found in DB"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
query.errback do |error|
|
85
|
+
log_error "DB async query error: #{error.inspect}"
|
86
|
+
request.reply 500, "DB async query error"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
rescue ::Mysql2::Error => e
|
91
|
+
log_error "DB async query error:"
|
92
|
+
log_error e
|
93
|
+
request.reply 500, "DB async query error"
|
94
|
+
end
|
95
|
+
```
|
96
|
+
|
97
|
+
|
98
|
+
## Sync style usage with `em-synchrony`
|
99
|
+
|
100
|
+
When creating a pool with `options[:synchrony] => true` the obtained pool is a [`EventMachine::Synchrony::ConnectionPool`](https://github.com/igrigorik/em-synchrony/blob/master/lib/em-synchrony/connection_pool.rb) instance.
|
101
|
+
|
102
|
+
Please ensure you properly understand how [em-synchrony](https://github.com/igrigorik/em-synchrony/) works. Specially take into account that just the code within the `EM.synchrony do [...] end` block is executed serially. Code placed after that block is executed immediately, this is, *before* the serial code is executed. So if you want to use serial style coding write all your logic code within a `EM.synchrony do [...] end` block.
|
103
|
+
|
104
|
+
* For more information about `em-synchrony` usage check [Untangling Evented Code with Ruby Fibers](http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/).
|
105
|
+
|
106
|
+
|
107
|
+
### Example
|
108
|
+
|
109
|
+
On top of `/etc/oversip/server.rb`:
|
110
|
+
|
111
|
+
```
|
112
|
+
require "oversip-mod-mysql"
|
113
|
+
|
114
|
+
def (OverSIP::SystemEvents).on_initialize
|
115
|
+
OverSIP::M::Mysql.add_pool(
|
116
|
+
{
|
117
|
+
:name => :my_sync_db,
|
118
|
+
:pool_size => 5,
|
119
|
+
:synchrony => true
|
120
|
+
},
|
121
|
+
{
|
122
|
+
:host => "localhost",
|
123
|
+
:username => "oversip",
|
124
|
+
:password => "xxxxxx",
|
125
|
+
:database => "oversip",
|
126
|
+
:cast_booleans => true,
|
127
|
+
:symbolize_keys => true
|
128
|
+
}
|
129
|
+
)
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
Somewhere within the `OverSIP::SipEvents.on_request()` method in `/etc/oversip/server.rb`:
|
134
|
+
|
135
|
+
```
|
136
|
+
EM.synchrony do
|
137
|
+
pool = OverSIP::M::Mysql.pool(:my_sync_db)
|
138
|
+
|
139
|
+
begin
|
140
|
+
result = pool.query "SELECT * FROM users WHERE user = \'#{request.from.user}\'"
|
141
|
+
log_info "DB sync query result: #{result.to_a.inspect}"
|
142
|
+
if result.any?
|
143
|
+
# Add a X-Header with value the 'custom_header' field of the table row:
|
144
|
+
request.set_header "X-Header", result.first["custom_header"]
|
145
|
+
proxy = ::OverSIP::SIP::Proxy.new :proxy_out
|
146
|
+
proxy.route request
|
147
|
+
else
|
148
|
+
request.reply 404, "User not found in DB"
|
149
|
+
end
|
150
|
+
|
151
|
+
rescue ::Mysql2::Error => e
|
152
|
+
log_error "DB sync query error:"
|
153
|
+
log_error e
|
154
|
+
request.reply 500, "DB sync query error"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
|
160
|
+
## Using sync and async styles together
|
161
|
+
|
162
|
+
A pool created with `OverSIP:M:Mysql.add_pool()` method must be sync or async. However the user can set two pools, the first one sync and the second one sync.
|
163
|
+
|
164
|
+
When a sync pool is created, the library loads `em-synchrony/mysql2` which overrides the `Mysql2::EM::Client#query()` method. So if *at least* one of your pools uses sync style then you must use the `Mysql2::EM::Client#aquery()` method for the async pool (which is an alias of the original `query()` method).
|
165
|
+
|
166
|
+
|
167
|
+
## Installation
|
168
|
+
|
169
|
+
```
|
170
|
+
~$ gem install oversip-mod-mysql
|
171
|
+
```
|
172
|
+
|
173
|
+
|
174
|
+
## Author
|
175
|
+
|
176
|
+
Iñaki Baz Castillo <ibc@aliax.net> (Github [@ibc](https://github.com/ibc)).
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "mysql2/em"
|
2
|
+
|
3
|
+
require "oversip-mod-mysql/version.rb"
|
4
|
+
require "oversip-mod-mysql/mysql2_em_client.rb"
|
5
|
+
|
6
|
+
|
7
|
+
module OverSIP
|
8
|
+
module Modules
|
9
|
+
|
10
|
+
module Mysql
|
11
|
+
|
12
|
+
extend ::OverSIP::Logger
|
13
|
+
|
14
|
+
DEFAULT_POOL_SIZE = 10
|
15
|
+
DEFAULT_SYNCHRONY = false
|
16
|
+
|
17
|
+
@log_id = "Mysql module"
|
18
|
+
@pools = {}
|
19
|
+
|
20
|
+
def self.add_pool options, db_data
|
21
|
+
raise ::ArgumentError, "`options' must be a Hash" unless options.is_a? ::Hash
|
22
|
+
raise ::ArgumentError, "`db_data' must be a Hash" unless db_data.is_a? ::Hash
|
23
|
+
|
24
|
+
name, pool_size, synchrony = options.values_at(:name, :pool_size, :synchrony)
|
25
|
+
pool_size ||= DEFAULT_POOL_SIZE
|
26
|
+
synchrony ||= DEFAULT_SYNCHRONY
|
27
|
+
|
28
|
+
raise ::ArgumentError, "`options[:name]' must be a Symbol" unless name.is_a? ::Symbol
|
29
|
+
raise ::ArgumentError, "`options[:pool_size]' must be a positive Fixnum" unless pool_size.is_a? ::Fixnum and pool_size > 0
|
30
|
+
|
31
|
+
# Forcing DB autoreconnect.
|
32
|
+
db_data[:reconnect] = true
|
33
|
+
|
34
|
+
# Use em-synchrony for serial coding.
|
35
|
+
if synchrony
|
36
|
+
begin
|
37
|
+
require "em-synchrony"
|
38
|
+
require "em-synchrony/mysql2"
|
39
|
+
rescue ::LoadError
|
40
|
+
OverSIP::Launcher.fatal "em-synchrony not installed: gem install em-synchrony"
|
41
|
+
end
|
42
|
+
|
43
|
+
OverSIP::SystemCallbacks.on_started do
|
44
|
+
log_system_info "Adding a sync pool with name #{name.inspect}..."
|
45
|
+
@pools[name] = ::EM::Synchrony::ConnectionPool.new(size: pool_size) do
|
46
|
+
::Mysql2::EM::Client.new(db_data)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Don't use em-synchrony but pure callbacks.
|
51
|
+
else
|
52
|
+
OverSIP::SystemCallbacks.on_started do
|
53
|
+
log_system_info "Adding an async pool with name #{name.inspect}..."
|
54
|
+
pool = @pools[name] = ::EM::Pool.new
|
55
|
+
pool_size.times do
|
56
|
+
pool.add ::Mysql2::EM::Client.new(db_data)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end # def self.add_pool
|
61
|
+
|
62
|
+
def self.pool name
|
63
|
+
pool = @pools[name]
|
64
|
+
raise ::ArgumentError, "no pool with `name' #{name.inspect}" unless pool
|
65
|
+
pool
|
66
|
+
end
|
67
|
+
|
68
|
+
end # module Mysql
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module OverSIP
|
2
|
+
module Modules
|
3
|
+
|
4
|
+
module Mysql
|
5
|
+
module Version
|
6
|
+
MAJOR = 0
|
7
|
+
MINOR = 0
|
8
|
+
TINY = 1
|
9
|
+
DEVEL = nil # Set to nil for stable releases.
|
10
|
+
end
|
11
|
+
|
12
|
+
VERSION = [Version::MAJOR, Version::MINOR, Version::TINY].join(".")
|
13
|
+
VERSION << ".#{Version::DEVEL}" if Version::DEVEL
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oversip-mod-mysql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Inaki Baz Castillo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: oversip
|
16
|
+
requirement: &16825480 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *16825480
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mysql2
|
27
|
+
requirement: &17963820 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.3.11
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *17963820
|
36
|
+
description: ! 'oversip-mod-mysql provides an easy to use MySQL connector for OverSIP
|
37
|
+
proxy. The library allows both pure async style (via callbacks) or serial style
|
38
|
+
(by using ''em-synchrony'' Gem).
|
39
|
+
|
40
|
+
'
|
41
|
+
email:
|
42
|
+
- ibc@aliax.net
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- lib/oversip-mod-mysql.rb
|
48
|
+
- lib/oversip-mod-mysql/version.rb
|
49
|
+
- lib/oversip-mod-mysql/mysql2_em_client.rb
|
50
|
+
- README.md
|
51
|
+
- AUTHORS
|
52
|
+
- LICENSE
|
53
|
+
homepage: https://github.com/versatica/oversip-mod-mysql
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: 1.9.2
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.11
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: MySQL connector module for OverSIP
|
77
|
+
test_files: []
|
78
|
+
has_rdoc: false
|