postqueue 0.5.3 → 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +181 -112
- data/lib/postqueue/queue.rb +18 -1
- data/lib/postqueue/queue/callback.rb +2 -4
- data/lib/postqueue/queue/logging.rb +8 -5
- data/lib/postqueue/queue/processing.rb +1 -1
- data/lib/postqueue/queue/timing.rb +3 -0
- data/lib/postqueue/version.rb +1 -1
- metadata +7 -5
- data/lib/postqueue/railtie.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 323c108f2c06eaaa629dd218e0e2483252b44c3e
|
4
|
+
data.tar.gz: c3c5521cf196e4b68bf835d1a00da1cd40c2e612
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e0991a54661b6ca09325e1a490ddb5f4dd71fb320188cd8d3aea49890aa03ffe8740f31f1e98a1015b4d7634e3735c2af0b68747bbaa52d21ddce2003e81e38
|
7
|
+
data.tar.gz: 645df66d57f05fd2f7f7a33d0798b4aa33faacfe72f84a1bebbe3d7678e520024806801aaa90ddd672400cf0b8ee2b0dda7d18755ace559a602e8e2e96d27c6f
|
data/README.md
CHANGED
@@ -1,116 +1,181 @@
|
|
1
1
|
# Postqueue
|
2
2
|
|
3
|
-
|
3
|
+
The `postqueue` gem implements a simple to use queue on top of postgresql.
|
4
4
|
|
5
|
-
|
6
|
-
a queue like this is typically used in a job queueing scenario, this document does not
|
7
|
-
talk about jobs, it talks about **queue items**; it also does not schedule a job,
|
8
|
-
it **enqueues** an item, and it does not executes a job, it **processes** queue items.
|
5
|
+
Lets have a word about words first: while a queue like this is typically used for job queues, this document does not talk about jobs, it talks about **queue items**; we also do not schedule jobs, we **enqueues** items, and we don't executes a job, we **processes** queue items instead.
|
9
6
|
|
10
|
-
|
11
|
-
usual suspects postqueue implements these features:
|
7
|
+
So, why building an additional queue implementation? Compared to the usual suspects this is what postqueue brings to the table:
|
12
8
|
|
13
|
-
- The item structure is intentionally kept
|
14
|
-
`op` field - a string - and an `id` field, an integer. In a typical usecase a
|
15
|
-
queue item would describe an operation on a specific entity, where `op` names
|
16
|
-
both the operation and the entity type and the `id` field would describe the
|
17
|
-
individual entity.
|
9
|
+
- The **item structure** is intentionally kept very **simple**: an item is described by an `op` field - a string - and an `id` field, an integer. In a typical usecase a queue item would describe an operation on a specific entity, and `op` would name both the operation and the entity type (say: `"product/invalidate"`) and the `id` field would hold the id of the product to invalidate.
|
18
10
|
|
19
|
-
-
|
20
|
-
otherwise evaluated using SQL. This also allows for **skipping duplicate entries**
|
21
|
-
when enqueuing items (managed via a duplicate: argument when enqueuing) and for
|
22
|
-
**batch processing** multple items in one go.
|
11
|
+
- Such a simplistic item structure lends quite well to **querying** the queue **using SQL**. While this is great for monitoring purposes - it is quite easy to fetch metrics regarding upcoming items - it also allows special handling of idempotent operations and automatic batching.
|
23
12
|
|
24
|
-
-
|
25
|
-
an item failing to process stays in the queue. Error handling is kept simpe to a
|
26
|
-
strategy of rescheduling items up to a specific maximum number of processing attemps.
|
13
|
+
- Some tasks typically handled by queues are of **idempotent** nature. For example, reindexing a document into a NoSQL search index needs not be done twice in a row, since only the last change to the primary object should and ultimately will be stored in the search index. Such tasks can therefore be run only once. postqueue supports this feature by optionally skipping duplicates when enqueuing tasks.
|
27
14
|
|
28
|
-
|
29
|
-
|
15
|
+
- Other tasks can be handled much more efficient when **run in batches**. Typical examples include processing a larger number of entities that need to be read from a database, but could be pulled much more efficient in a single query instead of in N queries. postqueue automatically batches such items.
|
16
|
+
|
17
|
+
- Being based on Postgresql postqueue provides **transactional semantics**: an item written into the database in a transaction that fails afterwards is never processed.
|
18
|
+
|
19
|
+
- **automatic retries**: like delayed job postqueue implements a rudimentary form of error processing. A failing item - this is an item which does not have a handler registered, or whose handler fails by raising an exception - is kept in the queue and reprocessed later. It is reprocessed up to N times (currently 5 times by default) until it is "doomed" ultimately. This is similar to delayed job's error handling, with some differences, however:
|
20
|
+
|
21
|
+
- no backtrace is kept in the database
|
22
|
+
- the waiting time doesn't ramp up as fast (postqueue does `1.5 ** <number of retries>`)
|
23
|
+
|
24
|
+
Please be aware that postqueue is using the `SELECT .. FOR UPDATE SKIP LOCKED` Postgresql syntax, and therefore needs at least PostgresQL >= 9.5.
|
30
25
|
|
31
26
|
## Basic usage
|
32
27
|
|
28
|
+
Postqueue is able to run queues that use separate tables as their backstore, or use a preexisting table. However, basic usage should cover most scenarios.
|
29
|
+
|
30
|
+
Hence we cover the basic scenario here: in that scenario a single table *"postqueue"* is used to store queue items, and the `Postqueue` default queue holds all configuration. We also assume that you want to integrate Postqueue with a Rails application.
|
31
|
+
|
32
|
+
## Installation
|
33
|
+
|
34
|
+
Add this line to your application's Gemfile:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gem 'postqueue'
|
38
|
+
```
|
39
|
+
|
40
|
+
And then execute:
|
41
|
+
|
42
|
+
$ bundle
|
43
|
+
|
44
|
+
### Adding a migration
|
45
|
+
|
46
|
+
The following migration creates a postqueue table with all necessary entries:
|
47
|
+
|
33
48
|
```ruby
|
34
|
-
|
35
|
-
|
36
|
-
|
49
|
+
class AddPostqueue < ActiveRecord::Migration
|
50
|
+
def up
|
51
|
+
Postqueue.migrate!
|
52
|
+
end
|
53
|
+
|
54
|
+
def down
|
55
|
+
Postqueue.unmigrate!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
### Configuring Postqueue
|
61
|
+
|
62
|
+
The postqueue configuration descrives all possible operations and their features:
|
63
|
+
|
64
|
+
- is it possible to batch these operationss? In that case multiple queue items will be combined and processed in one go. Set `batch_size:` to a sensible size.
|
65
|
+
- is this an idempotent operation? Set `idempotent:` to true.
|
66
|
+
|
67
|
+
The configuration file should live in `config/initializer/postqueue.rb` for Rails apps, and in `config/postqueue.rb` in other Ruby applications.
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
# config/initializer/postqueue.rb
|
71
|
+
Postqueue.on "refresh", batch_size: 10, idempotent: true do |op, entity_ids|
|
37
72
|
Product.index_many(Product.where(id: entity_ids))
|
38
73
|
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Note that you could define an operation without a handler callback:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
Postqueue.on "foo"
|
80
|
+
```
|
81
|
+
|
82
|
+
In this case the `foo` ops are just removed from the queue during procesing.
|
83
|
+
|
84
|
+
### Postqueue database configuration
|
85
|
+
|
86
|
+
When run from inside a Rails application Postqueue will reuse the applications database connection. When run outside a Rails application postqueue will use a
|
87
|
+
`config/database.yml` file to determine database connection settings. It will use the `RAILS_ENV` environment value, defaulting to `"development"`, to choose from entries in that file.
|
88
|
+
|
89
|
+
### Enqueueing items
|
90
|
+
|
91
|
+
Enqueuing items can be done using code like this:
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
# enqueue a single op
|
95
|
+
Postqueue.enqueue op: "refresh", entity_id: 12
|
39
96
|
|
40
|
-
|
97
|
+
# enqueue multiple ops in one go.
|
98
|
+
Postqueue.enqueue op: "refresh", entity_id: [12,13]
|
99
|
+
Postqueue.enqueue op: "refresh", entity_id: [13,14]
|
41
100
|
```
|
42
101
|
|
43
|
-
|
44
|
-
the same `op` attribute. The callback will receive the `op` attribute and the `entity_ids`
|
45
|
-
of all queue entries selected for processing. The `processing` method will return the number
|
46
|
-
of processed items.
|
102
|
+
Note that enqueueing is pretty fast. My developer machine is able to enqueue ~20000 items per second.
|
47
103
|
|
48
|
-
|
49
|
-
any processing.
|
104
|
+
### Processing items
|
50
105
|
|
51
|
-
|
106
|
+
While we recommend to use the command line interface to process postqueue items you can certainly process these *from within ruby code* by using one of these methods:
|
107
|
+
|
108
|
+
# process the next batch of items
|
109
|
+
Postqueue.process
|
110
|
+
|
111
|
+
# process a single item, do not batch
|
112
|
+
Postqueue.process_one
|
113
|
+
|
114
|
+
# process batches of items until there are none left
|
115
|
+
Postqueue.process_until_empty
|
116
|
+
|
117
|
+
These calls will select a one or more queue items for processing (with the same `op` attribute). The `process_*` methods will then call the callback for that operation with the `entity_ids` of all queue entries. After processing they will return the number of processed items, or 0 if no items could be found or be processed.
|
118
|
+
|
119
|
+
The `process_*` methods also accept the following arguments:
|
52
120
|
|
53
121
|
- `op`: only process entries with this `op` value;
|
54
122
|
- `batch_size`: maximum number of items to process in one go.
|
55
123
|
|
56
124
|
Example:
|
57
125
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
If the block raises an exception the queue will postpone processing these entries
|
63
|
-
by an increasing amount of time, up until `queue.max_attempts` failed attempts.
|
64
|
-
That value defaults to 5.
|
126
|
+
# process only `product` queue items
|
127
|
+
Postqueue.process(op: 'product', batch_size: 10)
|
65
128
|
|
66
|
-
|
67
|
-
returns 0.
|
129
|
+
### processing from the command line
|
68
130
|
|
69
|
-
|
70
|
-
|
71
|
-
|
131
|
+
```ruby
|
132
|
+
bundle exec postqueue run
|
133
|
+
```
|
72
134
|
|
73
|
-
|
135
|
+
starts a single postqueue runner. Note that there is intentionally no option to daemonize this process or to run these in parallel.
|
74
136
|
|
75
|
-
|
76
|
-
- multiple consumers can work in parallel.
|
137
|
+
The postqueue CLI has additional commands, see below.
|
77
138
|
|
78
|
-
|
79
|
-
process objects with the identical configuration.
|
139
|
+
## The postqueue CLI
|
80
140
|
|
81
|
-
|
141
|
+
postqueue comes with a command line interface:
|
82
142
|
|
83
|
-
|
84
|
-
|
143
|
+
```
|
144
|
+
~/postqueue[master] > ./bin/postqueue --help
|
145
|
+
This is postqueue 0.5.3. Usage examples:
|
146
|
+
|
147
|
+
postqueue [ stats ]
|
148
|
+
postqueue peek
|
149
|
+
postqueue enqueue op entity_id,entity_id,entity_id
|
150
|
+
postqueue run
|
151
|
+
postqueue help
|
152
|
+
postqueue process
|
153
|
+
```
|
85
154
|
|
86
|
-
|
87
|
-
queue.on "idempotent", idempotent: true do ]op, entity_ids|
|
88
|
-
# .. handle queue item
|
89
|
-
end
|
90
|
-
end
|
155
|
+
You can use the postqueue CLI to
|
91
156
|
|
92
|
-
|
157
|
+
- enqueue an item, e.g. `bundle exec postqueue enqueue foo 1,2,3`
|
158
|
+
- start a runner to process the queue: `bundle exec postqueue run`
|
159
|
+
- process a single item off the queue: `bundle exec postqueue process`
|
160
|
+
- get some stats for the queue: `bundle exec postqueue stats`
|
161
|
+
- get a list of the next 100 queue items: `bundle exec postqueue peek`
|
93
162
|
|
94
|
-
|
95
|
-
calls `Postqueue.process` with `batch_size` set to `1`:
|
163
|
+
## Additional notes
|
96
164
|
|
97
|
-
|
165
|
+
### Concurrency
|
98
166
|
|
99
|
-
|
100
|
-
`entity_ids` parameter to the callback is still an array (with a single ID entry
|
101
|
-
in that case).
|
167
|
+
Postqueue implements the following concurrency guarantees:
|
102
168
|
|
103
|
-
|
169
|
+
- catastrophic DB failure and communication breakdown aside a queue item which is enqueued will eventually be processed successfully exactly once;
|
170
|
+
- multiple consumers can work in parallel.
|
104
171
|
|
105
|
-
Postqueue
|
172
|
+
Note that you should not share a Postqueue instance across threads - instead you should create process objects with the identical configuration.
|
106
173
|
|
107
|
-
|
108
|
-
Postqueue.migrate!(table_name = "postqueue")
|
174
|
+
### Idempotent operations
|
109
175
|
|
110
|
-
|
111
|
-
Postqueue.unmigrate!(table_name = "postqueue")
|
176
|
+
If an operation was configured as idempotent (using the `Postqueue.on "op", idempotent: true` configuration) duplicate idempotent operations are not enqueued. However, if multiple transactions are enqueueing items at the same time, or when an idempotent item is processing while another item is being enqueued an additional queue item will still be enqueued. Therefore we also remove duplicate items during processing.
|
112
177
|
|
113
|
-
|
178
|
+
### Using non-default tables or databases
|
114
179
|
|
115
180
|
To use a non-default table or a non-default database, change the `item_class`
|
116
181
|
attribute of the queue:
|
@@ -119,72 +184,76 @@ attribute of the queue:
|
|
119
184
|
queue.item_class = MyItemClass
|
120
185
|
end
|
121
186
|
|
122
|
-
`MyItemClass` should inherit from Postqueue::Item and use the same or a compatible database
|
123
|
-
structure.
|
187
|
+
`MyItemClass` should inherit from Postqueue::Item and use the same or a compatible database structure.
|
124
188
|
|
125
|
-
|
189
|
+
### Special Ops
|
126
190
|
|
127
|
-
|
128
|
-
processing for some items, configure the Postqueue to either set a `default_batch_size`
|
129
|
-
or an operation-specific batch_size:
|
191
|
+
Postqueue always registers the following operations:
|
130
192
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
193
|
+
- `"test"` will write an output to the Postqueue.logger. Use this to test your infrastructure.
|
194
|
+
- `"fail"` will always raise an exception. Use this to test your error handling integration.
|
195
|
+
|
196
|
+
### Unknown operations
|
197
|
+
|
198
|
+
You can define a handler to handle unknown operations like this:
|
199
|
+
|
200
|
+
on :missing_handler do |op, entity_ids|
|
201
|
+
raise MissingHandler, queue: self, op: op, entity_ids: entity_ids
|
136
202
|
end
|
137
203
|
|
138
|
-
|
204
|
+
### Exception handling
|
139
205
|
|
140
|
-
|
141
|
-
and must be picked up later explicitely for processing (via one of the `process`, `process_one` or `process_until_empty` methods).
|
206
|
+
You can define a handler to handle any exceptions. This is the integration point for your exception handling framework like rollbar.com or so.
|
142
207
|
|
143
|
-
|
144
|
-
if you are interested in actual processing - or, at least, in a mode which validates that
|
145
|
-
the `op` value is valid (that means that a handler is registered for that op). You can
|
146
|
-
change the processing mode via
|
208
|
+
The default exception handler is:
|
147
209
|
|
148
|
-
|
149
|
-
|
210
|
+
Postqueue.on_exception do |e, _, _|
|
211
|
+
e.send :raise
|
212
|
+
end
|
150
213
|
|
151
|
-
|
214
|
+
The following would report exceptions to STDOUT and to rollbar:
|
152
215
|
|
153
|
-
Postqueue.
|
154
|
-
|
216
|
+
Postqueue.on_exception do |e, op, entity_ids|
|
217
|
+
msg = "Caught error #{e.to_s.inspect}"
|
218
|
+
msg += " on op: #{op.inspect} "
|
219
|
+
msg += " w/entity_ids: #{entity_ids.inspect}"
|
220
|
+
Rollbar.error(e)
|
155
221
|
end
|
156
222
|
|
157
|
-
|
223
|
+
### `after_processing` callback
|
158
224
|
|
159
|
-
|
225
|
+
After a batch of operations is processed, Postqueue calls the `after_processing` callback. It receives the `op` and `entity_ids` from the current processing run, and a `timing` object, which has these attributes:
|
160
226
|
|
161
|
-
|
162
|
-
|
163
|
-
|
227
|
+
- Timing#avg_queue_time: the average queueing time for all item in the batch;
|
228
|
+
- Timing#max_queue_time: the maximum queueing time of any item in the batch;
|
229
|
+
- Timing#processing_time: elapsed time for processing the batch.
|
164
230
|
|
165
|
-
|
231
|
+
The default `after_processing` callback simply logs all information. You can
|
232
|
+
easily use your own:
|
166
233
|
|
167
|
-
|
234
|
+
Postqueue.after_processing do |op, entity_ids, timing|
|
235
|
+
processing_time = timing.processing_time
|
236
|
+
Postqueue.logger.info "#{op] processing #{entity_ids.length}: #{'%.3f secs' % processing_time}"
|
237
|
+
end
|
238
|
+
|
239
|
+
## Testing postqueue applications
|
240
|
+
|
241
|
+
Postqueue works usually in an async mode: queue items that are enqueued are kept in a queue, and must be picked up later explicitely for processing (via one of the `process`, `process_one` or `process_until_empty` methods).
|
168
242
|
|
169
|
-
|
243
|
+
During unit tests it is likely preferrable to process queue items synchronously - if you are interested in actual processing - or, at least, in a mode which validates that the `op` value is actually configured in your application (i.e. that a handler is registered for that op). You can change the processing mode via
|
170
244
|
|
171
|
-
|
245
|
+
# can be :sync, :async, :verify
|
246
|
+
Postqueue.processing = :sync
|
172
247
|
|
173
248
|
## Development
|
174
249
|
|
175
|
-
After checking out the repo, run `bin/setup` to install dependencies. Make sure you have
|
176
|
-
a local postgresql implementation of at least version 9.5. Add a `postqueue` user with
|
177
|
-
a `postqueue` password, and create a `postqueue_test` database for it. The script
|
178
|
-
`./scripts/prepare_pg` can be somewhat helpful in establishing that.
|
250
|
+
After checking out the repo, run `bin/setup` to install dependencies. Make sure you have a local postgresql implementation of at least version 9.5. Add a `postqueue` user with a `postqueue` password, and create a `postqueue_test` database for it. The script `./scripts/prepare_pg` can be somewhat helpful in establishing that.
|
179
251
|
|
180
|
-
Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive
|
181
|
-
prompt that will allow you to experiment.
|
252
|
+
Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
182
253
|
|
183
254
|
To install this gem onto your local machine, run `bundle exec rake install`.
|
184
255
|
|
185
|
-
To release a new version, run `./scripts/release`, which will bump the version number,
|
186
|
-
create a git tag for the version, push git commits and tags, and push the `.gem` file
|
187
|
-
to [rubygems.org](https://rubygems.org).
|
256
|
+
To release a new version, run `./scripts/release`, which will bump the version number, create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
188
257
|
|
189
258
|
## Contributing
|
190
259
|
|
data/lib/postqueue/queue.rb
CHANGED
@@ -45,11 +45,27 @@ module Postqueue
|
|
45
45
|
raise MissingHandler, queue: self, op: op, entity_ids: entity_ids
|
46
46
|
end
|
47
47
|
|
48
|
+
set_default_callbacks
|
49
|
+
|
50
|
+
yield self if block
|
51
|
+
end
|
52
|
+
|
53
|
+
def set_default_callbacks
|
48
54
|
on_exception do |e, _, _|
|
49
55
|
e.send :raise
|
50
56
|
end
|
51
57
|
|
52
|
-
|
58
|
+
after_processing do |op, entity_ids, timing|
|
59
|
+
processing_time = timing.processing_time
|
60
|
+
avg_queue_time = timing.avg_queue_time
|
61
|
+
max_queue_time = timing.max_queue_time
|
62
|
+
|
63
|
+
msg = "processing '#{op}' for id(s) #{entity_ids.join(',')}: "
|
64
|
+
msg += "processing #{entity_ids.length} items took #{'%.3f secs' % processing_time}"
|
65
|
+
msg += ", queue_time: #{'%.3f secs (avg)' % avg_queue_time}/#{'%.3f secs (max)' % max_queue_time}"
|
66
|
+
|
67
|
+
Postqueue.logger.info msg
|
68
|
+
end
|
53
69
|
end
|
54
70
|
|
55
71
|
def batch_size(op:)
|
@@ -83,3 +99,4 @@ require_relative "queue/processing"
|
|
83
99
|
require_relative "queue/callback"
|
84
100
|
require_relative "queue/logging"
|
85
101
|
require_relative "queue/runner"
|
102
|
+
require_relative "queue/timing"
|
@@ -14,8 +14,6 @@ module Postqueue
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class Queue
|
17
|
-
Timing = Struct.new(:avg_queue_time, :max_queue_time, :total_processing_time, :processing_time)
|
18
|
-
|
19
17
|
def assert_valid_op!(op)
|
20
18
|
return if op == :missing_handler
|
21
19
|
return if op.is_a?(String)
|
@@ -58,12 +56,12 @@ module Postqueue
|
|
58
56
|
SQL
|
59
57
|
queue_time = queue_times.first
|
60
58
|
|
61
|
-
|
59
|
+
processing_time = Benchmark.realtime do
|
62
60
|
callback = callback_for(op: op) || callbacks.fetch(:missing_handler)
|
63
61
|
callback.call(op, entity_ids)
|
64
62
|
end
|
65
63
|
|
66
|
-
Timing.new(queue_time.avg, queue_time.max,
|
64
|
+
Timing.new(queue_time.avg, queue_time.max, processing_time)
|
67
65
|
end
|
68
66
|
end
|
69
67
|
end
|
@@ -3,12 +3,15 @@ module Postqueue
|
|
3
3
|
class Queue
|
4
4
|
private
|
5
5
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
6
|
+
def after_processing(&block)
|
7
|
+
if block
|
8
|
+
@after_processing = block
|
9
|
+
if block.arity > -3 && block.arity != 3
|
10
|
+
raise ArgumentError, "Invalid after_processing block: must accept 3 arguments"
|
11
|
+
end
|
12
|
+
end
|
9
13
|
|
10
|
-
|
11
|
-
logger.info msg
|
14
|
+
@after_processing
|
12
15
|
end
|
13
16
|
|
14
17
|
def log_exception(exception, op, entity_ids)
|
@@ -36,7 +36,7 @@ module Postqueue
|
|
36
36
|
entity_ids = items.map(&:entity_id)
|
37
37
|
timing = run_callback(op: match.op, entity_ids: entity_ids)
|
38
38
|
|
39
|
-
|
39
|
+
after_processing.call(match.op, entity_ids, timing)
|
40
40
|
item_class.where(id: items.map(&:id)).delete_all
|
41
41
|
|
42
42
|
# even though we try not to enqueue duplicates we cannot guarantee that,
|
data/lib/postqueue/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -150,7 +150,8 @@ dependencies:
|
|
150
150
|
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '0'
|
153
|
-
description:
|
153
|
+
description: simplistic postgresql based queue with support for batching and idempotent
|
154
|
+
operations
|
154
155
|
email:
|
155
156
|
- radiospiel@open-lab.org
|
156
157
|
executables:
|
@@ -175,7 +176,7 @@ files:
|
|
175
176
|
- lib/postqueue/queue/processing.rb
|
176
177
|
- lib/postqueue/queue/runner.rb
|
177
178
|
- lib/postqueue/queue/select_and_lock.rb
|
178
|
-
- lib/postqueue/
|
179
|
+
- lib/postqueue/queue/timing.rb
|
179
180
|
- lib/postqueue/version.rb
|
180
181
|
- lib/tracker.rb
|
181
182
|
- lib/tracker/advisory_lock.rb
|
@@ -217,5 +218,6 @@ rubyforge_project:
|
|
217
218
|
rubygems_version: 2.5.1
|
218
219
|
signing_key:
|
219
220
|
specification_version: 4
|
220
|
-
summary:
|
221
|
+
summary: simplistic postgresql based queue with support for batching and idempotent
|
222
|
+
operations
|
221
223
|
test_files: []
|
data/lib/postqueue/railtie.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module Postqueue
|
2
|
-
class Railtie < Rails::Railtie
|
3
|
-
# initializer "postqueue.configure_rails_initialization" do
|
4
|
-
# Postqueue.load_config_from "config/postqueue.rb"
|
5
|
-
# end
|
6
|
-
end
|
7
|
-
|
8
|
-
# def self.load_config_from(path)
|
9
|
-
# @config_file = path
|
10
|
-
# end
|
11
|
-
#
|
12
|
-
# def self.load_config
|
13
|
-
# return unless @config_file
|
14
|
-
# load @config_file
|
15
|
-
# @config_file = nil
|
16
|
-
# end
|
17
|
-
end
|