basket 0.0.1 → 0.0.2
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/Gemfile +5 -0
- data/Gemfile.lock +47 -1
- data/Guardfile +37 -0
- data/README.md +34 -38
- data/lib/basket/batcher.rb +34 -0
- data/lib/basket/configuration.rb +7 -0
- data/lib/basket/error.rb +4 -0
- data/lib/basket/{queue.rb → queue_collection.rb} +5 -1
- data/lib/basket/version.rb +1 -1
- data/lib/basket.rb +30 -5
- metadata +7 -5
- data/basket.gemspec +0 -37
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d11f37f0087fb606bf92362eb1c913e9f089b262d130a13edfb22d639055c374
|
4
|
+
data.tar.gz: b66835a0ad01af6b29b528a2e7bd481331e64b0b437586a42a504ecc27d3c1b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f015621c801d42ef33fc3090d244b8a53f8a8830d7230ce73177287ba9b7ab3a7fe41129a6427c66a1119e17e0fb75e1be82bfbca0424026bdbefb0d33e94a79
|
7
|
+
data.tar.gz: 4ae3e63475e3fb68e2177356d44f5a92b332b31efe43081c76f3df5824751f4ed3d203b39f3d01e227edea063466220e9ec4bd63a6cb272f8f560fbb70c31ce9
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,20 +1,57 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
basket (0.
|
4
|
+
basket (0.0.2)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ast (2.4.2)
|
10
|
+
coderay (1.1.3)
|
10
11
|
diff-lcs (1.5.0)
|
12
|
+
ffi (1.15.5)
|
13
|
+
formatador (1.1.0)
|
14
|
+
guard (2.18.0)
|
15
|
+
formatador (>= 0.2.4)
|
16
|
+
listen (>= 2.7, < 4.0)
|
17
|
+
lumberjack (>= 1.0.12, < 2.0)
|
18
|
+
nenv (~> 0.1)
|
19
|
+
notiffany (~> 0.0)
|
20
|
+
pry (>= 0.13.0)
|
21
|
+
shellany (~> 0.0)
|
22
|
+
thor (>= 0.18.1)
|
23
|
+
guard-compat (1.2.1)
|
24
|
+
guard-rspec (4.7.3)
|
25
|
+
guard (~> 2.1)
|
26
|
+
guard-compat (~> 1.1)
|
27
|
+
rspec (>= 2.99.0, < 4.0)
|
28
|
+
guard-standardrb (0.2.2)
|
29
|
+
guard (>= 2.0.0)
|
30
|
+
guard-compat (~> 1.0)
|
31
|
+
standardrb
|
11
32
|
json (2.6.3)
|
12
33
|
language_server-protocol (3.17.0.3)
|
34
|
+
listen (3.8.0)
|
35
|
+
rb-fsevent (~> 0.10, >= 0.10.3)
|
36
|
+
rb-inotify (~> 0.9, >= 0.9.10)
|
37
|
+
lumberjack (1.2.8)
|
38
|
+
method_source (1.0.0)
|
39
|
+
mocktail (1.2.2)
|
40
|
+
nenv (0.3.0)
|
41
|
+
notiffany (0.1.3)
|
42
|
+
nenv (~> 0.1)
|
43
|
+
shellany (~> 0.0)
|
13
44
|
parallel (1.22.1)
|
14
45
|
parser (3.2.1.0)
|
15
46
|
ast (~> 2.4.1)
|
47
|
+
pry (0.14.2)
|
48
|
+
coderay (~> 1.1)
|
49
|
+
method_source (~> 1.0)
|
16
50
|
rainbow (3.1.1)
|
17
51
|
rake (13.0.6)
|
52
|
+
rb-fsevent (0.11.2)
|
53
|
+
rb-inotify (0.10.1)
|
54
|
+
ffi (~> 1.0)
|
18
55
|
regexp_parser (2.7.0)
|
19
56
|
rexml (3.2.5)
|
20
57
|
rspec (3.12.0)
|
@@ -46,19 +83,28 @@ GEM
|
|
46
83
|
rubocop (>= 1.7.0, < 2.0)
|
47
84
|
rubocop-ast (>= 0.4.0)
|
48
85
|
ruby-progressbar (1.11.0)
|
86
|
+
shellany (0.0.1)
|
49
87
|
standard (1.24.3)
|
50
88
|
language_server-protocol (~> 3.17.0.2)
|
51
89
|
rubocop (= 1.44.1)
|
52
90
|
rubocop-performance (= 1.15.2)
|
91
|
+
standardrb (1.0.1)
|
92
|
+
standard
|
93
|
+
thor (1.2.1)
|
53
94
|
unicode-display_width (2.4.2)
|
54
95
|
|
55
96
|
PLATFORMS
|
56
97
|
arm64-darwin-22
|
57
98
|
x86_64-darwin-20
|
99
|
+
x86_64-darwin-21
|
58
100
|
x86_64-linux
|
59
101
|
|
60
102
|
DEPENDENCIES
|
61
103
|
basket!
|
104
|
+
guard
|
105
|
+
guard-rspec
|
106
|
+
guard-standardrb
|
107
|
+
mocktail
|
62
108
|
rake (~> 13.0)
|
63
109
|
rspec (~> 3.0)
|
64
110
|
standard (~> 1.3)
|
data/Guardfile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features) \
|
6
|
+
# .select{|d| Dir.exist?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
7
|
+
|
8
|
+
## Note: if you are using the `directories` clause above and you are not
|
9
|
+
## watching the project directory ('.'), then you will want to move
|
10
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
11
|
+
#
|
12
|
+
# $ mkdir config
|
13
|
+
# $ mv Guardfile config/
|
14
|
+
# $ ln -s config/Guardfile .
|
15
|
+
#
|
16
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
17
|
+
|
18
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
19
|
+
# rspec may be run, below are examples of the most common uses.
|
20
|
+
# * bundler: 'bundle exec rspec'
|
21
|
+
# * bundler binstubs: 'bin/rspec'
|
22
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
23
|
+
# installed the spring binstubs per the docs)
|
24
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
+
# * 'just' rspec: 'rspec'
|
26
|
+
|
27
|
+
group "specs", halt_on_fail: true do
|
28
|
+
guard :rspec, all_on_start: false, cmd: "rspec" do
|
29
|
+
watch(%r{^spec/.+_spec\.rb$})
|
30
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
31
|
+
watch("spec/spec_helper.rb") { "spec/lib" }
|
32
|
+
end
|
33
|
+
|
34
|
+
guard :standardrb, fix: true, all_on_start: true, progress: true do
|
35
|
+
watch(/.+\.rb$/)
|
36
|
+
end
|
37
|
+
end
|
data/README.md
CHANGED
@@ -1,21 +1,21 @@
|
|
1
|
-
|
1
|
+
[](https://badge.fury.io/rb/basket)
|
2
2
|
# Basket
|
3
3
|
|
4
|
-
A farmer doesn't walk down to the chicken coop, grab an egg, go back to the kitchen, go back to the coop, go back to the kitchen
|
4
|
+
A farmer doesn't walk down to the chicken coop, grab an egg, go back to the kitchen, go back to the coop, go back to the kitchen ad infinitum. They take a basket with them, and as the chickens lay their eggs, they fill up the basket and when the basket is full they go make something with them! I would make a quiche, but that's besides the case.
|
5
5
|
|
6
6
|
`Basket` lets you do just that. Collect items until your basket is full and then, when it is, go do something with them!
|
7
7
|
|
8
|
-
|
8
|
+
Basket is very new and under development.
|
9
9
|
|
10
|
-
|
10
|
+
## Installation
|
11
11
|
|
12
12
|
Install the gem and add to the application's Gemfile by executing:
|
13
13
|
|
14
|
-
$ bundle add
|
14
|
+
$ bundle add basket
|
15
15
|
|
16
16
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
17
17
|
|
18
|
-
$ gem install
|
18
|
+
$ gem install basket
|
19
19
|
|
20
20
|
## Usage
|
21
21
|
|
@@ -32,21 +32,19 @@ The item added to the basket can be any data you want! If you are using the in
|
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
class QuicheBasket
|
35
|
+
# Include the Basket::Batcher
|
35
36
|
include Basket::Batcher
|
36
|
-
|
37
|
-
|
37
|
+
|
38
|
+
# Define the size of your basket
|
39
|
+
basket_options size: 15
|
38
40
|
|
39
41
|
def perform
|
40
|
-
eggs = []
|
41
42
|
batch.each do | egg |
|
42
|
-
#
|
43
|
-
egg = Egg.new(egg)
|
44
|
-
egg.wash!
|
45
|
-
eggs << egg
|
43
|
+
# Do some processing on each element of the batch. In this case there will be 15 eggs.
|
46
44
|
end
|
47
45
|
|
48
46
|
# If you want to do something directly inline:
|
49
|
-
Quiche.make(
|
47
|
+
Quiche.make(batch)
|
50
48
|
|
51
49
|
# If you want to do something out of a request response cycle,
|
52
50
|
# call out to your favorite background processing framework:
|
@@ -54,18 +52,33 @@ class QuicheBasket
|
|
54
52
|
end
|
55
53
|
|
56
54
|
# There are four callbacks to the lifecycle of a basket.
|
57
|
-
# :
|
55
|
+
# :on_add, :on_success, and :on_failure.
|
58
56
|
# They can be used like this:
|
59
|
-
on_success
|
57
|
+
def on_success
|
58
|
+
Farm.rest_chickens
|
59
|
+
batch.each do |egg|
|
60
|
+
egg.inspect
|
61
|
+
end
|
62
|
+
end
|
60
63
|
|
61
|
-
def
|
62
|
-
|
64
|
+
def on_add
|
65
|
+
element.wash
|
63
66
|
end
|
64
67
|
|
68
|
+
def on_failure
|
69
|
+
Farm.notify_egg_monitor(error)
|
70
|
+
raise Error
|
71
|
+
end
|
65
72
|
end
|
66
73
|
```
|
67
74
|
|
68
|
-
The perform method will be called after there have been
|
75
|
+
The perform method will be called after there have been the defined number of elements added to the batch, specified in the `basket_options` size parameter. The elements can be any kind of data, depending on the backend that you are using. The default is just an in-memory hash.
|
76
|
+
|
77
|
+
The callbacks are lifecycle callbacks on the existing batch. `on_add` gives access to a variable called `element` which is equal to the item just added to the batch. `on_add`, `on_success` and `on_failure` also give access to the whole batch through the `batch` variable. `on_success` is called after `perform`.
|
78
|
+
|
79
|
+
The `on_failure` use of `batch` of course may not have a full batch as the error could have been generated during `add` or `on_add`. The `on_failure` callback also has access to an `error` variable which holds the error that was generated.
|
80
|
+
|
81
|
+
Defining `on_add`, `on_failure`, and `on_success` is optional.
|
69
82
|
|
70
83
|
## Development
|
71
84
|
|
@@ -73,6 +86,8 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
73
86
|
|
74
87
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
75
88
|
|
89
|
+
This project uses Guard to facilitate local development. You can run it with `bundle exec guard`. It will run specs on change to files and will run `standard --fix` after passing tests.
|
90
|
+
|
76
91
|
## Contributing
|
77
92
|
|
78
93
|
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/basket. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/basket/blob/main/CODE_OF_CONDUCT.md).
|
@@ -87,22 +102,3 @@ Everyone interacting in the Basket project's codebases, issue trackers, chat roo
|
|
87
102
|
|
88
103
|
|
89
104
|
|
90
|
-
## Ideas
|
91
|
-
|
92
|
-
1. Can the callbacks support ActiveSupport Notifications?
|
93
|
-
- ActiveSupport::Callbacks extraction of callbacks
|
94
|
-
2. Batch can be postgres json blob or Redis! - Backend system
|
95
|
-
~~3. Does not execute in line~~For now.
|
96
|
-
~~4. Use ActiveJob for background execution.~~ It's up to you to handle a full basket how you want.
|
97
|
-
~~5. "Buffer", "collection", "queue"~~ Basket.
|
98
|
-
6. Default trigger is just queue length.
|
99
|
-
7. Expose basket_options trigger: :check_some_thing_lambda
|
100
|
-
8. Redis push pop.
|
101
|
-
9. Make queue ephemeral?
|
102
|
-
10. Define gotchas but don't solve them.
|
103
|
-
11. Redis fetch / Super Fetch?
|
104
|
-
12. Configuration.
|
105
|
-
|
106
|
-
https://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html
|
107
|
-
|
108
|
-
|
data/lib/basket/batcher.rb
CHANGED
@@ -1,4 +1,38 @@
|
|
1
|
+
require_relative "./error"
|
1
2
|
module Basket
|
2
3
|
module Batcher
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def basket_options(args)
|
10
|
+
@basket_options = args
|
11
|
+
end
|
12
|
+
|
13
|
+
def basket_options_hash
|
14
|
+
raise Basket::Error, "You must specify the size of your basket!" if @basket_options.nil?
|
15
|
+
raise Basket::Error, "You must specify a size greater than 0" if @basket_options[:size] <= 0
|
16
|
+
@basket_options
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def batch
|
21
|
+
@batch ||= Basket.config.queue_collection.pop_all(self.class.name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def perform
|
25
|
+
raise Basket::Error, "You must implement perform in your Basket class."
|
26
|
+
end
|
27
|
+
|
28
|
+
def on_success
|
29
|
+
end
|
30
|
+
|
31
|
+
def on_add
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_failure
|
35
|
+
raise error
|
36
|
+
end
|
3
37
|
end
|
4
38
|
end
|
data/lib/basket/error.rb
ADDED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Basket
|
2
|
-
class
|
2
|
+
class QueueCollection
|
3
3
|
def initialize(backend = HashBackend.new)
|
4
4
|
@backend = backend
|
5
5
|
end
|
@@ -20,5 +20,9 @@ module Basket
|
|
20
20
|
def data
|
21
21
|
@backend.data
|
22
22
|
end
|
23
|
+
|
24
|
+
def reset_backend
|
25
|
+
@backend = HashBackend.new
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
data/lib/basket/version.rb
CHANGED
data/lib/basket.rb
CHANGED
@@ -1,18 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "basket/batcher"
|
4
|
+
require_relative "basket/configuration"
|
5
|
+
require_relative "basket/error"
|
4
6
|
require_relative "basket/hash_backend"
|
5
|
-
require_relative "basket/
|
7
|
+
require_relative "basket/queue_collection"
|
6
8
|
require_relative "basket/version"
|
7
9
|
|
8
10
|
module Basket
|
9
11
|
class Error < StandardError; end
|
10
12
|
|
13
|
+
def self.config
|
14
|
+
@config ||= Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.contents
|
18
|
+
@queue_collection.data
|
19
|
+
end
|
20
|
+
|
11
21
|
def self.add(queue, data)
|
12
|
-
|
13
|
-
|
14
|
-
|
22
|
+
@queue_collection = config.queue_collection
|
23
|
+
queue_length = @queue_collection.push(queue, data)
|
24
|
+
queue_class = Object.const_get(queue)
|
25
|
+
queue_instance = queue_class.new
|
26
|
+
|
27
|
+
queue_instance.define_singleton_method(:element) { data }
|
28
|
+
queue_instance.on_add
|
29
|
+
|
30
|
+
return unless queue_length == queue_class.basket_options_hash[:size]
|
31
|
+
|
32
|
+
queue_instance.perform
|
33
|
+
queue_instance.on_success
|
34
|
+
rescue => e
|
35
|
+
raise e if e.instance_of?(Basket::Error)
|
36
|
+
queue_instance.define_singleton_method(:error) { e }
|
37
|
+
queue_instance.on_failure
|
38
|
+
end
|
15
39
|
|
16
|
-
|
40
|
+
def self.clear_all
|
41
|
+
config.queue_collection.reset_backend
|
17
42
|
end
|
18
43
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: basket
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nichol alexander
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This is a longer description.
|
14
14
|
email:
|
@@ -23,14 +23,16 @@ files:
|
|
23
23
|
- CODE_OF_CONDUCT.md
|
24
24
|
- Gemfile
|
25
25
|
- Gemfile.lock
|
26
|
+
- Guardfile
|
26
27
|
- LICENSE.txt
|
27
28
|
- README.md
|
28
29
|
- Rakefile
|
29
|
-
- basket.gemspec
|
30
30
|
- lib/basket.rb
|
31
31
|
- lib/basket/batcher.rb
|
32
|
+
- lib/basket/configuration.rb
|
33
|
+
- lib/basket/error.rb
|
32
34
|
- lib/basket/hash_backend.rb
|
33
|
-
- lib/basket/
|
35
|
+
- lib/basket/queue_collection.rb
|
34
36
|
- lib/basket/version.rb
|
35
37
|
- sig/basket.rbs
|
36
38
|
homepage: https://github.com/nicholalexander/basket
|
@@ -55,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
57
|
- !ruby/object:Gem::Version
|
56
58
|
version: '0'
|
57
59
|
requirements: []
|
58
|
-
rubygems_version: 3.
|
60
|
+
rubygems_version: 3.3.24
|
59
61
|
signing_key:
|
60
62
|
specification_version: 4
|
61
63
|
summary: Wait until you have a bunch of things, then do something.
|
data/basket.gemspec
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/basket/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "basket"
|
7
|
-
spec.version = Basket::VERSION
|
8
|
-
spec.authors = ["nichol alexander"]
|
9
|
-
spec.email = ["nichol.alexander@gmail.com "]
|
10
|
-
|
11
|
-
spec.summary = "Wait until you have a bunch of things, then do something."
|
12
|
-
spec.description = "This is a longer description."
|
13
|
-
spec.homepage = "https://github.com/nicholalexander/basket"
|
14
|
-
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 2.6.0"
|
16
|
-
|
17
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
-
spec.metadata["source_code_uri"] = "https://github.com/nicholalexander/basket"
|
19
|
-
spec.metadata["changelog_uri"] = "https://github.com/nicholalexander/basket/blob/main/CHANGELOG.md"
|
20
|
-
|
21
|
-
# Specify which files should be added to the gem when it is released.
|
22
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
-
spec.files = Dir.chdir(__dir__) do
|
24
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
25
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|circleci)|appveyor)})
|
26
|
-
end
|
27
|
-
end
|
28
|
-
spec.bindir = "exe"
|
29
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
30
|
-
spec.require_paths = ["lib"]
|
31
|
-
|
32
|
-
# Uncomment to register a new dependency of your gem
|
33
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
34
|
-
|
35
|
-
# For more information and examples about making a new gem, check out our
|
36
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
37
|
-
end
|