question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I want there to be a method on a Var[A] that takes in a function A -> (A,B) and returns a B. This would be a generalization of update. This can be simulated using now() and set(), but then there are two separate transactions.

Also, is there a way of doing this without modifying Airstream itself that I am missing?

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
olynchcommented, Aug 25, 2022

OK, this is actually fine though, because I could actually wrap this in a future and then pass b into the callback. This is already inside of some async stuff, so this meshes well. I think you can close this issue now. Thank you so much for helping me out here!

0reactions
raquocommented, Aug 22, 2022

@olynch Although Javascript itself is single threaded, because of Airstream’s transaction system, the $a.set method is not guaranteed to actually update the Var immediately, it can de delayed until the current transaction is done. See https://github.com/raquo/Airstream#var-transaction-delay for details.

So yes, if you just write that snippet of yours, your other code can indeed change the value of $a after you called $a.now(), but before you called $a.set, for example if you have the following all inside the same Observer callback:

$a.set(ignoredA) // this does not update `$a` immediately because we're inside of an observer
val a = $a.now() // this reads the value immediately, so it reads the original value from `$a`, not `ignoredA` which wasn't set yet
val (newA,b) = f(a)
$a.set(newA) // this is also run at a delay, but it will run after the first `$a.set` above, overriding `ignoredA`.

As I mentioned, to solve this, you need to wrap the code that you want to run together/unbroken in a new Transaction. There are several ways to do it, but I guess the most obvious is this:

$a.set(firstA) // put this here, so that its transaction executes before the following `new Transaction`
new Transaction { _ =>
  val a = $a.now() // will read `firstA`, because this `new transaction` will be run after the `$a.set(firstA)` transaction.
  val (newA,b) = f(a)
  $a.set(newA)
}

For this to work, any $a.set / $.update that you do before $a.now() must be outside of new Transaction, if you want $a.now() to see those updates.

Notice that you can’t return B from the new Transaction block, for similar reasons why you can’t return B from an expression that is Future[B] – the B is not available yet.

We could potentially make Transactions return a value and provide a Future-like API with onComplete to get the value when it’s ready, but there would need to be some real strong justification for that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Eloquent update and get record back - Stack Overflow
Is there a more efficient way to update and get the records in one call/request to the database? php · mysql · laravel...
Read more >
Check & update your Android version - Google Help
Get the latest Android updates available for you · Open your phone's Settings app. · Near the bottom, tap System and then System...
Read more >
get update or get updates? - TextRanch
Here's how to get updates for Windows and other Microsoft programs at the same time, including updates for Microsoft Office (Word, Outlook ,...
Read more >
Get the latest Windows update - Microsoft Support
To check for updates, select Start > Settings > Windows Update , then select Check for updates. If updates are available, you can...
Read more >
sudo apt-get update vs upgrade – What is the Difference?
sudo apt-get update and sudo apt-get upgrade are two commands you can use to keep all of your packages up to date in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found