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

STM retry/orElse semantics #8696

Closed
durban opened this issue Mar 26, 2024 · 6 comments · Fixed by #8845
Closed

STM retry/orElse semantics #8696

durban opened this issue Mar 26, 2024 · 6 comments · Fixed by #8845

Comments

@durban
Copy link

durban commented Mar 26, 2024

This issue is a case of "behaves differently from Haskell", so I'm not even sure this is a bug. (Although the Haskell behavior seems more useful to me.)

Apparently, Haskell's STM retries a transaction if any of the variables read in any branch of an orElse change. (See section 3.4 here.) It seems ZSTM doesn't do this: it only retries if the TRef read by the RHS/second transaction changes. For example, this program hangs:

    for {
      ref1 <- TRef.makeCommit(0)
      ref2 <- TRef.makeCommit(0)
      txn1 = ref1.get.flatMap {
        case 0 => STM.retry
        case n => STM.succeed(n)
      } orElse ref2.get.flatMap {
        case 0 => STM.retry
        case n => STM.succeed(n)
      }
      txn2 = ref1.set(1) // if this is `ref2.set(1)`, it doesn't hang
      fib <- txn1.commit.forkDaemon
      _ <- ZIO.sleep(zio.durationInt(1).second)
      _ <- txn2.commit
      r <- fib.join
    } yield ()
@durban
Copy link
Author

durban commented Apr 25, 2024

Based on this part of the documentation, it probably should work like haskell. And note, that for orTry it does. So this seems like a bug in orElse.

@jdegoes
Copy link
Member

jdegoes commented May 8, 2024

/bounty $250 for fix and test to accompany it.

Copy link

algora-pbc bot commented May 8, 2024

💎 $250 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #8696 with your implementation plan
  2. Submit work: Create a pull request including /claim #8696 in the PR body to claim the bounty
  3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Additional opportunities:

Thank you for contributing to zio/zio!

Add a bountyShare on socials

Attempt Started (GMT+0) Solution
🟢 @BijenderKumar1 May 11, 2024, 6:17:07 PM #8845

@BijenderKumar1
Copy link
Contributor

BijenderKumar1 commented May 11, 2024

/attempt #8696
I reproduced the issue and found that the changes in the LHS (first branch) for orElse do not trigger a retry of the transaction, as pointed out. However, it works correctly with orTry instead of orElse. I dived deep into the ZSTM.scala file where the orElse function is defined. It seems that the issue is with the prepareResetJournal function, which resets the journal to empty each time it is invoked, and therefore, any changes in the first branch are not triggering a retry. I will be fixing the issue and raising the PR soon. Thanks!

Copy link

algora-pbc bot commented May 11, 2024

💡 @BijenderKumar1 submitted a pull request that claims the bounty. You can visit your bounty board to reward.

jdegoes pushed a commit that referenced this issue May 22, 2024
* Resolve journal reset issue with orElse function definition

* Remove extra braces

* Resolve Formatting issues, CI Test Failures, and add a new test for LHS variable updates in orElse Test Suite

* Make reset function private

* Review unnecessary comment

* Resolve linting errors
Copy link

algora-pbc bot commented May 22, 2024

🎉🎈 @BijenderKumar1 has been awarded $250! 🎈🎊

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

Successfully merging a pull request may close this issue.

3 participants