td-querier 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +14 -9
- data/README.md +47 -3
- data/VERSION +1 -1
- data/lib/td/querier.rb +7 -7
- data/spec/querier_spec.rb +87 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 478227b02106d0610c2662f2507c894bf32bd393
|
4
|
+
data.tar.gz: ead6a5f69c35e4c6d0e167ea7a93c90889e12aca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 013197d771d0710df0c51823d2975b4b2e262ff039e926120c0e6cb40d559b0818060f862b5837914143e13738189f44ae83e1c57448f3c7430deddfaca5bf45
|
7
|
+
data.tar.gz: 735e9f9635ec2cb22651d4effe909cdbd5ce40e817a4ad4bbe6da34781012d761fef867cf0a8703b2faccf9cee12615ba923180b64604af4e5554650e059553b
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,28 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
td-querier (0.0.
|
5
|
-
sidekiq (
|
6
|
-
td (
|
4
|
+
td-querier (0.0.5)
|
5
|
+
sidekiq (~> 2.7.2)
|
6
|
+
td (~> 0.10.73)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
-
celluloid (0.
|
11
|
+
celluloid (0.12.4)
|
12
|
+
facter (>= 1.6.12)
|
12
13
|
timers (>= 1.0.0)
|
13
14
|
connection_pool (1.0.0)
|
14
15
|
diff-lcs (1.2.4)
|
16
|
+
facter (1.6.17)
|
15
17
|
fluent-logger (0.4.5)
|
16
18
|
msgpack (= 0.4.7)
|
17
19
|
yajl-ruby (~> 1.0)
|
18
20
|
hirb (0.7.1)
|
19
21
|
json (1.7.7)
|
20
22
|
msgpack (0.4.7)
|
23
|
+
multi_json (1.7.3)
|
21
24
|
parallel (0.5.21)
|
25
|
+
rake (10.0.4)
|
22
26
|
redis (3.0.4)
|
23
27
|
redis-namespace (1.3.0)
|
24
28
|
redis (~> 3.0.0)
|
@@ -31,11 +35,11 @@ GEM
|
|
31
35
|
diff-lcs (>= 1.1.3, < 2.0)
|
32
36
|
rspec-mocks (2.13.1)
|
33
37
|
rubyzip (0.9.9)
|
34
|
-
sidekiq (2.
|
35
|
-
celluloid (
|
36
|
-
connection_pool (
|
37
|
-
|
38
|
-
redis (
|
38
|
+
sidekiq (2.7.2)
|
39
|
+
celluloid (~> 0.12.0)
|
40
|
+
connection_pool (~> 1.0)
|
41
|
+
multi_json (~> 1)
|
42
|
+
redis (~> 3)
|
39
43
|
redis-namespace
|
40
44
|
td (0.10.77)
|
41
45
|
hirb (>= 0.4.5)
|
@@ -59,5 +63,6 @@ PLATFORMS
|
|
59
63
|
ruby
|
60
64
|
|
61
65
|
DEPENDENCIES
|
66
|
+
rake
|
62
67
|
rspec
|
63
68
|
td-querier!
|
data/README.md
CHANGED
@@ -1,7 +1,51 @@
|
|
1
|
-
|
1
|
+
## Treasure Data and Sidekiq awesomeness
|
2
2
|
|
3
|
-
|
3
|
+
###Concept
|
4
|
+
Treasure data jobs take sometime to finish, and in most scenarios waiting is not really an option.
|
4
5
|
|
6
|
+
Td-querier will create a Sidekiq job with the job_id of your Treasure Data Queries and will check if the job has finished.
|
7
|
+
|
8
|
+
If it is finished, it will send a callback to continue your data process.
|
9
|
+
|
10
|
+
If not it will reschedule itself until the job is done.
|
11
|
+
|
12
|
+
###Installation
|
5
13
|
$ gem install td-querier
|
6
14
|
|
7
|
-
|
15
|
+
###Usage
|
16
|
+
```
|
17
|
+
querier = Querier.new("TREASURE_DATA_API_KEY")
|
18
|
+
database_name = 'my_td_database_name'
|
19
|
+
query_text = 'select count(*) from my_table'
|
20
|
+
options = {:klass=>"MyClass", :method=>"my_method", :results => "true"} #See Options section for this one
|
21
|
+
|
22
|
+
#Optional
|
23
|
+
on_demand_path = 'mysql://user:password@host/database/table' #will insert the result of your query into another table
|
24
|
+
priority = 1 #default 1
|
25
|
+
reschedule_time #Time interval for checking if the job is finished
|
26
|
+
|
27
|
+
querier.query(database_name, query_text, on_demand_path, options, priority, reschedule_time)
|
28
|
+
```
|
29
|
+
|
30
|
+
###Options
|
31
|
+
Once the job has finished sidekiq will stop retriying and will send a callback to a class method specified on the options.
|
32
|
+
|
33
|
+
* klass: The name of the class you want to use, i.e. "MyClass"
|
34
|
+
* method: The name of the class method you want to use, i.e. "my_method"
|
35
|
+
* results: if is "true" will fetch the results from treasure data and it will pass those results to your method as a parameter. Be aware that exceptionally large results might impact your performance.
|
36
|
+
|
37
|
+
###Internals
|
38
|
+
Querier objects are designed to query treasure data api asynchronously.
|
39
|
+
|
40
|
+
This gem uses [Sidekiq] (https://github.com/mperham/sidekiq) so make sure your app plays nice with that.
|
41
|
+
|
42
|
+
Also it uses [td gem](https://rubygems.org/gems/td)
|
43
|
+
|
44
|
+
### Contributing
|
45
|
+
|
46
|
+
1. Fork it
|
47
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
48
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
49
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
50
|
+
5. Create new Pull Request
|
51
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.6
|
data/lib/td/querier.rb
CHANGED
@@ -10,24 +10,24 @@ class Querier
|
|
10
10
|
@api_key = api_key
|
11
11
|
end
|
12
12
|
|
13
|
-
def query(database, query,
|
13
|
+
def query(database, query, opts, on_demand_path='', priority=1, reschedule_time=300)
|
14
14
|
client = TreasureData::Client.new(@api_key)
|
15
|
-
job = client.query(database, query,
|
15
|
+
job = client.query(database, query, on_demand_path, priority)
|
16
16
|
Querier.perform_async(@api_key, job.job_id, opts, reschedule_time)
|
17
17
|
end
|
18
18
|
|
19
|
-
def perform(api_key, job_id, opts, reschedule_time=
|
19
|
+
def perform(api_key, job_id, opts, reschedule_time=300)
|
20
20
|
client = TreasureData::Client.new(api_key)
|
21
21
|
job = client.job(job_id)
|
22
22
|
#reschedule if the job is not finished
|
23
23
|
return Querier.perform_in(reschedule_time, api_key, job_id, opts, reschedule_time) unless job.finished?
|
24
24
|
|
25
25
|
if opts
|
26
|
-
klass = opts[
|
27
|
-
meth = opts[
|
28
|
-
send_results = opts[
|
26
|
+
klass = opts[:klass]
|
27
|
+
meth = opts[:method]
|
28
|
+
send_results = opts[:results]
|
29
29
|
results = (send_results.to_s == "true" ? job.results : nil)
|
30
|
-
|
30
|
+
eval(klass).send(meth.to_s, results)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
data/spec/querier_spec.rb
CHANGED
@@ -1,6 +1,91 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'debugger'
|
3
2
|
|
4
3
|
describe Querier do
|
5
|
-
|
4
|
+
describe "Send the query to treasaure data" do
|
5
|
+
context "Wrong parameters" do
|
6
|
+
|
7
|
+
it "will raise an error if the api key is not valid" do
|
8
|
+
fake_client = Object.new
|
9
|
+
fake_client.should_receive(:query).and_raise(TreasureData::APIError.new("apikey authentication failed"))
|
10
|
+
TreasureData::Client.should_receive(:new).and_return(fake_client)
|
11
|
+
Querier.should_not_receive(:perform_async)
|
12
|
+
|
13
|
+
querier = Querier.new("bad_key")
|
14
|
+
lambda{querier.query("database", "my_query", {})}.should raise_error(TreasureData::APIError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "will raise an error if the database name is not valid" do
|
18
|
+
fake_client = Object.new
|
19
|
+
fake_client.should_receive(:query).and_raise(TreasureData::NotFoundError.new("Couldn't find UserDatabase with name = bad_name"))
|
20
|
+
TreasureData::Client.should_receive(:new).and_return(fake_client)
|
21
|
+
Querier.should_not_receive(:perform_async)
|
22
|
+
|
23
|
+
querier = Querier.new("good_key")
|
24
|
+
lambda{querier.query("bad_name", "my_query", {})}.should raise_error(TreasureData::NotFoundError)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Right parameters" do
|
29
|
+
it "will send a query to treasure data and instance a sidekiq job with the job id of the new job" do
|
30
|
+
fake_job = Object.new
|
31
|
+
fake_job.should_receive(:job_id).and_return(1)
|
32
|
+
|
33
|
+
fake_client = Object.new
|
34
|
+
fake_client.should_receive(:query).and_return(fake_job)
|
35
|
+
|
36
|
+
TreasureData::Client.should_receive(:new).and_return(fake_client)
|
37
|
+
|
38
|
+
Querier.should_receive(:perform_async).and_return(true)
|
39
|
+
|
40
|
+
querier = Querier.new("good_key")
|
41
|
+
querier.query("database", "my_query", {})
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "Sidekiq processing" do
|
47
|
+
context "Standar processing" do
|
48
|
+
before(:each) do
|
49
|
+
@opts = {:klass => "Object", :method => "fake_method", :results => "false"}
|
50
|
+
@fake_job = Object.new
|
51
|
+
@fake_client = Object.new
|
52
|
+
@fake_client.should_receive(:job).and_return(@fake_job)
|
53
|
+
TreasureData::Client.should_receive(:new).and_return(@fake_client)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "will reschedule the sidekiq job if the treasure data job is not yet finished" do
|
57
|
+
@fake_job.should_receive(:finished?).and_return(false)
|
58
|
+
Querier.should_receive(:perform_in).with(300, "apikey", 1, @opts, 300).and_return(true)
|
59
|
+
Querier.new.perform("apikey", 1, @opts)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "will make a call to a given class method if que job is finished" do
|
63
|
+
@fake_job.should_receive(:finished?).and_return(true)
|
64
|
+
Object.should_receive(:fake_method).and_return(true)
|
65
|
+
Querier.new.perform("apikey", 1, @opts)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "will request the query results if the options for result are set to true" do
|
69
|
+
new_opts = {:klass => "Object", :method => "fake_method", :results => "true"}
|
70
|
+
results = [[1]]
|
71
|
+
@fake_job.should_receive(:finished?).and_return(true)
|
72
|
+
@fake_job.should_receive(:results).and_return(results)
|
73
|
+
Object.should_receive(:fake_method).and_return(true)
|
74
|
+
Querier.new.perform("apikey", 1, new_opts)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "Error case" do
|
79
|
+
it "will raise an exception if something explodes within sidekiq" do
|
80
|
+
@opts = {:klass => "Object", :method => "fake_method", :results => "false"}
|
81
|
+
@fake_job = Object.new
|
82
|
+
@fake_client = Object.new
|
83
|
+
@fake_client.should_receive(:job).and_return(@fake_job)
|
84
|
+
TreasureData::Client.should_receive(:new).and_return(@fake_client)
|
85
|
+
|
86
|
+
@fake_job.should_receive(:finished?).and_raise(RuntimeError.new("unexpected error"))
|
87
|
+
lambda{Querier.new.perform("apikey", 1, @opts)}.should raise_error(RuntimeError)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
6
91
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: td-querier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Carlos Donderis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-05-
|
11
|
+
date: 2013-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|