celerb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,9 @@
1
+ === 0.0.2 / 2010-11-13
2
+
3
+ * subscribes to celery results
4
+
5
+ === 0.0.1 / 2010-11-12
6
+
7
+ * initial release
8
+ * can submit tasks to celery
9
+
data/Manifest.txt ADDED
@@ -0,0 +1,13 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/celerb.rb
6
+ lib/celerb/task.rb
7
+ lib/celerb/task_publisher.rb
8
+ lib/celerb/result_consumer.rb
9
+ test/test_celerb.rb
10
+ test/test_helper.rb
11
+ test/thumbTask.pb.rb
12
+ test/thumbTask.proto
13
+ test/vleugel.kmz
data/README.rdoc ADDED
@@ -0,0 +1,14 @@
1
+ = celery for ruby
2
+
3
+ https://github.com/skrat/celerb
4
+
5
+ Ruby client library for submitting task to celery queue.
6
+
7
+ == LICENSE:
8
+
9
+ (The GPL License)
10
+
11
+ Copyright (c) 2010 Dusan Maliarik
12
+
13
+ See http://www.gnu.org/licenses/gpl.html
14
+
data/Rakefile ADDED
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ gem 'hoe', '>= 2.1.0'
3
+ require 'hoe'
4
+ require 'fileutils'
5
+
6
+ # Hoe.plugin :website
7
+ # Hoe.plugin :cucumberfeatures
8
+
9
+ # Generate all the Rake tasks
10
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
11
+ $hoe = Hoe.spec 'celerb' do
12
+ self.developer 'Dusan Maliarik', 'dusan.maliarik@gmail.com'
13
+ self.rubyforge_name = self.name # TODO this is default value
14
+ self.extra_deps = [
15
+ ['amqp', '= 0.6.7'],
16
+ ['msgpack','= 0.4.3']
17
+ ]
18
+
19
+ end
20
+
@@ -0,0 +1,57 @@
1
+ module Celerb
2
+ class ResultConsumer
3
+ def initialize(opts)
4
+ @exchange = MQ.direct(opts[:results], :auto_delete => true)
5
+ @handlers = {}
6
+ @queues = {}
7
+ end
8
+
9
+ def register(task_id, &blk)
10
+ @handlers[task_id] = blk
11
+ end
12
+
13
+ def subscribe(task_id)
14
+ queue = task_id_to_queue(task_id)
15
+ queue.subscribe &method(:consume)
16
+ end
17
+
18
+ def consume(header, body)
19
+ result = Result.new(MessagePack.unpack(body))
20
+ queue = @queues.delete result.task_id
21
+ queue.unsubscribe
22
+ if @handlers.include? result.task_id
23
+ handler = @handlers.delete result.task_id
24
+ handler.call result
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def task_id_to_queue(task_id)
31
+ queue = MQ.queue(task_id_to_queue_name(task_id), :auto_delete => true)
32
+ queue.bind(@exchange)
33
+ @queues[task_id] = queue
34
+ end
35
+
36
+ def task_id_to_queue_name(task_id)
37
+ task_id.gsub('-', '')
38
+ end
39
+ end
40
+
41
+ class Result
42
+
43
+ attr_reader :task_id
44
+ attr_reader :status
45
+ attr_reader :body
46
+
47
+ def initialize(message)
48
+ @task_id = message['task_id']
49
+ @status = message['status'].to_sym
50
+ @body = message['result']
51
+ end
52
+
53
+ def success?
54
+ @status == :SUCCESS
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,48 @@
1
+ module Celerb
2
+ # Mixin for Celery tasks
3
+ module Task
4
+
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ def delay
10
+ self.class.delay self.to_celery
11
+ end
12
+
13
+ def to_celery
14
+ raise NotImplementedError, "You have to return Celery task arguments here"
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ def task_name(value)
20
+ @@name = value
21
+ end
22
+
23
+ def delay(*args)
24
+ argz = args.select{|a| !a.kind_of? Hash}
25
+ kwargz = args.select{|a| a.kind_of? Hash}.first
26
+ if argz.length + (kwargz && 1 || 0) > args.length
27
+ raise "Wrong arguments, must be list followed by optional Hash"
28
+ end
29
+ AsyncResult.new(TaskPublisher.delay_task(
30
+ @@name, task_args=argz, task_kwargs=kwargz||{}))
31
+ end
32
+ end
33
+
34
+ end
35
+
36
+ class AsyncResult
37
+
38
+ attr_reader :task_id
39
+
40
+ def initialize(task_id)
41
+ @task_id = task_id
42
+ end
43
+
44
+ def wait(&blk)
45
+ TaskPublisher.register_result_handler(@task_id, &blk)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ module Celerb
2
+ class TaskPublisher
3
+
4
+ def self.connect(opts)
5
+ @@exchange = MQ.direct(opts[:exchange],
6
+ :key => opts[:key], :durable => true)
7
+ @@results = ResultConsumer.new(opts)
8
+ end
9
+
10
+ def self.delay_task(task_name, task_args=[], task_kwargs={},
11
+ task_id=nil, taskset_id=nil, expires=nil, eta=nil,
12
+ exchange=nil, exchange_type=nil, retries=0)
13
+ task_id ||= TaskPublisher.uniq_id
14
+ @@results.subscribe task_id
15
+ publish({
16
+ :task => task_name,
17
+ :id => task_id,
18
+ :args => task_args,
19
+ :kwargs => task_kwargs,
20
+ :retries => retries,
21
+ :eta => eta,
22
+ :expires => expires
23
+ })
24
+ return task_id
25
+ end
26
+
27
+ def self.register_result_handler(task_id, &blk)
28
+ @@results.register(task_id, &blk)
29
+ end
30
+
31
+ private
32
+
33
+ def self.publish(body)
34
+ @@exchange.publish MessagePack.pack(body), {
35
+ :content_type => 'application/x-msgpack',
36
+ :content_encoding => 'binary'
37
+ }
38
+ end
39
+
40
+
41
+ def self.uniq_id
42
+ return UUID.create_v4.to_s
43
+ end
44
+
45
+ end
46
+ end
data/lib/celerb.rb ADDED
@@ -0,0 +1,15 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ require 'rubygems'
4
+
5
+ require 'mq'
6
+ require 'msgpack'
7
+ require 'uuid'
8
+
9
+ module Celerb
10
+ VERSION = '0.0.2'
11
+ end
12
+
13
+ require 'celerb/task'
14
+ require 'celerb/task_publisher'
15
+ require 'celerb/result_consumer'
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestCelerb < Test::Unit::TestCase
4
+
5
+ def test_unique_id
6
+ assert !Celerb::TaskPublisher.uniq_id.nil?
7
+ end
8
+
9
+ def x_test_delay_task
10
+ with_celery do |exchange|
11
+ tp = Celerb::TaskPublisher.new exchange
12
+ assert !tp.delay_task('some').nil?
13
+ end
14
+ end
15
+
16
+ def test_task_class
17
+ AMQP.run(TEST_CELERY[:AMQP]) do
18
+ Celerb::TaskPublisher.connect(TEST_CELERY)
19
+ asset = open(File.join(File.dirname(__FILE__), 'vleugel.kmz')).read()
20
+
21
+ task = Floorplanner::ThumbTask.new(
22
+ :type => Floorplanner::ThumbTask::AssetType::DAE,
23
+ :resultPath => '/test/thing/%s/some.png',
24
+ :asset => asset,
25
+ :styles => [Floorplanner::ThumbStyle.new(
26
+ :name => 'original',
27
+ :size => 512)]
28
+ ).delay.wait do |result|
29
+ puts result.body
30
+ end
31
+ puts "Done..."
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def with_amqp(&blk)
38
+ AMQP.connect(TEST_CELERY[:AMQP])
39
+ yield
40
+ end
41
+
42
+ def with_celery(&blk)
43
+ with_amqp do
44
+ yield MQ.direct(TEST_CELERY[:exchange],
45
+ :key => TEST_CELERY[:key], :durable => true)
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,17 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/celerb'
4
+ require 'test/thumbTask.pb'
5
+
6
+ TEST_CELERY = {
7
+ :AMQP => {
8
+ :host => 'localhost',
9
+ :user => 'geri',
10
+ :pass => 'geri',
11
+ :vhost => 'geri'
12
+ },
13
+ :key => 'celery',
14
+ :exchange => 'celery',
15
+ :results => 'celeryresults'
16
+ }
17
+
@@ -0,0 +1,53 @@
1
+ ### Generated by rprotoc. DO NOT EDIT!
2
+ ### <proto file: thumbTask.proto>
3
+ # package floorplanner;
4
+ #
5
+ # message ThumbTask {
6
+ #
7
+ # enum AssetType {
8
+ # DAE = 0;
9
+ # SWF = 1;
10
+ # }
11
+ #
12
+ # required string resultPath = 1;
13
+ # required AssetType type = 2;
14
+ # required bytes asset = 3;
15
+ # repeated ThumbStyle styles = 4;
16
+ # }
17
+ #
18
+ # message ThumbStyle {
19
+ # required string name = 1;
20
+ # required int32 size = 2;
21
+ # }
22
+
23
+ require 'protobuf/message/message'
24
+ require 'protobuf/message/enum'
25
+ require 'protobuf/message/service'
26
+ require 'protobuf/message/extend'
27
+
28
+ module Floorplanner
29
+ class ThumbTask < ::Protobuf::Message
30
+ defined_in __FILE__
31
+ class AssetType < ::Protobuf::Enum
32
+ defined_in __FILE__
33
+ DAE = value(:DAE, 0)
34
+ SWF = value(:SWF, 1)
35
+ end
36
+ required :string, :resultPath, 1
37
+ required :AssetType, :type, 2
38
+ required :bytes, :asset, 3
39
+ repeated :ThumbStyle, :styles, 4
40
+
41
+ include Celerb::Task
42
+ task_name 'thumbs.tasks.thumb3D'
43
+
44
+ def to_celery
45
+ serialize_to_string
46
+ end
47
+ end
48
+ class ThumbStyle < ::Protobuf::Message
49
+ defined_in __FILE__
50
+ required :string, :name, 1
51
+ required :int32, :size, 2
52
+ end
53
+ end
@@ -0,0 +1,19 @@
1
+ package floorplanner;
2
+
3
+ message ThumbTask {
4
+
5
+ enum AssetType {
6
+ DAE = 0;
7
+ SWF = 1;
8
+ }
9
+
10
+ required string resultPath = 1;
11
+ required AssetType type = 2;
12
+ required bytes asset = 3;
13
+ repeated ThumbStyle styles = 4;
14
+ }
15
+
16
+ message ThumbStyle {
17
+ required string name = 1;
18
+ required int32 size = 2;
19
+ }
data/test/vleugel.kmz ADDED
Binary file
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: celerb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dusan Maliarik
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-11-13 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: amqp
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.6.7
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: msgpack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.4.3
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rubyforge
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.0.3
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: gemcutter
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.3.0
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: hoe
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 2.5.0
64
+ version:
65
+ description: ""
66
+ email:
67
+ - dusan.maliarik@gmail.com
68
+ executables: []
69
+
70
+ extensions: []
71
+
72
+ extra_rdoc_files:
73
+ - History.txt
74
+ - Manifest.txt
75
+ files:
76
+ - History.txt
77
+ - Manifest.txt
78
+ - README.rdoc
79
+ - Rakefile
80
+ - lib/celerb.rb
81
+ - lib/celerb/task.rb
82
+ - lib/celerb/task_publisher.rb
83
+ - lib/celerb/result_consumer.rb
84
+ - test/test_celerb.rb
85
+ - test/test_helper.rb
86
+ - test/thumbTask.pb.rb
87
+ - test/thumbTask.proto
88
+ - test/vleugel.kmz
89
+ has_rdoc: true
90
+ homepage: https://github.com/skrat/celerb
91
+ licenses: []
92
+
93
+ post_install_message:
94
+ rdoc_options:
95
+ - --main
96
+ - README.txt
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: "0"
110
+ version:
111
+ requirements: []
112
+
113
+ rubyforge_project: celerb
114
+ rubygems_version: 1.3.5
115
+ signing_key:
116
+ specification_version: 3
117
+ summary: ""
118
+ test_files:
119
+ - test/test_helper.rb
120
+ - test/test_celerb.rb