larva 0.1.0 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0004f08094d687c91fb380df5790dd141cae409d
4
- data.tar.gz: bf30bed9cb37627e9c7ccb6d0df30375a89b4c2a
3
+ metadata.gz: cbf84efda642aa79d413f133e1b7f27db278bec6
4
+ data.tar.gz: 88f947616c14e531fee42dc00fbd419372303bdb
5
5
  SHA512:
6
- metadata.gz: 42b25983e5579a66a6848bb4b509093bcf00a04eb9db8a9fe4d4f16a30488201677b1e82f608a9cef85431be9f7bdfb5b679d1e7c48a3fd85777bd1931e91714
7
- data.tar.gz: 9f172bd1f6a72b9f6ef642747d52b2ce3de0ad55eba6158cc24ab65588ad1c91b983b36683095f1314ea16f6f98da143b3acf77ae5eb65a65b7fa331dd36a01d
6
+ metadata.gz: e1f4c8d39c1da9883535dc5b11f152e70a53c09906b6f4e29530514aa63dccd41c1d66f0ef540182d689a806d291c1a0b5b544be7d66d496281109043acdf795
7
+ data.tar.gz: 78624d5307e979b1bab7bf2d048cb14359d46a6147f2f484d6ec5c23b0146ac5fdf28b585ade020bd83feaca2969cfc575abe6f9ae48e0a82ceada5c6697c6dd
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  Gemfile.lock
2
2
  log/
3
+ pkg/
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - rbx-2.1.1
7
+ script:
8
+ - bundle exec rake test:local
9
+ #addons:
10
+ # code_climate:
11
+ # repo_token: 88dd239bc2e0010742a42a4e0234b4decd19b46d0e9d3408d8b1fe0f96dd8fc1
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: rbx-2.1.1
data/CHANGELOG CHANGED
@@ -1,2 +1,8 @@
1
+ # 0.3.0 / 2014-02-22
2
+ * [FEATURE] Add worker pool.
3
+
4
+ # 0.2.0 / 2014-02-22
5
+ * [FEATURE] Add processor.
6
+
1
7
  # 0.1.0 / 2014-02-22
2
- * [FEATURE] Initial release with listeners
8
+ * [FEATURE] Initial release with listeners.
data/README.md CHANGED
@@ -18,17 +18,76 @@ And then execute:
18
18
 
19
19
  ## Usage
20
20
 
21
+ Larva provides you with listeners, processors and a worker pool to build an application that listens and responds to Propono messages.
22
+
23
+ Here is a sample application. This forms the basis of a rake task for most Meducation daemons.
24
+
25
+ ```ruby
26
+ require 'larva'
27
+
28
+ # Setup Config for Filum and Propono
29
+
30
+ class MyProcessor < Larva::Processor
31
+ def process(message)
32
+ if entity == "comment" && action == "created"
33
+ # Do something...
34
+ else
35
+ false
36
+ end
37
+ end
38
+ end
39
+
40
+ processors = {my_topic: MyProcessor}
41
+ Larva::WorkerPool.start(processors, "queue-suffix")
42
+
43
+ ```
44
+
21
45
  ### Listeners
22
46
 
23
47
  Larva Listeners provide an easy way of listening to a Propono topic and processing the message, complete with lots of logging through Filum.
24
48
 
49
+ ```ruby
50
+ Larva::Listener.listen(:my_topic, processor, "queue_suffix")
51
+ ```
52
+
53
+ This will listen for messages on :my_topic and pass them to `processor.process`. It will log what is happening via Filum.
54
+
55
+ ### Processors
56
+
57
+ Processors are used by listeners to handle the messages that are received. You are expected to subclass `Lavar::Processor` and implement `process`.
58
+
59
+ Processors expect you to have an `entity` and `action` fields in your messages.
60
+
61
+ For example:
62
+
25
63
  ```ruby
26
64
  class MyProcessor
27
- def self.process(message)
65
+ def process(message)
66
+ if entity == "comment" && action == "created"
67
+ # Do something...
68
+ else
69
+ false
70
+ end
28
71
  end
29
72
  end
73
+ Larva::Listener.listen(:my_topic, MyProcessor, "")
74
+ Propono.publish(:my_topic, {entity: "comment", action: "created", id: 8}
75
+ ```
76
+
77
+ With this code `MyProcessor#process` will get called for each message, with extra logging around the call. Within the class you have access to `message`, `action`, `entity` and `id` methods.
78
+
79
+ ### Worker Pool
30
80
 
