Skip to content
This repository was archived by the owner on Mar 6, 2024. It is now read-only.

Commit 8df1bb1

Browse files
committed
First release of Sequel driver for River Ruby bindings
Related to main `riverqueue` gem's push in [1], this one provides a driver implementation for the Sequel gem. This is a similar concept to use the use of `riverpgxv5` in the main Go package -- it breaks up implementations for specific database packages into separate gems so that projects using River don't have include every third party database framework under the sun. I'll also be writing one for ActiveRecord. Like with [1], functionality for unique jobs and batch inserts is currently missing, to be added on a follow up release. [1] riverqueue/riverqueue-ruby#1
1 parent fab399e commit 8df1bb1

12 files changed

+543
-25
lines changed

.github/workflows/ci.yml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: CI
2+
3+
env:
4+
# Database to connect to that can create other databases with `CREATE DATABASE`.
5+
ADMIN_DATABASE_URL: postgres://postgres:postgres@localhost:5432
6+
7+
# Just a common place for steps to put binaries they need and which is added
8+
# to GITHUB_PATH/PATH.
9+
BIN_PATH: /home/runner/bin
10+
11+
# A suitable URL for a test database.
12+
TEST_DATABASE_URL: postgres://postgres:[email protected]:5432/riverqueue_ruby_test?sslmode=disable
13+
14+
on:
15+
- push
16+
17+
jobs:
18+
lint:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 3
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Install Ruby + `bundle install`
27+
uses: ruby/setup-ruby@v1
28+
with:
29+
ruby-version: "head"
30+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
31+
32+
- name: Standard Ruby
33+
run: bundle exec standardrb
34+
35+
spec:
36+
runs-on: ubuntu-latest
37+
timeout-minutes: 3
38+
39+
services:
40+
postgres:
41+
image: postgres
42+
env:
43+
POSTGRES_PASSWORD: postgres
44+
options: >-
45+
--health-cmd pg_isready
46+
--health-interval 2s
47+
--health-timeout 5s
48+
--health-retries 5
49+
ports:
50+
- 5432:5432
51+
52+
steps:
53+
- name: Checkout
54+
uses: actions/checkout@v4
55+
56+
- name: Install Ruby + `bundle install`
57+
uses: ruby/setup-ruby@v1
58+
with:
59+
ruby-version: "head"
60+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
61+
62+
# There is a version of Go on Actions' base image, but it's old and can't
63+
# read modern `go.mod` annotations correctly.
64+
- name: Install Go
65+
uses: actions/setup-go@v4
66+
with:
67+
go-version: "stable"
68+
check-latest: true
69+
70+
- name: Create database
71+
run: psql --echo-errors --quiet -c '\timing off' -c "CREATE DATABASE riverqueue_ruby_test;" ${ADMIN_DATABASE_URL}
72+
73+
- name: Install River CLI
74+
run: go install github.com/riverqueue/river/cmd/river@latest
75+
76+
- name: river migrate-up
77+
run: river migrate-up --database-url "$TEST_DATABASE_URL"
78+
79+
- name: Rspec
80+
run: bundle exec rspec

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/*.gem
2+
/coverage/

Gemfile

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,15 @@
1-
source 'https://rubygems.org'
2-
gemspec
1+
source "https://rubygems.org"
2+
3+
gemspec
4+
5+
group :development, :test do
6+
gem "riverqueue", git: "https://github.com/riverqueue/riverqueue-ruby", branch: "brandur-first-release"
7+
# gem "riverqueue", path: "../riverqueue-ruby"
8+
gem "standard"
9+
end
10+
11+
group :test do
12+
gem "rspec-core"
13+
gem "rspec-expectations"
14+
gem "simplecov", require: false
15+
end

Gemfile.lock

+75
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,92 @@
1+
GIT
2+
remote: https://github.com/riverqueue/riverqueue-ruby
3+
revision: 8d029045f4fee36289ce1da2e7a067fd851c84d7
4+
branch: brandur-first-release
5+
specs:
6+
riverqueue (0.0.1)
7+
18
PATH
29
remote: .
310
specs:
411
riverqueue-sequel (0.0.1)
12+
pg
13+
sequel
514

615
GEM
716
remote: https://rubygems.org/
817
specs:
18+
ast (2.4.2)
19+
bigdecimal (3.1.4)
20+
diff-lcs (1.5.0)
21+
docile (1.4.0)
22+
json (2.7.1)
23+
language_server-protocol (3.17.0.3)
24+
lint_roller (1.1.0)
25+
parallel (1.24.0)
26+
parser (3.3.0.5)
27+
ast (~> 2.4.1)
28+
racc
29+
pg (1.5.4)
30+
racc (1.7.3)
31+
rainbow (3.1.1)
32+
regexp_parser (2.9.0)
33+
rexml (3.2.6)
34+
rspec-core (3.12.2)
35+
rspec-support (~> 3.12.0)
36+
rspec-expectations (3.12.3)
37+
diff-lcs (>= 1.2.0, < 2.0)
38+
rspec-support (~> 3.12.0)
39+
rspec-support (3.12.1)
40+
rubocop (1.61.0)
41+
json (~> 2.3)
42+
language_server-protocol (>= 3.17.0)
43+
parallel (~> 1.10)
44+
parser (>= 3.3.0.2)
45+
rainbow (>= 2.2.2, < 4.0)
46+
regexp_parser (>= 1.8, < 3.0)
47+
rexml (>= 3.2.5, < 4.0)
48+
rubocop-ast (>= 1.30.0, < 2.0)
49+
ruby-progressbar (~> 1.7)
50+
unicode-display_width (>= 2.4.0, < 3.0)
51+
rubocop-ast (1.31.1)
52+
parser (>= 3.3.0.4)
53+
rubocop-performance (1.20.2)
54+
rubocop (>= 1.48.1, < 2.0)
55+
rubocop-ast (>= 1.30.0, < 2.0)
56+
ruby-progressbar (1.13.0)
57+
sequel (5.74.0)
58+
bigdecimal
59+
simplecov (0.22.0)
60+
docile (~> 1.1)
61+
simplecov-html (~> 0.11)
62+
simplecov_json_formatter (~> 0.1)
63+
simplecov-html (0.12.3)
64+
simplecov_json_formatter (0.1.4)
65+
standard (1.34.0)
66+
language_server-protocol (~> 3.17.0.2)
67+
lint_roller (~> 1.0)
68+
rubocop (~> 1.60)
69+
standard-custom (~> 1.0.0)
70+
standard-performance (~> 1.3)
71+
standard-custom (1.0.2)
72+
lint_roller (~> 1.0)
73+
rubocop (~> 1.50)
74+
standard-performance (1.3.1)
75+
lint_roller (~> 1.1)
76+
rubocop-performance (~> 1.20.2)
77+
unicode-display_width (2.5.0)
978

1079
PLATFORMS
1180
arm64-darwin-22
81+
x86_64-linux
1282

1383
DEPENDENCIES
84+
riverqueue!
1485
riverqueue-sequel!
86+
rspec-core
87+
rspec-expectations
88+
simplecov
89+
standard
1590

1691
BUNDLED WITH
1792
2.4.20

README.md

-8
This file was deleted.

docs/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# riverqueue-sequel [![Build Status](https://github.com/riverqueue/riverqueue-ruby-sequel/workflows/CI/badge.svg)](https://github.com/riverqueue/riverqueue-ruby-sequel/actions)
2+
3+
[Sequel](https://github.com/jeremyevans/sequel) driver for [River](https://github.com/riverqueue/river)'s [`riverqueue` gem for Ruby](https://rubygems.org/gems/riverqueue).
4+
5+
`Gemfile` should contain the core gem and a driver like this one:
6+
7+
``` yaml
8+
gem "riverqueue"
9+
gem "riverqueue-sequel"
10+
```
11+
12+
Initialize a client with:
13+
14+
```ruby
15+
DB = Sequel.connect("postgres://...")
16+
client = River::Client.new(River::Driver::Sequel.new(DB))
17+
```
18+
19+
See also [`rubyqueue`](https://github.com/riverqueue/riverqueue-ruby).
20+
21+
## Development
22+
23+
See [development](./development.md).

docs/development.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# riverqueue-ruby development
2+
3+
## Install dependencies
4+
5+
```shell
6+
$ bundle install
7+
```
8+
## Run tests
9+
10+
Create a test database and migrate with River's CLI:
11+
12+
```shell
13+
$ go install github.com/riverqueue/river/cmd/river
14+
$ createdb riverqueue_ruby_test
15+
$ river migrate-up --database-url "postgres://localhost/riverqueue_ruby_test"
16+
```
17+
18+
Run all specs:
19+
20+
```shell
21+
$ bundle exec rspec spec
22+
```
23+
24+
## Run lint
25+
26+
```shell
27+
$ standardrb --fix
28+
```
29+
30+
## Publish a new gem
31+
32+
```shell
33+
git checkout master && git pull --rebase
34+
VERSION=v0.0.x
35+
gem build riverqueue-sequel.gemspec
36+
gem push riverqueue-sequel-$VERSION.gem
37+
git tag $VERSION
38+
git push --tags
39+
```

lib/driver.rb

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
module River::Driver
2+
# Provides a Sequel driver for River.
3+
#
4+
# Used in conjunction with a River client like:
5+
#
6+
# DB = Sequel.connect("postgres://...")
7+
# client = River::Client.new(River::Driver::Sequel.new(DB))
8+
#
9+
class Sequel
10+
def initialize(db)
11+
@db = db
12+
13+
# It's Ruby, so we can only define a model after Sequel's established a
14+
# connection because it's all dynamic.
15+
if !River::Driver::Sequel.const_defined?(:RiverJob)
16+
River::Driver::Sequel.const_set(:RiverJob, Class.new(::Sequel::Model(:river_job)))
17+
18+
# Since we only define our model once, take advantage of knowing this is
19+
# our first initialization to add required extensions.
20+
db.extension(:pg_array)
21+
end
22+
end
23+
24+
def insert(insert_params)
25+
# the call to `#compact` is important so that we remove nils and table
26+
# default values get picked up instead
27+
to_job_row(
28+
RiverJob.create(
29+
{
30+
args: insert_params.encoded_args,
31+
kind: insert_params.kind,
32+
max_attempts: insert_params.max_attempts,
33+
priority: insert_params.priority,
34+
queue: insert_params.queue,
35+
state: insert_params.state,
36+
scheduled_at: insert_params.scheduled_at,
37+
tags: insert_params.tags ? ::Sequel.pg_array(insert_params.tags) : nil
38+
}.compact
39+
)
40+
)
41+
end
42+
43+
private def to_job_row(river_job)
44+
# needs to be accessed through values because Sequel shadows `errors`
45+
errors = river_job.values[:errors]
46+
47+
River::JobRow.new(
48+
id: river_job.id,
49+
attempt: river_job.attempt,
50+
attempted_at: river_job.attempted_at,
51+
attempted_by: river_job.attempted_by,
52+
created_at: river_job.created_at,
53+
encoded_args: river_job.args,
54+
errors: errors ? JSON.parse(errors, symbolize_names: true).map { |e|
55+
River::AttemptError.new(
56+
at: Time.parse(e[:at]),
57+
attempt: e[:attempt],
58+
error: e[:error],
59+
trace: e[:trace]
60+
)
61+
} : nil,
62+
finalized_at: river_job.finalized_at,
63+
kind: river_job.kind,
64+
max_attempts: river_job.max_attempts,
65+
priority: river_job.priority,
66+
queue: river_job.queue,
67+
scheduled_at: river_job.scheduled_at,
68+
state: river_job.state,
69+
tags: river_job.tags
70+
)
71+
end
72+
end
73+
end

lib/riverqueue-sequel.rb

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1+
require "sequel"
2+
3+
require_relative "driver"
4+
15
module River
2-
module Driver
3-
module Sequel
4-
def initialize
5-
end
6-
end
7-
end
8-
end
6+
end

riverqueue-sequel.gemspec

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
Gem::Specification.new do |s|
2-
s.name = "riverqueue-sequel"
3-
s.version = "0.0.1"
4-
s.summary = "Sequel driver for the River Ruby gem."
2+
s.name = "riverqueue-sequel"
3+
s.version = "0.0.1"
4+
s.summary = "Sequel driver for the River Ruby gem."
55
s.description = "Sequel driver for the River Ruby gem."
6-
s.authors = ["Blake Gentry", "Brandur Leach"]
7-
s.email = "[email protected]"
8-
s.files = ["lib/riverqueue-sequel.rb"]
9-
s.homepage = "https://riverqueue.com"
10-
s.license = "LGPL-3.0-or-later"
6+
s.authors = ["Blake Gentry", "Brandur Leach"]
7+
s.email = "[email protected]"
8+
s.files = ["lib/riverqueue-sequel.rb"]
9+
s.homepage = "https://riverqueue.com"
10+
s.license = "LGPL-3.0-or-later"
11+
12+
s.add_dependency "pg"
13+
s.add_dependency "sequel"
1114
end

0 commit comments

Comments
 (0)