GithubHelp home page GithubHelp logo

ash-project / ash_oban Goto Github PK

View Code? Open in Web Editor NEW
21.0 4.0 11.0 327 KB

The extension for integrating Ash resources with Oban.

Home Page: https://hexdocs.pm/ash_oban

License: MIT License

Elixir 100.00%
ash background-jobs jobs oban

ash_oban's People

Contributors

dependabot[bot] avatar infinitis avatar janajri avatar jimsynz avatar moissela avatar rellen avatar sevenseacat avatar sitch avatar smt116 avatar zachdaniel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ash_oban's Issues

require_queues! should be configurable

Currently ash oban assumes that all queues exist on every instance, which may not always be the case.

It would be helpful to allow the ability to split queues between nodes. See https://hexdocs.pm/oban/splitting-queues.html

Something like this

config :my_app, AshOban, require_queues: false

There are situations where we'd like to test an app locally, and not have Oban running creating noise in the console.

Test helper functions like `assert_triggered`

When testing actions that can kick off background jobs, it would be nice to be able to have succinct and fine-grained assertions on exactly what jobs were fired.

Oban provides assert_enqueued, and that can be used eg.

# A job should be enqueued to make the meeting on Zoom
assert_enqueued(args: %{primary_key: %{id: appointment.id}}, queue: :zoom_api)

But nothing really more specific, given that worker modules are dynamically defined.

It would be great if assert_enqueued was wrapped in a way that if we had code like:

update :update do
  change AshOban.Changes.BuiltinChanges.run_oban_trigger(:create_zoom_meeting)
end

We could test it like:

{:ok, appointment} = Appointment.update(appointment, params)
assert_triggered(appointment, :create_zoom_meeting)

Trigger state ArgumentError

With ash_oban 0.1.9 and oban 2.16.2,

putting state :paused in a trigger

is failing on application start with ** (ArgumentError) expected valid job options, got: [paused: true]

Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]
Elixir 1.15.6 (compiled with Erlang/OTP 26)

UndefinedFunctionError

Seeing an UndefinedFunctionError and dialyzer is showing a pattern can never match the type error from ashoban (janajri@81375c0).

The error:

** (UndefinedFunctionError) function :trigger_no_longer_applies.valid?/0 is undefined (module :trigger_no_longer_applies is not available)

and the dialyzer error:

deps/ash_oban/lib/transformers/define_schedulers.ex:421:pattern_match
The pattern can never match the type.

Pattern:
:trigger_no_longer_applies

Type:
%Ash.Changeset{
  :__validated_for_action__ => atom(),
  :action =>
    nil
    | %{
        :__struct__ =>
          Ash.Resource.Actions.Action
          | Ash.Resource.Actions.Create
          | Ash.Resource.Actions.Destroy
          | Ash.Resource.Actions.Read
          | Ash.Resource.Actions.Update,
        :arguments => [any()],
        :description => nil | binary(),
        :name => atom(),
        :primary? => boolean(),
        :touches_resources => [any()],
        :transaction? => _,
        :type => :action | :create | :destroy | :read | :update,
        :accept => _,
        :allow_nil? => boolean(),
        :allow_nil_input => [any()],
        :atomics => _,
        :changes => _,
        :constraints => [any()],
        :delay_global_validations? => boolean(),
        :error_handler => _,
        :filter => _,
        :get? => false | nil | true,
        :get_by => atom() | [any()],
        :manual => atom() | {_, _},
        :manual? => _,
        :metadata => _,
        :modify_query => nil | {_, _, _},
        :pagination => _,
        :preparations => _,
        :reject => _,
        :require_atomic? => boolean(),
        :require_attributes => _,
        :returns => atom() | {_, _},
        :run => {_, _},
        :skip_global_validations? => boolean(),
        :soft? => _,
        :timeout => nil | pos_integer(),
        :upsert? => boolean(),
        :upsert_fields => nil | :replace_all | [any()] | {_, _},
        :upsert_identity => atom()
      },
  :action_failed? => boolean(),
  :action_type => :action | :create | :destroy | nil | :read | :update,
  :after_action => [(_, _ -> any()) | {_, _}],
  :after_transaction => [(_, _ -> any()) | {_, _}],
  :api => atom(),
  :arguments => %{atom() => _},
  :around_action => [(_, _ -> any()) | {_, _}],
  :around_transaction => [(_ -> any()) | {_, _}],
  :atomics => [{_, _}],
  :attributes => %{atom() => _},
  :before_action => [(_ -> any()) | {_, _}, ...],
  :before_transaction => [(_ -> any()) | {_, _}],
  :casted_arguments => _,
  :casted_attributes => _,
  :context => map(),
  :data => nil | struct(),
  :defaults => [atom()],
  :errors => [map()],
  :filters => _,
  :handle_errors => nil | (map(), _ -> any()),
  :invalid_keys => %MapSet{:map => MapSet.internal(_)},
  :load => [{_, _}],
  :params => %{atom() | binary() => _},
  :phase =>
    :after_action
    | :after_transaction
    | :around_action
    | :around_transaction
    | :before_action
    | :before_transaction
    | :validate,
  :relationships => %{atom() => [any()] | map()},
  :resource => atom(),
  :select => nil | [atom()],
  :tenant => _,
  :timeout => nil | pos_integer(),
  :valid? => boolean()
}

Handle non-existent actions more gracefully

Is your feature request related to a problem? Please describe.

Given a trigger setup with a non-existent action:

    trigger :send_email do
        action :send_email
        read_action :invalid_action
        queue :emailer
      end

I get the following error which doesn't tell me what I did wrong:

** (RuntimeError) Exception in transformer AshOban.Transformers.SetDefaults on MyResource:

key :pagination not found in: nil. If you are using the dot syntax, such as map.field, make sure the left-hand side of the dot is a map
    (ash_oban 0.1.4) lib/transformers/set_defaults.ex:40: anonymous fn/3 in AshOban.Transformers.SetDefaults.transform/1
    (elixir 1.14.4) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ash_oban 0.1.4) lib/transformers/set_defaults.ex:19: AshOban.Transformers.SetDefaults.transform/1
    (spark 1.1.22) lib/spark/dsl/extension.ex:679: anonymous fn/4 in Spark.Dsl.Extension.run_transformers/4
    (elixir 1.14.4) lib/enum.ex:4751: Enumerable.List.reduce/3
    (elixir 1.14.4) lib/enum.ex:2514: Enum.reduce_while/3

Describe the solution you'd like

An error/warning suggesting that the action doesn't exist would be very helpful. Just like the unpaginated read action warning.

Additional context

Not sure if this is an Ash Oban specific issue?

Add `queues` and `*_later`

In discussing ways we can integrate oban with Ash, we've found that the ability to trigger actions to run "later" (start an oban job that will run a given action) would be very useful.

The way this would work is via configured queues for given actions:

    queues do
      queue :some_queue do
        actions [:action_1, :action_2]
        ...
      end
    end

and then you could use AshOban.send_later(Api, Resource, :action)

and some builtin changes could also be used. Perhaps an AshOban api extension to add create_later to the api for Api.create_later() (as well as the other action types)

      change create_later(AnalyticsEvent, :create, fn changeset, result -> 
        %{action: :input}
      end)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.