31
- Larva::Listener.listen(:my_topic, MyProcessor, "queue_suffix")
81
+ The worker pool creates a listener for each topic, and proxies messages to the associated processors. If any processors die, the application will die.
82
+
83
+ Creating a worker pool is trivial:
84
+
85
+ ```ruby
86
+ processors = {
87
+ my_topic_1: MyProcessor1
88
+ my_topic_2: MyProcessor2
89
+ }
90
+ Larva::WorkerPool.start(processors, "queue-suffix")
32
91
  ```
33
92
 
34
93
  ### Is it any good?
data/lib/larva.rb CHANGED
@@ -4,6 +4,8 @@ require 'propono'
4
4
  require 'filum'
5
5
 
6
6
  require 'larva/listener'
7
+ require 'larva/processor'
8
+ require 'larva/worker_pool'
7
9
 
8
10
  module Larva
9
11
  end
@@ -0,0 +1,24 @@
1
+ module Larva
2
+ class Processor
3
+ def self.process(message)
4
+ new(message).process_with_logging
5
+ end
6
+
7
+ attr_accessor :message, :action, :entity, :id
8
+ def initialize(message)
9
+ @message = message
10
+ @action = message[:action]
11
+ @entity = message[:entity]
12
+ @id = message[:id]
13
+ end
14
+
15
+ def process_with_logging
16
+ Propono.config.logger.info "Processing message: #{message}"
17
+ if self.process
18
+ Propono.config.logger.info "Message Processed: #{message}"
19
+ else
20
+ Propono.config.logger.info "Unrecognized event type, entity: #{entity} action: #{action}."
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/larva/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Larva
2
- VERSION = '0.1.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -0,0 +1,42 @@
1
+ module Larva
2
+ class WorkerPool
3
+ def self.start(processors, queue_suffix)
4
+ new(processors, queue_suffix).start
5
+ end
6
+
7
+ attr_reader :processors, :queue_suffix, :workers
8
+ def initialize(processors, queue_suffix)
9
+ @processors = processors
10
+ @queue_suffix = queue_suffix
11
+ end
12
+
13
+ def start
14
+ start_workers
15
+ keep_workers_alive if workers.count > 0
16
+ end
17
+
18
+ private
19
+ def start_workers
20
+ logger.info "Starting threads."
21
+ @workers = processors.map do |topic, processor|
22
+ Thread.new { start_worker(topic, processor) }
23
+ end
24
+ logger.info "Threads Started."
25
+ end
26
+
27
+ def start_worker(topic, processor)
28
+ Larva::Listener.listen(topic, processor, queue_suffix)
29
+ rescue => e
30
+ logger.error "Unexpected listener termination: #{e} #{e.backtrace}"
31
+ end
32
+
33
+ def keep_workers_alive
34
+ sleep(1) while workers.all? { |t| t.alive? }
35
+ logger.error "Some threads have died"
36
+ end
37
+
38
+ def logger
39
+ Propono.config.logger
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Larva
4
+ class ProcessorTest < Minitest::Test
5
+ def test_initialize_should_extract_action_and_entity
6
+ entity = "media_file"
7
+ action = "processed"
8
+ message = {entity: entity, action: action, media_file_id: "8"}
9
+ processor = Processor.new(message)
10
+ assert_equal entity, processor.entity
11
+ assert_equal action, processor.action
12
+ end
13
+
14
+ class GoodProcessor < Processor
15
+ def process
16
+ true
17
+ end
18
+ end
19
+
20
+ class BadProcessor < Processor
21
+ def process
22
+ false
23
+ end
24
+ end
25
+
26
+ def test_process_logs_message
27
+ message = {entity: "media_file", action: "processed", media_file_id: "8"}
28
+ output = "Processing message: #{message}"
29
+ Propono.config.logger.stubs(:info)
30
+ Propono.config.logger.expects(:info).with(output)
31
+ GoodProcessor.process(message)
32
+ end
33
+
34
+ def test_process_logs_success
35
+ message = {entity: "media_file", action: "processed", media_file_id: "8"}
36
+ output = "Message Processed: #{message}"
37
+ Propono.config.logger.stubs(:info)
38
+ Propono.config.logger.expects(:info).with(output)
39
+ GoodProcessor.process(message)
40
+ end
41
+
42
+ def test_process_logs_message
43
+ entity = "media_file"
44
+ action = "processed"
45
+ message = {entity: entity, action: action, media_file_id: "8"}
46
+ output = "Unrecognized event type, entity: #{entity} action: #{action}."
47
+
48
+ Propono.config.logger.stubs(:info)
49
+ Propono.config.logger.expects(:info).with(output)
50
+ BadProcessor.process(message)
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ module Larva
4
+ class WorkerPoolTest < Minitest::Test
5
+ def test_should_complete_for_no_processors
6
+ WorkerPool.start({}, "")
7
+ end
8
+
9
+ def test_process_logs_start_message
10
+ Propono.config.logger.stubs(:info)
11
+ Propono.config.logger.expects(:info).with("Starting threads.")
12
+ WorkerPool.start({}, "")
13
+ end
14
+
15
+ def test_process_logs_end_message
16
+ Propono.config.logger.stubs(:info)
17
+ Propono.config.logger.expects(:info).with("Threads Started.")
18
+ WorkerPool.start({}, "")
19
+ end
20
+
21
+ def test_start_worker_logs_exception
22
+ Larva::Listener.expects(:listen).raises(RuntimeError)
23
+ Propono.config.logger.expects(:error).with do |error|
24
+ error.start_with?("Unexpected listener termination:")
25
+ end
26
+ Propono.config.logger.expects(:error).with('Some threads have died')
27
+ WorkerPool.start({nil => nil}, "")
28
+ end
29
+
30
+ def test_listen_is_called_correctly
31
+ topic_name = "Foo"
32
+ processor = mock
33
+ queue_suffix = "Bar"
34
+ Larva::Listener.expects(:listen).with(topic_name, processor, queue_suffix)
35
+ WorkerPool.start({topic_name => processor}, queue_suffix)
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: larva
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - iHiD
@@ -102,6 +102,7 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - .gitignore
105
+ - .travis.yml
105
106
  - CHANGELOG
106
107
  - CONTRIBUTING.md
107
108
  - Gemfile
@@ -111,10 +112,14 @@ files:
111
112
  - larva.gemspec
112
113
  - lib/larva.rb
113
114
  - lib/larva/listener.rb
115
+ - lib/larva/processor.rb
114
116
  - lib/larva/version.rb
117
+ - lib/larva/worker_pool.rb
115
118
  - test/larva_test.rb
116
119
  - test/listener_test.rb
120
+ - test/processor_test.rb
117
121
  - test/test_helper.rb
122
+ - test/worker_pool_test.rb
118
123
  homepage: https://github.com/meducation/larva
119
124
  licenses:
120
125
  - AGPL3
@@ -142,5 +147,7 @@ summary: Some Meducation specific helper files for ur pub/sub network
142
147
  test_files:
143
148
  - test/larva_test.rb
144
149
  - test/listener_test.rb
150
+ - test/processor_test.rb
145
151
  - test/test_helper.rb
152
+ - test/worker_pool_test.rb
146
153
  has_rdoc: