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

Commit

Permalink
First release of Sequel driver for River Ruby bindings
Browse files Browse the repository at this point in the history
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
  • Loading branch information
brandur committed Mar 2, 2024
1 parent fab399e commit 78b1e9a
Show file tree
Hide file tree
Showing 12 changed files with 552 additions and 25 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: CI

env:
# Database to connect to that can create other databases with `CREATE DATABASE`.
ADMIN_DATABASE_URL: postgres://postgres:postgres@localhost:5432

# Just a common place for steps to put binaries they need and which is added
# to GITHUB_PATH/PATH.
BIN_PATH: /home/runner/bin

# A suitable URL for a test database.
TEST_DATABASE_URL: postgres://postgres:postgres@127.0.0.1:5432/riverqueue_ruby_test?sslmode=disable

on:
- push

jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 3

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Ruby + `bundle install`
uses: ruby/setup-ruby@v1
with:
ruby-version: "head"
bundler-cache: true # runs 'bundle install' and caches installed gems automatically

- name: Standard Ruby
run: bundle exec standardrb

spec:
runs-on: ubuntu-latest
timeout-minutes: 3

services:
postgres:
image: postgres
env:
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 2s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Ruby + `bundle install`
uses: ruby/setup-ruby@v1
with:
ruby-version: "head"
bundler-cache: true # runs 'bundle install' and caches installed gems automatically

# There is a version of Go on Actions' base image, but it's old and can't
# read modern `go.mod` annotations correctly.
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: "stable"
check-latest: true

- name: Create database
run: psql --echo-errors --quiet -c '\timing off' -c "CREATE DATABASE riverqueue_ruby_test;" ${ADMIN_DATABASE_URL}

- name: Install River CLI
run: go install github.com/riverqueue/river/cmd/river@latest

- name: river migrate-up
run: river migrate-up --database-url "$TEST_DATABASE_URL"

