-
Notifications
You must be signed in to change notification settings - Fork 605
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
Improve Ref #993
Comments
True, thanks. I'll just remove that point. |
@SystemFw just maybe for some thoughts re performance:
which imho clearly shows the overhead of the actor is significant. |
I'm making decent progress in removing |
Sort of ad hoc idea, but not sure about the impacts. I don't like the fact that Ref may be bot set/unset initially. How about having SetRef and UnSetRef, where SetRef will have |
What would be the semantics of Now, if you mean that Thoughts? |
Remember we also need |
Ah, didn't think about that, that's very good point |
GetIfSet would behave completely like current get, but will be available only on Unset ref, whoch in turn will miss get. Similarly SetRef will have only get but will be missing getIfSet. Is more like tupesafe way to distinguish between set/uset ref. Also i believe that setref could be then in fact SyncRef as it is today. |
I have been thinking about this a more, and I think we don't need AsyncRef and SyncRef. I think currently, all the functionality of the AsyncRef may be implemented with the So essentially I think we should end up with This will also allow, that both references will require only Note that this also solves the situation, where you want to supply your own EC when performing async operations (ie. Also I believe that this approach may lead to Ref that does not have Any thoughts? |
Just for the record, yesterday night I started an attempt to build a Ref (including the semantic blocking on empty) using AtomicReference only. At the moment it's broken (and I have to add more tests to RefSpec anyway, if we're going to touch it more deeply), but you can get an idea, and perhaps offer suggestions as to why it's not working yet, here: EDIT: Just found (one of) the bugs |
Sounds great to me. A single implementation would make it easier to include in cats-effect too. |
General fs2 test suite passing with an Actor-less Ref. |
@SystemFw I think the |
@SystemFw when you will be done we can run the simple test above. ... |
The version I have now seems to be working, but it maintains the general idea of the old Ref. Once I consolidate it a bit we can decide if it's Ok, or if we should be making an attempt to revise the implementation strategy more deeply (e.g. by having it built on top of |
That simple test is a good start yeah, but probably needs to be expanded to test contention as well. |
I would say that simple test shown rationale, if we would be close to it ti should give us enough confidence that we didn't slow things down. |
We might not need that |
ok sure perfect. Good job :-) |
Initial benchmarks show pretty much identical performance for Ref implemented with or without Actor (lol) compared to SyncRef, i.e. a lot slower. However the non-Actor implementation allows taking a closer look at what's going on from a code point of view. I'll keep investigating. |
@SystemFw, interesting. I think this comes to complexity which unset state brings to the table. I think we have to look on this, really I believe that hence the unset is only done once in whole lifetime of ref, we shall really get away all that orchestration whenever possible. |
Yeah, I opened a PR so we can start analysing what's going on |
FYI, I've also opened a PR related to this: #1007. |
This can be fleshed out, but for now let's collate the ideas about things worth improving in Ref.
Is Actor necessary or can we use something more lightweight? What's the actual overhead of Actor ?
The behaviour of
setSync(fa: F[A])
andsetAsync(fa: F[A]
) has been weird for a while. A failure infa
will make them succeed, and the subsequentget
will fail.setSync
could be easily fixed, and probably replaced byfa.flatMap(setSyncPure(a))
altogether. Can we do the same withsetAsync
? Is havingsetAsyncPure
enough (so that thefa
will run synchronously, and thesetAsyncPure
asynchronously)Related to the above, if actions in
set*
can't fail, do we needEither[Throwable, A]
as the state of the Ref? Shouldn't a reference to A be enough? Things likestart
could be recovered via an explicitRef[F, Either[Throwable, A]]
As a counterpoint to the above two points, what about
modifyF
(RFE: Ref/Signal modifyF #888). To have the expected semantics (effect only run once,Change
is faithful), the only way I could envision is sending a closure (or an IO) to the Actor, which is only run when it wins the contention race. Unclear at the moment if that invalidates the actions that set the Ref shouldn't be able to fail hypothesis, and therefore cement the need for having anEither[Throwable, A]
as the state ofRef
.As a broader point, users now have
runAsync
andshift
in their API, which they didn't before, which might influence how (or whether) we rethink RefIf this sounds non-organic and confused, it's because it still is (in my head), please challenge/correct.
Relevant discussions:
#989
#986
#888
#974 (initial push, not much in terms of discussion of Ref)
@mpilquist @pchlupacek
The text was updated successfully, but these errors were encountered: