Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plans for 1.0.0 #127

Closed
1 of 7 tasks
timriley opened this issue Jun 30, 2019 · 26 comments
Closed
1 of 7 tasks

Plans for 1.0.0 #127

timriley opened this issue Jun 30, 2019 · 26 comments

Comments

@timriley
Copy link
Member

timriley commented Jun 30, 2019

Please see the comments as the discussion has gone into a different direction after all


Original description that's now obsolete

A lot has changed since dry-transaction was brought into the dry-rb family in 2016: dry-monads was later created, and for the last year, it has offered its Do Notation feature, which provides an expressive API for chaining dependent sequences of commands. Do notation is far more flexible than dry-transaction's simple "step" definitions while being just as easy to use, and it is now our recommended solution for this kind of behaviour.

As such, we'll be soon releasing dry-transaction 1.0.0, then ceasing further development.

Here's what will happen:

  • Ship an upgraded Result matcher in dry-matcher, to support matching on Failure codes (this will provide an equivalent to dry-transaction's built-in result matching)
  • Address any legitimate bugs remaining in dry-transaction's current feature set
  • Move dry-transaction documentation from dry-rb.org into the dry-transaction README (or alternatively, a set of markdown files in a docs/ dir)
  • Add some examples of using dry-monads Do notation as a replacement for dry-transaction
  • Add a notice to the top of dry-transaction's README stating that active maintenance and development within within the dry-rb project has ceased, and that the project can be forked and renamed if anyone wishes to create a successor.
  • Release 1.0.0
  • Remove dry-transaction from dry-rb.org, and add a redirect from dry-rb.org/gems/dry-transaction to the README of this repo

The purpose of this issue is to track all these steps.

If you have any questions, feel free to reach out on https://discourse.dry-rb.org!

@michaelherold
Copy link

A nice-to-have would be clear, concise examples for how to replicate the behavior of the different dry-transaction step adapters in Do Notation. For example, tee is very useful. I'm not sure if it's able to be 100% implemented in Do Notation, can it? A naive implementation would be something like:

class MyCommand
  include Dry::Monads::Result::Mixin
  include Dry::Monads::Do.for(:call)

  def call(params)
    values = yield validate(params)
    yield log(params)
    Success(values)
  end

  def validate(params)
    # ...
  end

  def log(values)
    Logger.new.info(values)
    Success(values)
  end
end

That seems like it would be right? It's a little clumsy though.

What do you think?

@timriley
Copy link
Member Author

@michaelherold this is a good idea, I'll add it to the TODO list in the main issue body above.

As for replicating the tee behaviour, I don't think we need to do anything so special, it's just this:

def call(params)
  values = yield validate(params)
  
  # nothing special, just a plain old method call
  log(params)

  # do more steps here
end

@no-reply
Copy link

no-reply commented Oct 1, 2019

Is this something there's interest in following through on?

A few times now I've had folks react with confusion when I mention that I'm not developing dependent code anymore, since there's no mention(?) of development being phased out in the README or on dry-rb.org

no-reply pushed a commit to samvera/hyrax that referenced this issue Oct 15, 2019
This is a first hack at `Dry::Transaction`-like behavior with Do notation.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
@jdickey
Copy link

jdickey commented Oct 30, 2019

Move dry-transaction documentation from dry-rb.org into the dry-transaction README (or alternatively, a set of markdown files in a docs/ dir)

I'd vote for the separate-docs-directory approach; a quick-and-dirty render-everything-in-a-single-Markdown-file experiment yielded a ~480-line, seven-and-a-half-rendered-pages (on a large monitor) file that felt far clunkier than the existing docs. I've added an item to my personal TODOs to write a PR for this sometime next week, health and time permitting.

I agree enthusiastically with the overall point of this issue; do notation is a far more flexible, low-DSL way to get the job done.

@graudeejs
Copy link

FYI, link to Do Notation is broken in description of the issue. It should be something like: https://dry-rb.org/gems/dry-monads/1.0/do-notation/

@paul
Copy link

paul commented Feb 1, 2020

I started using dry-transaction in 2018 after having used most of the command/interactor pattern gems, and fell in love with it. I have to say I am disappointed with this news. Even though it is more "magical", it provides an explicitness in its DSL that is missing from the plan do-notation.

Borrowing the example from @michaelherold:

# Do-notation
class MyCommand
  include Dry::Monads::Result::Mixin
  include Dry::Monads::Do.for(:call)

  def call(params)
    values = yield validate(params)
    values = yield transform(values)
    log(values)
    Success(values)
  end

  def validate(params)
    MySchema.call(params).to_monad
  end

  def transform(values)
    Success(values.transform_keys(&:to_s))
  end

  def log(values)
    Logger.new.info(values)
  end
end

# Transaction
class MyTransaction
  include Dry::Transaction

  step :validate
  map  :transform
  tee  :log

  def validate(params)
    MySchema.call(params).to_monad
  end

  def transform(values)
    values.transform_keys(&:to_s)
  end

  def log(values)
    Logger.new.info(values)
  end
end

The step DSL in the transaction removes a lot of the boilerplate and general "noise" present in the #call method, and to me feels a lot cleaner. It keeps the pure "business logic" isolated inside the step implementation, while the "ceremony" of managing Results is handled cleanly and explicitly by the DSL.

In our app, we've also utilized the Dry::Events notifications from each step to automatically log the step and the Result, which has been extremely useful, and seems harder to accomplish with Do-notation. We use Rails' TaggedLogger to add a tag for each Transaction being called, making it very easy to trace:

Feb 01 18:10:09 [Messaging::Ingress::HandleMessage] [Conversations::Fetch] Transaction succeeded in 53.00ms 
Feb 01 18:10:09 [Messaging::Ingress::HandleMessage] [Messaging::Attachments::Upload] Transaction succeeded in 9.02ms 
Feb 01 18:10:09 [Messaging::Ingress::HandleMessage] [Integrations::HandleMessageEvent] Transaction succeeded in 14.32ms 
Feb 01 18:10:09 [Messaging::Ingress::HandleMessage] Transaction succeeded in 341.33ms 
---
Feb 01 18:10:09 [Messaging::Ingress::LayeredReceiptParser] Failure in :validate step. Input: {"messageId"=>"m-4hwzflo4knjxjslrdnpx4da", "eventType"=>"sms", ... } 
Feb 01 18:10:09 [Messaging::Ingress::LayeredReceiptParser] Transaction failed in 0.52ms 

Dry::Transaction also does a nice job of automatically pulling in other Dry building blocks, like Containers. For us, Dry::Transaction was the gateway drug to introduce most of the rest of the Dry ecosystem into our Rails application. Now, we have nearly 250 Transactions in our app. (I was amazed when I just looked that up. I was gonna guess 50. It does not feel cumbersome at all, the app is very easy to work on).

Perhaps I'm just misunderstanding Do-notation, but it seems to me that its missing a great deal of additional features that Dry::Transaction provides, which we've come to rely on. Is "use Do-notation instead" the only reason for discontinuing Dry::Transaction, or is it the additional maintenance burden? If the latter, I'm happy to step up and help with the maintenance. Perhaps Dry::Transaction post-1.0 could be refactored to use Do-notation internally, but still expose the step DSL and the Events features (or maybe thats even a separate library).

no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 1, 2020
This is a first hack at `Dry::Transaction`-like behavior with Do notation.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 1, 2020
This is a first hack at `Dry::Transaction`-like behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 2, 2020
This is a first hack at `Dry::Transaction`-like behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 2, 2020
A first hack at `Dry::Transaction`-like dependency behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 2, 2020
A first hack at `Dry::Transaction`-like dependency behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
@jdickey
Copy link

jdickey commented Feb 3, 2020

@paul I can well understand that sentiment. I happen to prefer do notation for what I suspect is the exact opposite reason to your dislike of it: it utilises an instance method (#call), and thus allows/encourages the step methods it calls to be private. The dry-transaction DSL, admittedly cleaner and more explicit in several respects, at least encourages the methods called by the DSL class methods (e.g., step) to be public methods. That is frowned upon nowadays much more than it was a few years ago, when DSLs were all the rage.

It's not so much that dry-transaction has bugs that are too troublesome/expensive to fix, but that it's predicated on a coding style that a) is no longer as widely used as it had been, and thus b) does not mesh well with other current and plausible future directions of the dry-rb ecosystem.

At least that's how it appears to this outside, non-core-team user and observer. Feel free to throw popcorn and/or hand grenades as appropriate, all. 😀

no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 5, 2020
A first hack at `Dry::Transaction`-like dependency behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
no-reply pushed a commit to samvera/hyrax that referenced this issue Feb 5, 2020
A first hack at `Dry::Transaction`-like dependency behavior with Do notation.

Adds Do-style transactions for applying ChangeSets and for creating Works.

See: dry-rb/dry-transaction#127
and: https://dry-rb.org/gems/dry-monads/1.0/do-notation/
@solnic
Copy link
Member

solnic commented Feb 9, 2020

Perhaps Dry::Transaction post-1.0 could be refactored to use Do-notation internally, but still expose the step DSL and the Events features (or maybe thats even a separate library).

This is an idea worth to explore. If it can be done easily I'd be in favor of keeping dry-transaction alive.

@gottfrois
Copy link

I want to add my 2 cents here and say that I also really like the simplicity of dry-transaction which, in my opinion, reads better than the do notation. For us as well it was the gateway to using more and more every day dry-rb gems and still is.

The do notation seems like something that should be used to build lower-level components and is missing a more user-friendly interface on top (dry-transaction anyone?).

@paul
Copy link

paul commented Feb 28, 2020

