tuber 0.0.1 → 0.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56b8831d5bdb6338f58cee603b906c4d41a4c36a0a4ac497ab3761838e8e5ffa
4
- data.tar.gz: 361c630c0d818b347dc033ba14c6679a60ea1d35e8bfb22feae2f86ac9ca151b
3
+ metadata.gz: 28e2397d8368c54a6711fa1db82b5c54ea649a4113e4da808b9dbc6db9cec1cb
4
+ data.tar.gz: dee769c5e37ff64726e1563150af3a25e2dc3f65405844f58b76bafbf4f7148f
5
5
  SHA512:
6
- metadata.gz: 39705970d8f4128a944dbb48741cebfaf34071eba99a50c5ee308c4b5f5d416d9c6ae2b054ea792701aea751da3fc26fc683d1bad074c38642d9911dd03c2d0e
7
- data.tar.gz: 1e3e6de54b17990613c44b81d4318cfc5b6dcef81f94bef600614ca93cccf29503c3ab63dbc34decc44a8e2a63def7a6008a029039bd0a87f84dcb14a37e92e0
6
+ metadata.gz: 48a99c28b12b3f83cd1f24f743fabda6f06a97802c3e2633bb805f7309a3574508d45b3ba7c2ce1cfd7842b1f92159115e19f7331362c79d662c687f0b60af75
7
+ data.tar.gz: 60fa0ea0b9d9440ba798bf953f640f9a6c654bf3988bdca58bc51e037bfa347fefc606964c81a236335467cd5441ce4344ef9382a725e2920d69d8a871ba996f
@@ -0,0 +1,68 @@
1
+ # CI runs the full suite against Tuber (the primary target) and the portable
2
+ # subset against stock beanstalkd (Tuber-only tests skip via require_tuber!).
3
+
4
+ name: Build Status
5
+
6
+ on:
7
+ push:
8
+ branches: [ "main" ]
9
+ pull_request:
10
+ branches: [ "main" ]
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ test:
17
+ name: tuber (ruby ${{ matrix.ruby-version }})
18
+ runs-on: ubuntu-latest
19
+ strategy:
20
+ fail-fast: false
21
+ matrix:
22
+ ruby-version: ["2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0"]
23
+
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ # Not a service container: the image's entrypoint needs the `server`
27
+ # subcommand, and services can't pass a command.
28
+ - name: Start tuber
29
+ run: |
30
+ docker run -d --name tuber -p 11300:11300 ghcr.io/tuberq/tuber:latest server
31
+ for i in $(seq 1 30); do (echo > /dev/tcp/127.0.0.1/11300) 2>/dev/null && exit 0; sleep 1; done
32
+ docker logs tuber; exit 1
33
+ - name: Set up Ruby
34
+ uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: ${{ matrix.ruby-version }}
37
+ bundler-cache: true
38
+ - name: Run tests
39
+ run: bundle exec rake test:full
40
+ env:
41
+ TUBER_TEST_ADDRESS: 127.0.0.1
42
+
43
+ beanstalkd-compat:
44
+ name: beanstalkd compat (ruby ${{ matrix.ruby-version }})
45
+ runs-on: ubuntu-latest
46
+ strategy:
47
+ fail-fast: false
48
+ matrix:
49
+ ruby-version: ["2.7", "4.0"]
50
+
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+ - name: Download & Extract beanstalkd
54
+ run: curl -L https://github.com/beanstalkd/beanstalkd/archive/refs/tags/v1.13.tar.gz | tar xz
55
+ - name: Make beanstalkd
56
+ run: make
57
+ working-directory: beanstalkd-1.13
58
+ - name: Set up Ruby
59
+ uses: ruby/setup-ruby@v1
60
+ with:
61
+ ruby-version: ${{ matrix.ruby-version }}
62
+ bundler-cache: true
63
+ - name: Daemonize beanstalkd
64
+ run: ./beanstalkd-1.13/beanstalkd -l 127.0.0.1 &
65
+ - name: Run tests
66
+ run: bundle exec rake test:full
67
+ env:
68
+ TUBER_TEST_ADDRESS: 127.0.0.1
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ _yardoc
2
+ .bundle
3
+ .config
4
+ .yardoc
5
+ *.gem
6
+ *.rbc
7
+ coverage
8
+ doc/
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.yardopts ADDED
@@ -0,0 +1,8 @@
1
+ --output-dir doc/
2
+ --readme README.md
3
+ --title Tuber
4
+ --markup-provider=redcarpet
5
+ --markup=markdown
6
+ --protected
7
+ --no-private
8
+ lib/tuber/**/*.rb
data/CHANGELOG.md ADDED
@@ -0,0 +1,134 @@
1
+ # CHANGELOG for the tuber gem
2
+
3
+ The tuber gem is a fork of [beaneater](https://github.com/beanstalkd/beaneater), taken at
4
+ beaneater 1.1.4. Entries from 1.1.4 down are beaneater's history, kept for reference.
5
+ (0.0.1 was an empty placeholder published to claim the gem name.)
6
+
7
+ ## 0.6.0 (September 16 2026)
8
+
9
+ Reconnection release. The gem retried reconnects but not connects, so a
10
+ consumer that caught `Tuber::NotConnected` and built a new client — the obvious
11
+ thing to write — never reached the retrying path, and a server restart of a few
12
+ seconds was enough to kill it. `reconnect!` makes the existing healing
13
+ reachable, and `connect_retries` gives a cold start a window wider than the
14
+ outage. Existing behaviour is unchanged until `connect_retries` is raised, with
15
+ two exceptions noted below: `NotConnected` messages gained a suffix (the
16
+ historical text remains a strict prefix), and a connect error other than
17
+ `ECONNREFUSED` is now retried and surfaced as `NotConnected` rather than
18
+ escaping as a raw `Errno`.
19
+
20
+ * Add `Tuber#reconnect!` / `Connection#reconnect!`: re-establishes the connection and replays its tube state (watched tubes with their weights, the used tube, the reserve mode). This healing only ever ran when the connection itself noticed a dropped socket, so a consumer that caught `Tuber::NotConnected` had no way to reach it and had to build a new client — which starts with no tube state and has to re-watch and re-weight every tube by hand.
21
+ * Add `connect_retries` and `connect_retry_interval` configuration. The initial connect took exactly one attempt with no retry, so a cold start during a server restart — a web boot, a fresh `Tuber.new`, a daemon rebuilding its client after an error — failed where an established connection would have healed. Defaults to the historical single attempt; raising it also lifts the reconnect budget of connections already established, so one knob covers both.
22
+ * Retry a connect that fails for any reason the server might be unreachable (`ETIMEDOUT`, `EHOSTUNREACH`, `ENETUNREACH`, DNS failure, connect timeout), not only `ECONNREFUSED`. Those previously escaped as a raw `Errno` from the middle of a reconnect, a class no consumer thinks to rescue.
23
+ * `Tuber::NotConnected` now names the underlying error in its message and keeps it as the exception's `cause`. A bare `rescue` collapsed every connect failure into "Connection to beanstalk '...' is closed!", hiding whether the server refused, timed out, or was never resolved — exactly what you need during an outage.
24
+ * `Connection#close` no longer raises if the socket cannot be closed cleanly; the connection is gone either way and `reconnect!` must not fail on the way to replacing it.
25
+ * Fix a reconnect silently dropping per-tube weights and the connection's reserve mode ([#1](https://github.com/tuberq/tuber-gem/issues/1)). Both are per-connection server state that a fresh socket resets, so a consumer that healed across a brief server restart kept working but quietly fell back to FIFO. `Connection` now remembers the weight each tube was watched with and the mode set by `Tubes#reserve_mode`, and replays them (watch, then `ignore default`, then `reserve-mode`) when re-initialising tubes.
26
+ * Fix `_initialize_tubes` sending `ignore default` after a reconnect even when `default` was one of the watched tubes, which dropped it from the watch list.
27
+ * `Connection#add_to_watched` now takes an optional weight as a second argument, and `Connection#tube_weights` / `Connection#reserve_mode` expose the replayed state.
28
+
29
+ ## 0.5.1 (August 13 2026)
30
+
31
+ * Fix empty keyword arguments forwarded through `Tube#transmit`, `Tubes#transmit` and `Jobs#transmit` arriving as an extra positional `{}` on Ruby 2.7
32
+ * CI: start the Tuber container with an explicit `server` subcommand, add Ruby 4.0 to the test matrix
33
+
34
+ ## 0.5.0 (August 13 2026)
35
+
36
+ First functional release under the `tuber` name. Versioning restarts below 1.0
37
+ while the Tuber-first API settles; 1.0.0 will follow once it has. Entries below
38
+ 1.1.4 with earlier version numbers are beaneater history.
39
+
40
+ * **Renamed from `beaneater` to `tuber`** (briefly `russet` while the gem name was being freed up, though never published under that name). The `Beaneater` class is now `Tuber`, and `require 'beaneater'` becomes `require 'tuber'`. Nothing else changed in the rename — see "Migrating from beaneater" in the README.
41
+ * Fix `_with_retry` retransmitting non-idempotent commands (`put`/`delete`/`release`/`bury`/`touch`/`kick` and batch variants) after a reconnect: the first send's fate is unknown, so a re-sent `put` could duplicate a job and a re-sent `delete` could raise `NOT_FOUND` for work that succeeded. These verbs now reconnect (and re-watch tubes) but re-raise the original connection error so the caller decides; idempotent commands keep the transparent retry.
42
+ * Add `Jobs#touch_all` (Tuber 0.12.0+): one-command heartbeat for every job the connection holds, returning how many were still held
43
+ * Add `Tube#flush_buried` (Tuber only): atomically deletes only the buried jobs in a tube, returning the count
44
+ * Add optional long-poll `timeout` to `reserve_batch` (Tuber only): `tubes.reserve_batch(count, timeout)` blocks up to `timeout` seconds for the first job, then drains what's ready
45
+ * Add `connect_timeout` (Ruby 3+), `resolv_timeout` (Ruby 3+), `read_timeout`, and `write_timeout` configuration options (@rveznaver)
46
+ * Fix fractional timeout handling for `read_timeout` and `write_timeout` socket options
47
+ * Add `TUBER_URL` environment variable and `config.tuber_url` as the primary way to point at a server; `BEANSTALKD_URL` and `config.beanstalkd_url` remain as compatible fallbacks/aliases
48
+ * Tests can target a specific server via `TUBER_TEST_ADDRESS`, and Tuber-only tests skip automatically against stock beanstalkd; CI runs the full suite against Tuber and the portable subset against beanstalkd
49
+ * Fix `StatStruct#[]` raising a `SyntaxError` when looking up hyphenated beanstalkd keys (e.g. `stats['current-jobs-ready']`); keys are now underscored before lookup to match how they are stored
50
+
51
+ ## 1.1.4 (March 6 2026)
52
+
53
+ * Add frozen string literal comments for Ruby 3.4 compatibility (@nearapogee)
54
+ * Update tests for Ruby 3.4.x (@nearapogee)
55
+ * Add GitHub Actions CI workflow (@Ifiht)
56
+ * Update README.md (@Ifiht)
57
+
58
+ ## 1.1.3 (Oct 14 2022)
59
+
60
+ * Fixes issue introduced in 1.1.2 re YML parsing (@pond)
61
+ * Fix job lookup test so it passes again
62
+
63
+ ## 1.1.2 (Oct 10 2022)
64
+
65
+ * Fixes beaneater when used with Ruby 3.1 and YAML 4 (@pond)
66
+
67
+ ## 1.1.1 (April 27th 2021)
68
+
69
+ * Support Ruby 3 keyword arguments (@yahonda)
70
+ * Add CI for Ruby 3 (@yahonda)
71
+
72
+ ## 1.1.0 (April 25th 2021)
73
+
74
+ * 'clear' behavior was failing unexpectedly, swallow issues during delete as well (@bfolkens)
75
+ * Fix assigned but unused variables (@utilum)
76
+ * Fix last_used tube not stored (@albb0920)
77
+ * Fix deprecation warning in ruby 2.7 (@albb0920)
78
+ * Fix watched tubes not restored after reconnect (@albb0920)
79
+ * Fix keyword arguemnt warning (@albb0920)
80
+
81
+ ## 1.0.0 (April 26th 2015)
82
+
83
+ * Beginning from version 1.0.0 the support for `Beaneater::Pool` has been dropped (@alup)
84
+ * `Jobs#find_all` method has been removed, since it is no longer necessary after removing pool (@alup)
85
+ * `Tubes` is now an enumerable allowing `tubes` to be handled as a collection (@Aethelflaed)
86
+
87
+ ## 0.3.3 (August 16th 2014)
88
+
89
+ * Fix failure when job is not defined and fix exception handling for jobs (@nicholasorenrawlings)
90
+ * Add reserve_timeout option to job processing (@nicholasorenrawlings)
91
+ * Add travis-ci badge (@tdg5)
92
+ * Fix tests to run more reliably (@tdg5)
93
+
94
+ ## 0.3.2 (Sept 15 2013)
95
+
96
+ * Fix #29 ExpectedCrlfError name and invocation (@tdg5)
97
+
98
+ ## 0.3.1 (Jun 28 2013)
99
+
100
+ * Fixes issue with "chomp" nil exception when losing connection (Thanks @simao)
101
+ * Better handling of unknown or invalid commands during transmit
102
+ * Raise proper CRLF exception (Thanks @carlosmoutinho)
103
+
104
+ ## 0.3.0 (Jan 23 2013)
105
+
106
+ * Replace Telnet with tcpsocket thanks @vidarh
107
+
108
+ ## 0.2.2 (Dec 2 2012)
109
+
110
+ * Fixes status and ID parsing in a response (Thanks @justincase)
111
+
112
+ ## 0.2.1 (Dec 1 2012)
113
+
114
+ * Convert command to ASCII_8Bit to avoid gsub issues
115
+
116
+ ## 0.2.0 (Nov 12 2012)
117
+ * Fix 1.8.7 compatibility issues
118
+ * Add configuration block to beaneater and better job parsing
119
+ * BREAKING: json jobs now return as string by default not hashes
120
+
121
+ ## 0.1.2 (Nov 7 2012)
122
+
123
+ * Add timeout: false to transmit to allow longer reserve
124
+
125
+ ## 0.1.1 (Nov 4 2012)
126
+
127
+ * Add `Jobs#find_all` to fix #10
128
+ * Fixed issue with `tubes-list` by merging results
129
+ * Add `Job#ttr`, `Job#pri`, `Job#delay`
130
+ * Improved yardocs coverage and accuracy
131
+
132
+ ## 0.1.0 (Nov 1 2012)
133
+
134
+ * Initial release!
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in tuber.gemspec
6
+ gemspec
7
+
8
+ group :development do
9
+ # 3.5.1 fixes CVE-2020-26298 (XSS when processing quotes). The old '~> 1'
10
+ # pin was inherited from beaneater and capped us below the fix.
11
+ gem 'redcarpet', '~> 3.6', '>= 3.5.1'
12
+ gem 'github-markup'
13
+ gem 'yard'
14
+ end
15
+
16
+ group :development, :test do
17
+ gem 'coveralls', :require => false
18
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2012 Nico Taing
2
+ Copyright (c) 2026 Dan Milne
3
+
4
+ Tuber is a fork of beaneater (https://github.com/beanstalkd/beaneater),
5
+ originally written by Nico Taing and contributors, and is distributed under
6
+ the same MIT License.
7
+
8
+ MIT License
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining
11
+ a copy of this software and associated documentation files (the
12
+ "Software"), to deal in the Software without restriction, including
13
+ without limitation the rights to use, copy, modify, merge, publish,
14
+ distribute, sublicense, and/or sell copies of the Software, and to
15
+ permit persons to whom the Software is furnished to do so, subject to
16
+ the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be
19
+ included in all copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.