- name: Rspec
run: bundle exec rspec
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/*.gem
/coverage/
17 changes: 15 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
source 'https://rubygems.org'
gemspec
source "https://rubygems.org"

gemspec

group :development, :test do
gem "riverqueue", git: "https://github.com/riverqueue/riverqueue-ruby", branch: "brandur-first-release"
# gem "riverqueue", path: "../riverqueue-ruby"
gem "standard"
end

group :test do
gem "rspec-core"
gem "rspec-expectations"
gem "simplecov", require: false
end
75 changes: 75 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,17 +1,92 @@
GIT
remote: https://github.com/riverqueue/riverqueue-ruby
revision: 8d029045f4fee36289ce1da2e7a067fd851c84d7
branch: brandur-first-release
specs:
riverqueue (0.0.1)

PATH
remote: .
specs:
riverqueue-sequel (0.0.1)
pg
sequel

GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
bigdecimal (3.1.4)
diff-lcs (1.5.0)
docile (1.4.0)
json (2.7.1)
language_server-protocol (3.17.0.3)
lint_roller (1.1.0)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
pg (1.5.4)
racc (1.7.3)
rainbow (3.1.1)
regexp_parser (2.9.0)
rexml (3.2.6)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
rubocop (1.61.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.31.1)
parser (>= 3.3.0.4)
rubocop-performance (1.20.2)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (1.13.0)
sequel (5.74.0)
bigdecimal
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
standard (1.34.0)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0)
rubocop (~> 1.60)
standard-custom (~> 1.0.0)
standard-performance (~> 1.3)
standard-custom (1.0.2)
lint_roller (~> 1.0)
rubocop (~> 1.50)
standard-performance (1.3.1)
lint_roller (~> 1.1)
rubocop-performance (~> 1.20.2)
unicode-display_width (2.5.0)

PLATFORMS
arm64-darwin-22
x86_64-linux

DEPENDENCIES
riverqueue!
riverqueue-sequel!
rspec-core
rspec-expectations
simplecov
standard

BUNDLED WITH
2.4.20
8 changes: 0 additions & 8 deletions README.md

This file was deleted.

23 changes: 23 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# riverqueue-sequel [![Build Status](https://github.com/riverqueue/riverqueue-ruby-sequel/workflows/CI/badge.svg)](https://github.com/riverqueue/riverqueue-ruby-sequel/actions)

[Sequel](https://github.com/jeremyevans/sequel) driver for [River](https://github.com/riverqueue/river)'s [`riverqueue` gem for Ruby](https://rubygems.org/gems/riverqueue).

`Gemfile` should contain the core gem and a driver like this one:

``` yaml
gem "riverqueue"
gem "riverqueue-sequel"
```

Initialize a client with:

```ruby
DB = Sequel.connect("postgres://...")
client = River::Client.new(River::Driver::Sequel.new(DB))
```

See also [`rubyqueue`](https://github.com/riverqueue/riverqueue-ruby).

## Development

See [development](./development.md).
48 changes: 48 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# riverqueue-ruby development

## Install dependencies

```shell
$ bundle install
```
## Run tests

Create a test database and migrate with River's CLI:

```shell
$ go install github.com/riverqueue/river/cmd/river
$ createdb riverqueue_ruby_test
$ river migrate-up --database-url "postgres://localhost/riverqueue_ruby_test"
```

Run all specs:

```shell
$ bundle exec rspec spec
```

## Run lint

```shell
$ standardrb --fix
```

## Code coverage

Running the entire test suite will produce a coverage report, and will fail if line and branch coverage is below 100%. Run the suite and open `coverage/index.html` to find lines or branches that weren't covered:

```shell
$ bundle exec rspec spec
$ open coverage/index.html
```

## Publish a new gem

```shell
git checkout master && git pull --rebase
VERSION=v0.0.x
gem build riverqueue-sequel.gemspec
gem push riverqueue-sequel-$VERSION.gem
git tag $VERSION
git push --tags
```
73 changes: 73 additions & 0 deletions lib/driver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module River::Driver
# Provides a Sequel driver for River.
#
# Used in conjunction with a River client like:
#
# DB = Sequel.connect("postgres://...")
# client = River::Client.new(River::Driver::Sequel.new(DB))
#
class Sequel
def initialize(db)
@db = db

# It's Ruby, so we can only define a model after Sequel's established a
# connection because it's all dynamic.
if !River::Driver::Sequel.const_defined?(:RiverJob)
River::Driver::Sequel.const_set(:RiverJob, Class.new(::Sequel::Model(:river_job)))

# Since we only define our model once, take advantage of knowing this is
# our first initialization to add required extensions.
db.extension(:pg_array)
end
end

def insert(insert_params)
# the call to `#compact` is important so that we remove nils and table
# default values get picked up instead
to_job_row(
RiverJob.create(
{
args: insert_params.encoded_args,
kind: insert_params.kind,
max_attempts: insert_params.max_attempts,
priority: insert_params.priority,
queue: insert_params.queue,
state: insert_params.state,
scheduled_at: insert_params.scheduled_at,
tags: insert_params.tags ? ::Sequel.pg_array(insert_params.tags) : nil
}.compact
)
)
end

private def to_job_row(river_job)
# needs to be accessed through values because Sequel shadows `errors`
errors = river_job.values[:errors]

River::JobRow.new(
id: river_job.id,
attempt: river_job.attempt,
attempted_at: river_job.attempted_at,
attempted_by: river_job.attempted_by,
created_at: river_job.created_at,
encoded_args: river_job.args,
errors: errors ? JSON.parse(errors, symbolize_names: true).map { |e|
River::AttemptError.new(
at: Time.parse(e[:at]),
attempt: e[:attempt],
error: e[:error],
trace: e[:trace]
)
} : nil,
finalized_at: river_job.finalized_at,
kind: river_job.kind,
max_attempts: river_job.max_attempts,
priority: river_job.priority,
queue: river_job.queue,
scheduled_at: river_job.scheduled_at,
state: river_job.state,
tags: river_job.tags
)
end
end
end
12 changes: 5 additions & 7 deletions lib/riverqueue-sequel.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
require "sequel"

require_relative "driver"

module River
module Driver
module Sequel
def initialize
end
end
end
end
end
19 changes: 11 additions & 8 deletions riverqueue-sequel.gemspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
Gem::Specification.new do |s|
s.name = "riverqueue-sequel"
s.version = "0.0.1"
s.summary = "Sequel driver for the River Ruby gem."
s.name = "riverqueue-sequel"
s.version = "0.0.1"
s.summary = "Sequel driver for the River Ruby gem."
s.description = "Sequel driver for the River Ruby gem."
s.authors = ["Blake Gentry", "Brandur Leach"]
s.email = "brandur@brandur.org"
s.files = ["lib/riverqueue-sequel.rb"]
s.homepage = "https://riverqueue.com"
s.license = "LGPL-3.0-or-later"
s.authors = ["Blake Gentry", "Brandur Leach"]
s.email = "brandur@brandur.org"
s.files = ["lib/riverqueue-sequel.rb"]
s.homepage = "https://riverqueue.com"
s.license = "LGPL-3.0-or-later"

s.add_dependency "pg"
s.add_dependency "sequel"
end
Loading

0 comments on commit 78b1e9a

Please sign in to comment.