dry-rb / dry-operation

MIT License
24 stars 5 forks source link

Basic class to define routine context and to mount it into fiber #12

Closed vTinMan closed 1 year ago

vTinMan commented 1 year ago

Overview

Routine context feature based on fiber storage.

Useful to have this tool when we develop a project with number of vendors or customers with their own scope of settings and data scopes and we need to implement complex multi-component operations including several classes related to vendor properties.

Details

Simple draft example:

class MyMultiOperation < Dry::Operation
  def call(input)
    steps do
      info = step composer.call(input)
      result = step reporter.call(info)
      result
    end
  end
end

class Composer
  def call(input)
   # Dry::Monads::Result::Success or Dry::Monads::Result::Failure
  end

  def current_vendor
    routine.vendor
  end
end

class Reporter
  def call(info)
   # Dry::Monads::Result::Success or Dry::Monads::Result::Failure
  end

  def current_vendor
    routine.vendor
  end
end

class Routine < Dry::Operation::Routine
  attr_reader :vendor

  def initialize(vendor)
    @vendor = vendor
  end

  def callee
    MyMultiOperation.new
  end
end
timriley commented 1 year ago

Hi @vTinMan, thanks for taking the time to make this contribution!

However, I think it's a little too early in dry-operation's life to incorporate something like this. We're still putting the basics together. We’ll want to wait until all the basics are in place and feeling good before we consider things like this.

This PR also introduces too many new things at once, with very little to explain them: a plugin system (with some references to dry-system, which confuse me a little), a new Routine user-facing entry point, as well as the interaction between it and operations.

If you'd like to advocate for this kind of feature to be included in dry-operation one day, I think it'd be good if you could share a post on our forum better explaining your use cases and motivations behind this PR. Focus on what you’d like to achieve in the end, rather than an exact implementation. I think there’ll be various different implementation paths we might want to consider (if we did something like this at all, I can’t promise anything right now!), and having a clear pitch laid out will help us do that.

For example, I think you could already achieve what you want (within any kind of classes) using dry-effects. Have you given that a try?

In general, posting on the forum would be our recommended approach for any large features you might want to add to our gems, because then we could give you guidance before you commit too much time to putting together code.

waiting-for-dev commented 1 year ago

As Tim said, dry-effects is the first thing that came to my mind for your use case. I think Reader is what you're looking for, although State can be useful if you need to change stuff along the way.