hoze 0.1.0 → 0.2.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
  SHA1:
3
- metadata.gz: 13ccaea71486a72b78f2c505eee8c33f6262ef22
4
- data.tar.gz: 101857b73c29bfc24f96b8be3392fe76f2708da2
3
+ metadata.gz: 53fef088aa9de3cf52f33960c03effe4f2f20be1
4
+ data.tar.gz: 9d779070f50f18d770c5738bdd70045c4bdff96c
5
5
  SHA512:
6
- metadata.gz: bf093a19e8b9f0633d73e19ae631dad346a323fd8ec5cc4174ae1040520d4ab3b98b1831fbac6cb91d0df1610796b67533ced7d8377f8f50d80a6d74b8d6f72c
7
- data.tar.gz: b820e09cf639dc65e49cf919ad0859d49a13a2bdc6919125dde6765ad2d01991530809ac847b3ce419e1666d834749b5ceb7f9f3d95ec1a98092dcb55c6cdf26
6
+ metadata.gz: b24fcb64027938e64d59d40e7d2801ac474d62bff4527cdb68364f1e89b3039bec9f9b2d219685eb4afbe1f6437d217c1916b14dec9c89df95aea90b208d3009
7
+ data.tar.gz: 58e8cd2d9fd52c54542055a3c341ebf1455ebe2f0d4d0c7f20ca63142348d9064511cc210f09f51eadd5b2734c9fdf31d92e46e36d1799368305973ebe323124
data/README.md CHANGED
@@ -16,11 +16,13 @@ And then execute:
16
16
 
17
17
  ## Usage
18
18
 
19
+ ### Basic usage
20
+
19
21
  Write a simple worker file `worker.rb`:
20
22
 
21
23
  ```ruby
22
24
  Hoze.worker
23
- .configure do |config|
25
+ .listen_to do |config| # Define where to find messages
24
26
  # You can use env variable for each property to overload hardcoded values
25
27
  config.channel = "my.pubsub.topic" # HOZE_CONFIG_CHANNEL
26
28
  config.key = "my.subscription.name" # HOZE_CONFIG_KEY
@@ -28,9 +30,18 @@ Hoze.worker
28
30
  config.connector.project = "my-gcp-project" # HOZE_CONFIG_CONNECTOR_PROJECT
29
31
  config.connector.path_to_key = "/path/to/keyfile.json" # HOZE_CONFIG_CONNECTOR_PATH_TO_KEY
30
32
  end
31
- .process do |message|
33
+ .process do |message| # Define job function
32
34
  puts "Hello #{message.payload} !"
35
+ "my result"
36
+ end
37
+ .push_to do |config| # Define where to push job result
38
+ # You can use env variable for each property to overload hardcoded values
39
+ config.channel = "my.other.pubsub.topic" # HOZE_CONFIG_DEST_CHANNEL
40
+ config.connector.type = "pubsub" # HOZE_CONFIG_CONNECTOR_DEST_TYPE
41
+ config.connector.project = "my-gcp-project" # HOZE_CONFIG_CONNECTOR_DEST_PROJECT
42
+ config.connector.path_to_key = "/path/to/keyfile.json" # HOZE_CONFIG_CONNECTOR_DEST_PATH_TO_KEY
33
43
  end
44
+ .go!
34
45
  ```
35
46
 
36
47
  And now run it:
@@ -39,6 +50,95 @@ And now run it:
39
50
  bundle exec hoze worker.rb
