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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: acc989a7981c73a9503e369c54b4c912f3dab1ca073c33d49a38c379db2c0b7b
4
- data.tar.gz: c408d6c67f41b2e0da1992aa8226d3b1bdd3e24c6ac9eda8bb91ed4010061af3
3
+ metadata.gz: 7e49f396b457d247ba22300439d134f4d663696f445a32dc36451fae46566602
4
+ data.tar.gz: 5ef52af86d0a282e5e633c156f7fcf3d1c08ccbb079cd0c5cb5f98eec3ab33ef
5
5
  SHA512:
6
- metadata.gz: 62068b04ecf60602b1094106c9fc0700659af07aa779b8f4b89e608a81f95e60fd29ef93257eee67f2cd0e1fa271bf25717017beed998b3b133c45a86f2e3d5d
7
- data.tar.gz: ddeb4a8105387ec43a35a07edae349f6952a71e9b15d64b6e03b6bf0414bccfa57523067984610c36ef8422ff745358ac56ccd20e3c77c469e5006c30df6ac44
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.2.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.548.0)
14
- aws-sdk-core (3.125.3)
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. Initial
4
- implementation will work with Beanstalkd, though I might expand it to cover other
5
- types of queue later. The idea behind this gem is to allow for the easy creation
6
- of an application as a service, where the services job is to pull items from a
7
- queue and process them. The library code is intended to wrap the parts of the code
8
- that would be common and repeated if you made individual service applications.
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
- TODO: Write usage instructions here
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
 
@@ -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 [String] The name assigned to the processor, primarily used for logging.
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
- # Valid keys include :logger and :reuse_processor.
27
- def initialize(name, class_names, settings={})
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
- @parser_class = get_class!(class_names.fetch(:parser, DEFAULT_PARSER_CLASS))
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 do|message|
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
- private
66
-
67
- def get_class(name)
68
- name.split("::").reduce(Object) {|t, e| (!t.nil? ? t.const_get(e) : nil)}
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
- def get_class!(name)
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 handle(job)
78
- @instance = @processor_class.new(parser: @parser_class.new(logger: logger),
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
- settings[:logger] = Logger.new(STDOUT) if !settings.include?(:logger) || !settings[:logger]
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.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module QProcessor
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
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.2.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-14 00:00:00.000000000 Z
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