I haven't actually tried it, but isn't "refactor dry-transaction to use do-notation" basically:

include Dry::Monads::Do.for(:call)

def call(input)
  steps.reduce(Success(input)) do |result, step| 
    yield step.call(result)
  end
end

@solnic
Copy link
Member

solnic commented Feb 28, 2020

@paul I implemented a PoC a couple of weeks ago, see https://gist.github.com/solnic/66d663790a956fc811ee376249ec0447

@timriley
Copy link
Member Author

timriley commented Feb 29, 2020 via email

@no-reply
Copy link

@timriley thanks for this update.

i'm in the position of making a decision about moving forward with this gem, or with a localized wrapper around Do Notation. until this message, i assumed the localized wrapper was the best approach. but if there's a commitment to keeping this alive, and some guidance about what to expect/how to be involved, that would be a boon.

how can i help?

@jcmfernandes
Copy link

@timriley given your last statement, shouldn't the disclaimer present on the website about deprecation be removed?

@solnic
Copy link
Member

solnic commented May 27, 2020

@jcmfernandes thanks for pointing it out! I just changed it instead of deleting it though.

@solnic solnic changed the title Release 1.0.0 and discontinue active development Plans for 1.0.0 May 27, 2020
@rinaldifonseca
Copy link

@timriley @solnic I am starting a new project. Should I use dry-transaction without worry about the future?

@timriley
Copy link
Member Author

timriley commented Jun 9, 2020

I think you should be fine. The next evolution of this gem might not retain every current feature/behaviour, but we'll have to provide clearly documented migration paths for current users no matter what.

@Codcore
Copy link

Codcore commented Jul 26, 2020

Hi, guys! I really like dry-transaction gem, and use it massively. Is there chance to see new versions soon?

@solnic
Copy link
Member

solnic commented Jul 26, 2020

@Codcore hey, this has to wait until after hanami 2.0 is released, unless somebody steps up and takes over the maintenance.

@timriley
Copy link
Member Author

In the meantime I'm going to close this issue. As I mentioned above, people can feel free to use 0.13.0, and for any subsequent releases, we'll be sure to provide clear migration paths for any aspects of the feature set that may significantly change.

@tiev
Copy link

tiev commented Feb 2, 2021

I've used dry-transaction on production for a CSV importing process. And I've refactored it to use Do-notation.

My experience was very positive. Do-notation gave a cleaner code and easier to understand the reason for each step.

  • dry-transaction has the DSL, while Do-notation has the body of #call method. Both are very easy to read (if you follow best-practice of short method length).
  • The events of dry-transaction can be easily implemented by include Dry::Events::Publisher.
  • One thing that Do-notation is better is the flow of data. Because of the linear-nature of dry-transaction, data is passed from step to step. Something like this is very easy in Do-notation but not in dry-transaction
def call
  user = yield find_user
  company = yield find_company
  employment(user, company)
end

I will never go back to dry-transaction after writing code in Do-notation. I feel it's more matched with the style of whole dry-rb gems, where we can combines gems for only the features we need. dry-transaction bundle many features inside a DSL that I feel not very easy to use (mainly because of the data flow).

@solnic
Copy link
Member

solnic commented Feb 2, 2021

@tiev thanks for sharing this experience! I feel like many people like dry-transaction because it's just easier to get started and it feels more familiar, that's all.

@pboling
Copy link

pboling commented Mar 23, 2022

https://dry-rb.org/gems/dry-transaction/master/ The warning is still in latest docs. It appears from this discussion, and the fact that dry-transaction is now based on dry-monads, that dry-transaction survives? Will there be a 1.0 release?

@solnic
Copy link
Member

solnic commented Mar 24, 2022

It appears from this discussion, and the fact that dry-transaction is now based on dry-monads

We're considering rebuilding it on top of dry-monads

dry-transaction survives? Will there be a 1.0 release?

Double yes 🙂

@ShalokShalom
Copy link

ShalokShalom commented Aug 5, 2022

@tiev I feel like many people like dry-transaction because it's just easier to get started and it feels more familiar, that's all.

Oh yeah. I was just reading the documentation and thought exactly this.

I am coming from FSharp, and dry-rb seem to introduce already a bit more to the syntax as I am used to.

dry-transition is a welcome exception and I would welcome much more libraries like this, not less. ✌🏻

I would also consider re-opening this issue.

Thanks a lot 😊

@santiagodoldan
Copy link
Contributor

I use dry-transaction on several projects and I'd love to understand if there are plans to get a 1.0 version in 2024, I'd love to help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests