Comments (5)
Something similar to this came up in the recipe post that I'm working on: how do you insert a lot of jobs (where I'd define a lot as "too many to simply loop over") at once and retain features like uniqueness and prefix support.
This seems like a great solution to the problem, though I do have an open questions about your proposal:
Is the idea that new_for_insert_all/1
would return a map rather than a changeset, the way insert_all/3
functions expect data? That poses an issue because the unique
field on jobs is virtual, so it is dropped when we convert the changeset to a map for insert. I think Oban.insert_all/2
should receive a list of changesets instead. It isn't as consistent with Repo.insert_all/3
, but it does match Oban.insert/2
.
from oban.
Oban knows its Repo
, so I think that a list of changesets or Job structs is the best choice. I am less concerned about uniqueness support for the case where I’d be using an insert_all
, although other users may be more concerned about that. My use case is something like:
Multi.new()
|> Multi.insert_all("deactivate_accounts", expired_customers, on_conflict: update_clause)
|> Multi.insert_all("deactivate_memberships", expired_customers, on_conflict: update_clause)
|> Oban.insert_all("notify_customers", Enum.map(expired_customers, &Worker.new/1))
|> Repo.transaction()
In some ways this is an abuse of insert_all
(there are no new records that will be created, guaranteed), but update_all
is too limited in ability. We’re guaranteed, for our particular use case, that every expired customer will be notified because we’re guaranteed that they will all be deactivated.
from oban.
@halostatue Support for insert_all
has been added. You may be interested in the new Oban.Job.to_map/1
function as well, if using Oban.insert_all/2,4
isn't sufficient.
This will be released in 0.9.0
today or tomorrow
from oban.
Thank you!
from oban.
Fun little benchmark demonstrating the relative improvement from batch inserting jobs.
Name ips average deviation median 99th %
insert_all 22.12 45.22 ms ±18.31% 43.96 ms 75.43 ms
insert 1.75 570.56 ms ±3.08% 570.52 ms 640.43 ms
insert_unique 0.99 1014.89 ms ±0.73% 1015.18 ms 1038.70 ms
Comparison:
insert_all 22.12
insert 1.75 - 12.62x slower +525.34 ms
insert_unique 0.99 - 22.44x slower +969.67 ms
Here is the benchee script itself:
defmodule WorkerA do
use Oban.Worker, queue: :bench
def perform(_, _), do: :ok
end
defmodule WorkerB do
use Oban.Worker, queue: :unique, unique: [period: 60]
def perform(_, _), do: :ok
end
Logger.configure(level: :warn)
Oban.Test.Repo.start_link()
Oban.start_link(repo: Oban.Test.Repo, queues: false)
insert = fn ->
Enum.each(1..1_000, fn index ->
%{id: index}
|> WorkerA.new()
|> Oban.insert()
end)
end
insert_all = fn ->
1..1_000
|> Enum.map(&WorkerA.new(%{id: &1}))
|> Oban.insert_all()
end
insert_unique = fn ->
Enum.each(1..1000, fn index ->
%{id: index}
|> WorkerB.new()
|> Oban.insert()
end)
end
Benchee.run(
%{"insert" => insert,
"insert_all" => insert_all,
"insert_unique" => insert_unique
},
time: 30,
warmup: 1
)
from oban.
Related Issues (20)
- timestamp fields in oban_jobs table doesn't have time zone causing AT TIME ZONE shift incorrect time HOT 2
- Oban crashing with RDS Proxy HOT 5
- assert_enqueued/2 fails to match a job by state=available and scheduled_at HOT 2
- Shared hook compilation failure HOT 5
- Oban Web fails when router helpers are disabled HOT 1
- `Oban.insert_all` spec is ambiguous HOT 5
- Smart Engine always wraps job insert statements in transaction HOT 2
- Is there way to check when the particular cron was executed last? HOT 1
- Structured jobs fail when using {:array, :uuid} HOT 1
- Helper functions to get available states by "categories" HOT 3
- Incompatibility with Ecto 3.10.1 HOT 5
- Add first-class support for reliable execution guarantees to DynamicCron HOT 5
- Allow configuration for default priority HOT 4
- Oban.Migration queries do not emit `schema_migration: true` in telemetry metadata HOT 6
- SmartEngine: Don't fetch jobs that have reached max attempts HOT 1
- Oban.Pro.Queue.SmartEngine doesn't put oban telemetry metadata HOT 1
- Minor documentation clarification for Oban.Worker and Oban.Pro.Worker HOT 1
- KeyError key :limit not found HOT 2
- Support LiveView v0.19.x HOT 2
- Invalid jobs are gracefully inserted but corrupted upon Oban.insert_all of a workflow HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from oban.