Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Scott Treppa
@streppa
At the bottom of the script is how I want to interact with my lib. I had to juggle some things to get it working how I wanted.
But transitioning from dry-auto_inject 0.4.4 to 0.4.5+ results in an argument error. I'm pretty sure it on the 'super' call in MadLib#intialize.
'super' has to be called to get the injection to work.
Scott Treppa
@streppa
My actual implementation is for a ruby json api wrapper. I'd like to be able to set some values wrapper wide but with the ability to instantiate a new client with new parameters if necessary.
So... set host and api version in the configuration step but authentication credentials and other options might be different from client instantiation to instantiation.
Spencer Goh
@dymaxionuk

dry-transaction and wondering how one might facilitate long running tasks: eg.

step :preprocess_params
enqueue :generate_report # long running, handled by exector/threadpool or sidekiq
step :extract_and_parse_report_output
step :persist_to_storage
step :email_user_notification
  • I don't think there's a mechanism for callback and resumption of a next step.
  • some async/await fiber like dispatch and resumption of execution path would suit
  • in lieu of this, I'll have to
    • Split the transaction into 2 parts (before and after the async/long task)
    • have my long running task, on completion, callback/publish an event/message, then start TransactionPart2.call(result)

I like the idea that the transaction encapsulates and clearly declares the end to end steps, but I can't think of a clean way to handle the async or long running task.
I could wrap the whole transaction call in a thread/threadpool....

what's the best practice around this?

Nikita Shilnikov
@flash-gordon
dry-transaction works with Result/Either which is a synchronous computation. If you wrap it with a thread pool you should be fine. There is also Task in dry-monads 1.0,0.beta1+ that can be run on a thread pool
Tim Riley
@timriley
@dymaxionuk what you’ve done so far is the best one can do for the moment. I was actually thinking about this problem just a couple of weeks ago - I’d like to add support for re-entering/resuming a transaction mid-way so your initial plan becomes possible
I have transactions that suffer from exactly the same problem - an “enqueue” step forces me to split them into two
Jonah
@jonahx

In the dry-system docs it says:

When components are auto-registered, default identifiers are created based on file paths, ie lib/api/client resolves to API::Client class with identifier api.client.

How is API determined to be all caps here? I would think it would be Api...

Or is it assuming that the Client class defined my the file lib/api/client is inside a module called API?
Gustavo Caso
@GustavoCaso
it should be inside a module
or a class @jonahx
Gustavo Caso
@GustavoCaso
you can look at the test suite inside the library to see some examples
Hope this helps
Jonah
@jonahx
@GustavoCaso thanks
Jonah
@jonahx

I’m having trouble getting dry-system to work, and I think I’m missing something obvious, but even after reading the docs and test cases I don’t know what it is. In system/container.rb I have:

require 'dry/system/container'

class Application < Dry::System::Container
  configure do |config|
    config.root = Pathname('.')
    config.auto_register = 'domain'
    config.auto_register = 'use_cases'
  end

  load_paths!('lib', 'use_cases')
end

Application.finalize!

p Application['bot_reply']

and in system.import.rb I have:

require 'system/container'
Import = Application.injector

In lib/bot_reply.rb I have:

require 'dry-struct'
require 'import'

class BotReply < Dry::Struct
# stuff
end

If I execute system/container.rb as a test, I get the error:

Nothing registered with the key "bot_reply" (Dry::Container::Error)

What am I missing?

Tim Riley
@timriley
    config.auto_register = 'domain'
    config.auto_register = 'use_cases'
Those aren’t right if you’re expecting lib/bot_reply.rb to be registered
And you should only have one auto_register config (it can be an array)
try this:
config.auto_register = “lib”
then, after you’ve finalized your container, you can do Application.keys to see what it has
Jonah
@jonahx
@timriley I’m still getting empty keys after making those changes and fixing the typo you caught (lib should have been domain):
require 'dry/system/container'

class Application < Dry::System::Container
  configure do |config|
    config.root = Pathname('.')
    config.auto_register = 'domain'
    # config.auto_register = 'use_cases'
  end

  load_paths!('domain')
end

Application.finalize!

p Application.keys # => []
Tim Riley
@timriley
where is this application.rb file located?
And what does Application.config.root return?
Jonah
@jonahx

@timriley, if I test by running an app.rb from the project root (ie, the dir containing system and domain), which looks like this:

require_relative 'system/container'

p Application.keys
puts Application.config.root.realpath

I get the error:

require_component': could not resolve require file for bot_dialogue (Dry::System::FileNotFoundError)

bot_dialogue.rb is the alphabetically first file in the domain directory, so this is some progress. It looks like this:

require 'import'

class BotDialogue
#stuff
end

It errors before it gets to the line puts Application.config.root.realpath in app.rb so I can’t answer your other question.

Tim Riley
@timriley
@jonahx what is the directory that contains your “domain” dir?
Jonah
@jonahx
@timriley the root of the project
Tim Riley
@timriley
I think you should probably make that the value you pass to load_paths!
Your project seems to be structured differently to how most of us have used dry-system so this might be why you’re experiencing some hiccups
Jonah
@jonahx
@timriley I’ll try that now. but for clarity it looks like this:
root
  application.rb
  domain
    bot_dialogue.rb
    bot_reply.rb
Tim Riley
@timriley
@jonahx If you could push a skeleton of this structure up to a GH repo I’d also be happy to try sort it out for you too (if you’re still stuck after trying a few more things)
Jonah
@jonahx
Cool, thanks. Let me make sure I understand this conceptually… Is config.root supposed to be the project root, or something else? And what is load_paths! supposed to specify?
Tim Riley
@timriley
yes, the project root. and load_paths! is just a way of putting things on ruby’s $LOAD_PATH, relative to the project root
Jonah
@jonahx
@timriley thanks, i was able to get it working based on that and putsing $LOAD_PATH until it worked
Tim Riley
@timriley
@jonahx great!
what was your final working config?
Jonah
@jonahx
@timriley like this:
require 'dry/system/container'

class Application < Dry::System::Container
  configure do |config|
    config.root = Pathname(File.dirname(__FILE__)).parent
    config.auto_register = ['domain', 'lib', 'use_cases']
  end

  load_paths!('domain', 'lib', 'use_cases')
end

Application.finalize!
Jonah
@jonahx
new question: It looks like when I resolve auto-registered classes with #[] that new is automatically invoked on them. But I want the class itself to be returned, not the class called with new...
Jonah
@jonahx

to ground that question a bit, consider the example from the docs:

Application.register('utils.logger', Logger.new($stdout))

Let’s say that logger had been auto-registered. How would you specify the $stdout when creating it? Or some object may need to configure it with a different output, at runtime. So I want the Logger class itself, so I can call Logger.new(<whatever i want>) myself.

Tim Riley
@timriley
I can’t be around to help anymore, may I suggest you post to discourse.dry-rb.org?
Jonah
@jonahx
sure, thanks @timriley
Lairan
@alex-lairan

Hi ! :)

I try to use around in Dry-Transaction but I have troubles :s

This is my code:

class Containers::Transaction
  extend ::Dry::Container::Mixin

  register(:transaction) do |input, &block|
    puts "Before"
    ActiveRecord::Base.transaction do
      next block.(Failure(input))
    end
    puts "After"
  end
end
class User::Invitation::Send
  include Dry::Transaction(container: Containers::Transaction)

  around :transaction
  tee :model!
  step :persist!
  tee :mailer!
  step :email!

  .
  .
  .
end

And this give me

NoMethodError: undefined method `Failure' for Containers::Transaction:Class Did you mean? fail from /home/necros/.rvm/gems/ruby-2.3.6/gems/dry-configurable-0.7.0/lib/dry/configurable.rb:177:in `method_missing'

This happen with Success too.

Thanks for your help !

Oskar Szrajer
@gotar
Failure is a part of monads you need to include them to call it directly
or call it using whole class namespace
Gustavo Caso
@GustavoCaso
There is a handy module inside dry-transaction that might be helpful