basket 0.0.1 → 0.0.2

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: 20ae2ec64c54d8a1ae452a284e20f8bc2393318f7333bcbc7152bf24236e4b26
4
- data.tar.gz: 8cb26c727cbc2c49ea906a6f949c6b1a8631a9bea3200b446f7ee2b4a8c15a59
3
+ metadata.gz: d11f37f0087fb606bf92362eb1c913e9f089b262d130a13edfb22d639055c374
4
+ data.tar.gz: b66835a0ad01af6b29b528a2e7bd481331e64b0b437586a42a504ecc27d3c1b7
5
5
  SHA512:
6
- metadata.gz: 7f0b0410eb3ad97c9ca857e875c031d5d0bbee7183f62dc22d087424d503c16b2f5c7080aa1f458b89a07719eace55fae46b87f6df079cc8a4cc341b8a00f17a
7
- data.tar.gz: a6924dd3d2e1b3d3b731cbcbe2fa473718785244e432fd87a9de11e29a3f0275380581dbf5844a5e0d7bbbb6377a262e6592a657f0f1df5d5f0517f0697869ed
6
+ metadata.gz: f015621c801d42ef33fc3090d244b8a53f8a8830d7230ce73177287ba9b7ab3a7fe41129a6427c66a1119e17e0fb75e1be82bfbca0424026bdbefb0d33e94a79
7
+ data.tar.gz: 4ae3e63475e3fb68e2177356d44f5a92b332b31efe43081c76f3df5824751f4ed3d203b39f3d01e227edea063466220e9ec4bd63a6cb272f8f560fbb70c31ce9
data/Gemfile CHANGED
@@ -8,5 +8,10 @@ gemspec
8
8
  gem "rake", "~> 13.0"
9
9
 
10
10
  gem "rspec", "~> 3.0"
11
+ gem "mocktail"
11
12
 
12
13
  gem "standard", "~> 1.3"
14
+
15
+ gem "guard"
16
+ gem "guard-rspec", require: false
17
+ gem "guard-standardrb", require: false
data/Gemfile.lock CHANGED
@@ -1,20 +1,57 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- basket (0.1.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
- # It would be silly to use this gem because it doesn't work yet.
1
+ [![Gem Version](https://badge.fury.io/rb/basket.svg)](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, etc, etc. 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.
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
- ## Installation
8
+ Basket is very new and under development.
9
9
 
10
- TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
+ ## Installation
11
11
 
12
12
  Install the gem and add to the application's Gemfile by executing:
13
13
 
14
- $ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
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 UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
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
- basket_options length: 15
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
- # do some processing on each element of the batch. In this case there will be 15 eggs.
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(eggs)
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
- # :on_success, :on_failure, :on_add, :check_length
55
+ # :on_add, :on_success, and :on_failure.
58
56
  # They can be used like this:
59
- on_success: :let_chickens_rest
57
+ def on_success
58
+ Farm.rest_chickens
59
+ batch.each do |egg|
60
+ egg.inspect
61
+ end
62
+ end
60
63
 
61
- def let_chickens_rest
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 15 elements added to the batch. The callbacks are lifecycle callbacks on the existing batch. `on_add` takes an argument of the element that is being added. The elements are just a hash. `on_success` and `on_failure` give access to the whole batch.
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
-
@@ -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
@@ -0,0 +1,7 @@
1
+ module Basket
2
+ class Configuration
3
+ def queue_collection
4
+ @queue_collection ||= Basket::QueueCollection.new
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,4 @@
1
+ module Basket
2
+ class Error < StandardError
3
+ end
4
+ end
@@ -1,5 +1,5 @@
1
1
  module Basket
2
- class Queue
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Basket
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
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/queue"
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
- queue_length = Basket::Queue.push(queue, data)
13
- queue_class = queue.constantize.new
14
- return unless queue_length == queue_class.batcher.options.queue_length
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
- queue_class.perform
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.1
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-02-18 00:00:00.000000000 Z
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/queue.rb
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.4.7
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