qprocessor 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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