qprocessor 0.2.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 +4 -4
- data/.rspec +1 -0
- data/Gemfile.lock +20 -3
- data/README.md +83 -7
- data/lib/qprocessor/processor.rb +31 -38
- data/lib/qprocessor/sqs_source.rb +0 -9
- data/lib/qprocessor/version.rb +1 -1
- data/qprocessor.gemspec +4 -0
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e49f396b457d247ba22300439d134f4d663696f445a32dc36451fae46566602
|
4
|
+
data.tar.gz: 5ef52af86d0a282e5e633c156f7fcf3d1c08ccbb079cd0c5cb5f98eec3ab33ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4711089a7f42c713698c5183e56b3dbc287f4f25f3fb3197dfe5eb55e0f6dda809f558fc6e124f6b1a3b077045715a7b763518b08878ded26303e2d2b6258ff
|
7
|
+
data.tar.gz: 026c0bdc955bfcb61201b29453bbe2db5f1685b5273df674ac7b439551a9fe7b3e176cf26a71e5d520aa49af0c13a98de9b894221b1fe08d4d98ef8399edba0f
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/Gemfile.lock
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
qprocessor (0.
|
4
|
+
qprocessor (0.3.0)
|
5
5
|
aws-sdk-sqs (~> 1.49)
|
6
6
|
aws-sdk-sts (~> 1.5)
|
7
7
|
beaneater (~> 1.1)
|
8
|
+
ox (~> 2.14)
|
8
9
|
|
9
10
|
GEM
|
10
11
|
remote: https://rubygems.org/
|
11
12
|
specs:
|
12
13
|
aws-eventstream (1.2.0)
|
13
|
-
aws-partitions (1.
|
14
|
-
aws-sdk-core (3.125.
|
14
|
+
aws-partitions (1.550.0)
|
15
|
+
aws-sdk-core (3.125.5)
|
15
16
|
aws-eventstream (~> 1, >= 1.0.2)
|
16
17
|
aws-partitions (~> 1, >= 1.525.0)
|
17
18
|
aws-sigv4 (~> 1.1)
|
@@ -25,8 +26,23 @@ GEM
|
|
25
26
|
aws-sigv4 (1.4.0)
|
26
27
|
aws-eventstream (~> 1, >= 1.0.2)
|
27
28
|
beaneater (1.1.1)
|
29
|
+
diff-lcs (1.5.0)
|
28
30
|
jmespath (1.5.0)
|
31
|
+
ox (2.14.6)
|
29
32
|
rake (13.0.6)
|
33
|
+
rspec (3.10.0)
|
34
|
+
rspec-core (~> 3.10.0)
|
35
|
+
rspec-expectations (~> 3.10.0)
|
36
|
+
rspec-mocks (~> 3.10.0)
|
37
|
+
rspec-core (3.10.1)
|
38
|
+
rspec-support (~> 3.10.0)
|
39
|
+
rspec-expectations (3.10.2)
|
40
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
41
|
+
rspec-support (~> 3.10.0)
|
42
|
+
rspec-mocks (3.10.2)
|
43
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
+
rspec-support (~> 3.10.0)
|
45
|
+
rspec-support (3.10.3)
|
30
46
|
|
31
47
|
PLATFORMS
|
32
48
|
x86_64-linux
|
@@ -34,6 +50,7 @@ PLATFORMS
|
|
34
50
|
DEPENDENCIES
|
35
51
|
qprocessor!
|
36
52
|
rake (~> 13.0)
|
53
|
+
rspec
|
37
54
|
|
38
55
|
BUNDLED WITH
|
39
56
|
2.2.3
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# QProcessor
|
2
2
|
|
3
|
-
A simple library that wraps the processing of elements pulled from a queue.
|
4
|
-
implementation
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
A simple library that wraps the processing of elements pulled from a queue. The
|
4
|
+
current implementation supports the Beanstalkd and SQS queuing platforms. The
|
5
|
+
idea behind this gem is to allow for the easy creation of an 'application as a
|
6
|
+
service', where the services jobs is to pull items from a queue and process them.
|
7
|
+
The library code is intended to wrap the parts of the code that would be common
|
8
|
+
and repeated if you made individual service applications.
|
9
9
|
|
10
10
|
## Installation
|
11
11
|
|
@@ -25,7 +25,83 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
## Usage
|
27
27
|
|
28
|
-
|
28
|
+
There are two things that you need to do to make use of this library. The first
|
29
|
+
is to create a processor class and the second is to assemble the service
|
30
|
+
execution functionality.
|
31
|
+
|
32
|
+
### The Processor Class
|
33
|
+
|
34
|
+
The processor class is a standard Ruby class that obeys the following rules...
|
35
|
+
|
36
|
+
1. It takes a Hash of settings for the constructor parameter. These will be
|
37
|
+
passed down from the service when the class is instantiated.
|
38
|
+
|
39
|
+
2. It implements a ``process()`` method that takes a single parameter. This
|
40
|
+
parameter will be the message that was obtained from the queue. The
|
41
|
+
message has a ``body()`` accessor method that grants access to a ``String``
|
42
|
+
containing the message contents that are to be processed. The ``process()``
|
43
|
+
method should conduct whatever work is needed based on the message. If
|
44
|
+
processing of the message is complete then the ``process()`` method should
|
45
|
+
call the ``dispose()`` method of the message parameter received as this
|
46
|
+
informs the queuing mechanism that the message has been completely dealt
|
47
|
+
with and should not be issued to any other requesters.
|
48
|
+
|
49
|
+
### The Service
|
50
|
+
|
51
|
+
The service should follow this general structure...
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
require "qprocessor"
|
55
|
+
require "processor_class"
|
56
|
+
|
57
|
+
begin
|
58
|
+
processor = QProcessor::Processor.new(ProcessorClass, logger: logger)
|
59
|
+
processor.start
|
60
|
+
rescue => error
|
61
|
+
STDERR.puts "ERROR: #{error}\n#{error.backtrace.join("\n")}"
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
First thing this does is require in the qprocessor library and then the processor
|
66
|
+
class (as outlined in the previous section). Next it creates an instance of the
|
67
|
+
``QProcessor::Processor`` class, passing it at least two parameters. The first
|
68
|
+
parameter is a reference to the Processor class that will be used by this
|
69
|
+
instance to handle entries read from the queue. This should be an instance of
|
70
|
+
the ``Class`` class.
|
71
|
+
|
72
|
+
The constructor accepts additional parameters in the form of a ``Hash`` of
|
73
|
+
settings. These settings will be passed down to the processor class whenever
|
74
|
+
it gets instantiated but they may also be used by the queue processor
|
75
|
+
functionality itself. For example, if the settings include the key
|
76
|
+
``reuse_processor``, then the processor class will only be instantiated once
|
77
|
+
and then re-used for all messages. You can use this settings ``Hash`` to pass
|
78
|
+
value to the processing class that are reusable resources or that might include
|
79
|
+
configuration.
|
80
|
+
|
81
|
+
## Configuration
|
82
|
+
|
83
|
+
You need to provide the qprocessor service with details for the queue that it
|
84
|
+
will be working with. Currently supported queueing platforms include AQWS SQS
|
85
|
+
and Beanstalkd. Configuring which platform and which queue is used is done
|
86
|
+
through environment settings are outlined below...
|
87
|
+
|
88
|
+
### Beanstalkd
|
89
|
+
|
90
|
+
To use a Beanstalkd queue (tube) then you must set the ``BEANSTALK_URL``
|
91
|
+
environment setting. An example of this might be...
|
92
|
+
|
93
|
+
``beanstalk://host:port/tube_name``
|
94
|
+
|
95
|
+
### AWS SQS
|
96
|
+
|
97
|
+
To use the AWS SQS queuing platform you must set the ``SQS_QUEUE_NAME``
|
98
|
+
environment setting. Note that the Beanstalk configuration, if present, will
|
99
|
+
be used in preference to the SQS one - so don't configure both settings on
|
100
|
+
the same processor. The ``SQS_QUEUE_NAME`` environment variable can just be
|
101
|
+
the name of the SQS queue that will be used. The AWS SQS processor also needs
|
102
|
+
the ``AWS_ACCESS_KEY``, ``AWS_REGION`` and ``AWS_SECRET_KEY`` environment
|
103
|
+
variables set to appropriate values for use in getting access to the SQS
|
104
|
+
queue specified.
|
29
105
|
|
30
106
|
## Contributing
|
31
107
|
|
data/lib/qprocessor/processor.rb
CHANGED
@@ -7,28 +7,20 @@ module QProcessor
|
|
7
7
|
# processor that pulls work from a queue and passes it to an instance of a
|
8
8
|
# specified class for 'handling'.
|
9
9
|
class Processor
|
10
|
-
# A constant with the name of the default job parser class.
|
11
|
-
DEFAULT_PARSER_CLASS = "QProcessor::YAMLParser"
|
12
|
-
|
13
10
|
# A constant containing the maximum permitted setting for the inter-error sleep interval.
|
14
11
|
MAX_ERROR_RESTART_INTERVAL = 32
|
15
12
|
|
16
13
|
# Constructor for the Processor class.
|
17
14
|
#
|
18
|
-
# @param [
|
19
|
-
# @param [Hash] A Hash of the class names used by the processor. There are two
|
20
|
-
# keys recognised in this Hash - :parser and :processor. The
|
21
|
-
# :parser class should be the fully qualified name of the class
|
22
|
-
# class that can be used to parse job content. The :processor
|
23
|
-
# class should be the fully qualified name of the class that will
|
24
|
-
# process jobs.
|
15
|
+
# @param [Class] A reference to the class that will used to process jobs.
|
25
16
|
# @param [Hash] A Hash of additional settings that will be used by the processor.
|
26
|
-
#
|
27
|
-
|
17
|
+
# These will get passed to the processor class when it is
|
18
|
+
# instantiated and provides a mechansim for passing in elements
|
19
|
+
# such as configuration or settings.
|
20
|
+
def initialize(processor, settings={})
|
28
21
|
@instance = nil
|
29
|
-
@name = name
|
30
|
-
@
|
31
|
-
@processor_class = get_class!(class_names[:processor])
|
22
|
+
@name = processor.class.name
|
23
|
+
@processor_class = processor
|
32
24
|
@settings = {}.merge(settings)
|
33
25
|
@terminate = false
|
34
26
|
end
|
@@ -42,16 +34,7 @@ module QProcessor
|
|
42
34
|
while !@terminate
|
43
35
|
begin
|
44
36
|
logger.debug("The '#{name}' queue processor is listening for jobs.")
|
45
|
-
queue.get
|
46
|
-
begin
|
47
|
-
logger.debug "The '#{name}' queue processor received message id #{message.id}."
|
48
|
-
handle(message)
|
49
|
-
interval = 0
|
50
|
-
rescue => error
|
51
|
-
message.release
|
52
|
-
raise
|
53
|
-
end
|
54
|
-
end
|
37
|
+
queue.get {|message| handle(message)}
|
55
38
|
rescue => error
|
56
39
|
logger.error "The '#{name}' queue processor caught an exception.\nType: #{error.class.name}\n"\
|
57
40
|
"Message: #{error}\nStack Trace:\n#{error.backtrace.join("\n")}"
|
@@ -62,28 +45,38 @@ module QProcessor
|
|
62
45
|
end
|
63
46
|
end
|
64
47
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
48
|
+
def handle(message)
|
49
|
+
begin
|
50
|
+
logger.debug "The '#{name}' queue processor received message id #{message.id}."
|
51
|
+
process(message)
|
52
|
+
message.dispose
|
53
|
+
interval = 0
|
54
|
+
rescue => error
|
55
|
+
message.release
|
56
|
+
raise
|
57
|
+
end
|
69
58
|
end
|
70
59
|
|
71
|
-
|
72
|
-
result = get_class(name)
|
73
|
-
raise QProcessor::Error.new("Unable to locate the '#{class_name}' class.") if result.nil?
|
74
|
-
result
|
75
|
-
end
|
60
|
+
private
|
76
61
|
|
77
|
-
def
|
78
|
-
@instance = @processor_class.new(
|
79
|
-
logger: logger) if @instance.nil?
|
62
|
+
def process(job)
|
63
|
+
@instance = @processor_class.new(settings) if @instance.nil?
|
80
64
|
@instance.process(job)
|
81
65
|
@instance = nil if !settings.fetch(:reuse_processor, true)
|
82
66
|
end
|
83
67
|
|
84
68
|
def logger
|
85
|
-
|
69
|
+
if !settings.include?(:logger) || !settings[:logger]
|
70
|
+
settings[:logger] = Logger.new(STDOUT)
|
71
|
+
settings[:logger].level = logging_level
|
72
|
+
end
|
86
73
|
settings[:logger]
|
87
74
|
end
|
75
|
+
|
76
|
+
def logging_level
|
77
|
+
name = ENV["LOGGING_LEVEL"].to_s
|
78
|
+
name = "INFO" if name == "" || !Logger.const_defined?(name)
|
79
|
+
Logger.const_get(name)
|
80
|
+
end
|
88
81
|
end
|
89
82
|
end
|
@@ -63,15 +63,6 @@ module QProcessor
|
|
63
63
|
@aws_secret_key
|
64
64
|
end
|
65
65
|
|
66
|
-
def connection
|
67
|
-
if !@connection
|
68
|
-
url = beanstalk_url
|
69
|
-
raise "No BEANSTALK_URL environment variable set." if url.nil?
|
70
|
-
@connection ||= Beaneater.new(url)
|
71
|
-
end
|
72
|
-
@connection
|
73
|
-
end
|
74
|
-
|
75
66
|
# Fetches a Aws::SQS::Client instance using AWS credentials and region
|
76
67
|
# details that are read from environment settings. If any of these settings
|
77
68
|
# are missing an exception will be raised.
|
data/lib/qprocessor/version.rb
CHANGED
data/qprocessor.gemspec
CHANGED
@@ -32,6 +32,10 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_dependency "aws-sdk-sqs", "~> 1.49"
|
33
33
|
spec.add_dependency "aws-sdk-sts", "~> 1.5"
|
34
34
|
spec.add_dependency "beaneater", "~> 1.1"
|
35
|
+
spec.add_dependency "ox", "~> 2.14"
|
36
|
+
|
37
|
+
# Development dependency.
|
38
|
+
spec.add_development_dependency "rspec"
|
35
39
|
|
36
40
|
# For more information and examples about making a new gem, checkout our
|
37
41
|
# guide at: https://bundler.io/guides/creating_gem.html
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qprocessor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Wood
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-01-
|
11
|
+
date: 2022-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-sqs
|
@@ -52,6 +52,34 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: ox
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.14'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
description: A library to assist in the creation of queue processing 'application
|
56
84
|
as a service' entities.
|
57
85
|
email:
|
@@ -61,6 +89,7 @@ extensions: []
|
|
61
89
|
extra_rdoc_files: []
|
62
90
|
files:
|
63
91
|
- ".gitignore"
|
92
|
+
- ".rspec"
|
64
93
|
- CHANGELOG.md
|
65
94
|
- Gemfile
|
66
95
|
- Gemfile.lock
|