40
51
  ```
41
52
 
53
+ It'll now listen to `my.subscription.name` for any message, print the payload to `STDOUT` then push the message `my result` to `my.other.pubsub.topic`.
54
+
55
+ ### Acknowledgement, delay and rejection
56
+
57
+ By default, messages must be acknowledged explicitly. If messages are not acked before a time depending on the source implementation, they'll be sent again to the subscribers. Your worker may ask for more time before the timeout expires if the processing is known to be long. It may also `reject` a message, telling the source it won't process it and then sending it bck to its queue.
58
+ You may also define an automatic acknowledgement if you don't want to handle this by hand.
59
+
60
+ #### Auto-ack
61
+
62
+ ```ruby
63
+ Hoze.worker
64
+ .listen_to do |config|
65
+ # ...
66
+ config.auto_ack = true # Will ack the message as soon as it is received
67
+ end
68
+ .process do |message|
69
+ # ...
70
+ end
71
+ .go!
72
+ ```
73
+
74
+ #### Manual ack
75
+
76
+ ```ruby
77
+ Hoze.worker
78
+ .listen_to do |config|
79
+ # ...
80
+ end
81
+ .process do |message|
82
+ # ...
83
+ message.ack!
84
+ end
85
+ .go!
86
+ ```
87
+
88
+ #### Delay and rejection
89
+
90
+ ```ruby
91
+ Hoze.worker
92
+ .listen_to do |config|
93
+ # ...
94
+ end
95
+ .process do |message|
96
+ # pretty long processing
97
+ message.delay! 10 # asking for 10 more seconds
98
+ # continue long processing
99
+ message.reject! # finally reject the message
100
+ end
101
+ .go!
102
+ ```
103
+
104
+ ### Retries
105
+
106
+ Failed processing may be retried. Set the config variable `max_tries` to tell how many times it's gonna be tried before it's considered dead.
107
+
108
+ ```ruby
109
+ Hoze.worker
110
+ .listen_to do |config|
111
+ # ...
112
+ config.max_tries = 5
113
+ end
114
+ .process do |message|
115
+ # Failable processing
116
+ end
117
+ .go!
118
+ ```
119
+
120
+ *Beware* the retry system is still alpha. Messages will be pushed back immediately in the queue with a `tries` metadata recording the tries count. Dead messages will just be logged.
121
+
122
+ ### Metadata transfer
123
+
124
+ When the result is pushed to another topic, original message's metadata are transfered along. They can be modified in the `process` block:
125
+
126
+ ```ruby
127
+ Hoze.worker
128
+ .listen_to do |config|
129
+ # ...
130
+ end
131
+ .process do |message|
132
+ message.metadata[:who_is_the_best] = "I am the best"
133
+ "my result"
134
+ end
135
+ .push_to do |config|
136
+ # ...
137
+ end
138
+ .go!
139
+ ```
140
+
141
+
42
142
  ## Development
43
143
 
44
144
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -5,8 +5,9 @@ module Hoze
5
5
  class Configuration
6
6
  attr_accessor :channel, :key, :auto_ack, :connector, :max_tries
7
7
 
8
- def initialize
9
- @connector = ConnectorConfiguration.new
8
+ def initialize prefix = nil
9
+ @connector = ConnectorConfiguration.new prefix
10
+ @prefix = prefix
10
11
  end
11
12
 
12
13
  def channel
@@ -20,7 +21,8 @@ module Hoze
20
21
  private
21
22
 
22
23
  def env_config name
23
- return ENV["HOZE_CONFIG_#{name}"]
24
+ key = ["HOZE","CONFIG",@prefix,name].join('_')
25
+ return ENV[key]
24
26
  end
25
27
 
26
28
  end
@@ -28,6 +30,10 @@ module Hoze
28
30
  class ConnectorConfiguration
29
31
  attr_accessor :type, :project, :path_to_key
30
32
 
33
+ def initialize prefix = nil
34
+ @prefix = prefix
35
+ end
36
+
31
37
  def type
32
38
  env_config('TYPE') || @type
33
39
  end
@@ -43,7 +49,8 @@ module Hoze
43
49
  private
44
50
 
45
51
  def env_config name
46
- return ENV["HOZE_CONFIG_CONNECTOR_#{name}"]
52
+ key = ["HOZE","CONFIG","CONNECTOR",@prefix,name].join('_')
53
+ return ENV[key]
47
54
  end
48
55
  end
49
56
 
@@ -7,6 +7,10 @@ module Hoze
7
7
  def listen &block
8
8
  raise NotImplementedError.new("This source implementation doesn't support listen method.")
9
9
  end
10
+
11
+ def push payload, metadata
12
+ raise NotImplementedError.new("This source implementation doesn't support push method.")
13
+ end
10
14
 
11
15
  end
12
16
 
@@ -0,0 +1,4 @@
1
+ module Hoze
2
+ class SourceError < Exception
3
+ end
4
+ end
@@ -1,4 +1,5 @@
1
1
  require "hoze/interface/source"
2
+ require "hoze/interface/source_error"
2
3
  require "hoze/pubsub/message"
3
4
 
4
5
  module Hoze
@@ -24,7 +25,7 @@ module Hoze
24
25
 
25
26
 
26
27
  def listen &block
27
- #puts @subscription.inspect
28
+ raise HozeSourceError.new("Tryng to listen source but no key configured") if @key.nil?
28
29
  subscriber = @subscription.listen do |received_message|
29
30
  begin
30
31
  msg = Hoze::PubSubMessage.new(received_message, self)
@@ -46,15 +47,22 @@ module Hoze
46
47
  subscriber.stop.wait!
47
48
  end
48
49
  end
50
+
51
+ def push payload, metadata
52
+ @topic.publish_async payload, metadata
53
+ end
49
54
 
50
55
  private
51
56
 
52
57
  def ensure_topic
53
- @engine.topic(@channel)||@engine.create_topic(@channel)
58
+ raise HozeSourceError.new("No topic configured for source") if @channel.nil?
59
+ @engine.topic(@channel) || @engine.create_topic(@channel)
54
60
  end
55
61
 
56
62
  def ensure_subscription
57
- @topic.subscription(@key)||@topic.subscribe(@key)
63
+ return nil if @key.nil?
64
+ subname = [@channel,@key].join('+')
65
+ @topic.subscription(subname) || @topic.subscribe(subname)
58
66
  end
59
67
 
60
68
  end
@@ -1,3 +1,3 @@
1
1
  module Hoze
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -11,23 +11,38 @@ module Hoze
11
11
  attr_accessor :source_factory
12
12
 
13
13
  def initialize
14
- @configuration = Hoze::Configuration.new
14
+ @source_config = Hoze::Configuration.new
15
15
  @source_factory = Hoze::SourceFactory.new
16
16
  end
17
17
 
18
- def configure &block
19
- yield @configuration
20
- puts "Configuration is: #{@configuration.inspect}"
18
+ def listen_to &block
19
+ yield @source_config
20
+ puts "Source Configuration is: #{@source_config.inspect}"
21
21
  self
22
22
  end
23
23
 
24
- def process &block
25
- source = @source_factory.build(@configuration)
26
-
27
- source.listen do |msg|
24
+ def push_to &block
25
+ @destination_config = Hoze::Configuration.new 'DEST'
26
+ yield @destination_config
27
+ puts "Destination Configuration is: #{@destination_config.inspect}"
28
+ self
29
+ end
30
+
31
+ def process &block
32
+ @process_fn = Proc.new do |msg|
33
+ yield msg
34
+ end
35
+ self
36
+ end
37
+
38
+ def go!
39
+ @source = @source_factory.build(@source_config)
40
+ @destination = @source_factory.build(@destination_config) if @destination_config
41
+ @source.listen do |msg|
28
42
  begin
29
- msg.ack! if @configuration.auto_ack
30
- result = yield msg
43
+ msg.ack! if @source_config.auto_ack
44
+ result = @process_fn.call msg
45
+ @destination.push result, msg.metadata if @destination
31
46
  rescue Exception => e
32
47
  msg.retry!
33
48
  raise e
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoze
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - pluce
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-03-05 00:00:00.000000000 Z
11
+ date: 2018-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -90,6 +90,7 @@ files:
90
90
  - lib/hoze/configuration.rb
91
91
  - lib/hoze/interface/message.rb
92
92
  - lib/hoze/interface/source.rb
93
+ - lib/hoze/interface/source_error.rb
93
94
  - lib/hoze/pubsub/message.rb
94
95
  - lib/hoze/pubsub/source.rb
95
96
  - lib/hoze/source_factory.rb