Closed jnicklas closed 3 years ago
Thanks for kicking this off! I'm excited to start working on v2 😄
What issues do we see as blocking the v1 release? I don't think we've had any major breaking API changes in a really long time, and I don't see that there is an urgent need for it right now, so it might make sense to release v1 as-is?
I agree with the core proposal, and would like to include in the v2 plan some secondary issues / questions.
Channel
and Port
so that you can hand out references to things that can only publish things, or consolidating @effection/{events, channel, subscription}
into a single library.Finally, I've recently found the 7GUIs site and really like the approach of trying to identify the use-cases that highlight the heart of the problems. I think now that we've had a lot of experience with structured concurrency and the problems it solves (and in our case, creates because of deficiencies in the library!) I think we can outline our own tasks that can serve both as a guide for evaluating v2 design decisions, and also as documentation that we can publish directly.
Of course it doesn't need to be exactly 7, but these were the first that occured to me:
Promise.all()
or Promise.race()
.If we can fill out this list with anything that's missing, and then condense it so that we have either an implementation or a plausible plan for all of them, then I think we can be very confident that v2 will be able to do whatever anybody cares to throw at it. I imagine that we'll want v2 to be the version that we begin to evangelize and that we end up using for a very long time, and so I'd like to begin with great evidence for why it's awesome both to validate the design, but also to make the case to the public.
Very good question regarding renaming things. If we already align things towards the naming we want in v2, then we can make those changes now, and have less churn when we eventually move to v2, which will be more focused around the actual functionality, rather than naming changes.
Here are the things that I renamed in #194:
Context
-> Task
: I just don't like the name Context
, it's too generic and not descriptive to me. The fact that Rust uses Task
for a similar concept and ember-concurrency also uses it for an admittedly slightly different, but still related concept makes it feel like the correct name to me.Subscription
-> OperationIterator
: In practice we just don't use raw subscriptions very often, and so reserving such a "nice" name for them feels a bit backwards. This naming also aligns with Iterator
and AsyncIterator
, the already existing interfaces with similar functionality.Subscribable
-> OperationSubscribable
: Again, this aligns with the Iterable
and AsyncIterable
interfaces which already exist.ChainableSubscription
-> Subscription
: This gives the interface that we do use in practice a nicer name.I've created #205 to discuss a possible split of Channel into its sending and receiving end. IMO this is a good idea, and might be something we want to do before releasing v1
.
Great list of design considerations!
I think especially (5) and (6) are really great inclusions, since I did not give them any consideration in the design of mini-effection
.
I think answering a question like "what is the state of Effection right now" is very interesting, and we should definitely spend some time thinking about how best to answer such a question.
For example, one small thing that I've thought about is the ability to name spawned tasks:
function *server(handler: ...) {
// ...
task.spawn(`handler for request ${request.id}`, handler(request));
}
There are a lot of things to consider with making Effection more easily debuggable.
A lot of the questions surrounding the naming of things in for example @effection/channel
. I just had a thought. Can we hit 1.0 on effection itself without shipping 1.0 of the secondary packages like channel? This way we don't have to settle on an API on these component libraries until we feel confident about them.
What do you think?
I think that makes sense. One thing that I was thinking recently while trying to walk some folks through using Effection for the first time was that in order to accomplish anything non-trivial, you have to reach for several packages and know where to look for them. @effection/subscription
, @effection/channel
, and @effection/events
are foundational to almost every single effection application. It will make it a lot less confusing and spur adoption if we can eventually import them all directly from the effection
package proper.
Perhaps what we should do is develop the new mini-effection based effection in @effection/core
and then, when ready, just re-export all of the symbols from there in effection
as 1.0
Then, as we settle on what @effection/subscription
looks like, we can add it to the aggregator package effection
as 1.1, etc...
As we commit to each sub package's api, we can add it as a minor release to the effection
package.
We're nearing the beta release of BigTest, and once that has settled, IMO we should also start condsidering the path forward for Effection, and how we proceed with both the current version of Effection and a possible future version.
Let's recap some of the issues of the current version of Effection, and why we might want to make some fundamental changes:
yield
is async: For all of its faults (and there are many), one thing that the promise spec does get right is that all promises are always asynchronous. Evenawait Promise.resolve(3)
actually suspends and continues in the next iteration of the event loop. Effection currently allowsyield
to be synchronous as long asresume
is always called synchronously. Not only does this lead to issues like #26, but it is also dangerous and confusing to users. If ayield
is always synchronous, a user will have to be aware of this fact and build their code around this. The current situation encourages users to rely on the fact thatyield
can be synchronous, but if the called code ever does decide to suspend then this has the potential of introducing subtle bugs into the program.yield
is synchronous when spawning. It's worth pointing out that there is no inherent reason forspawn
to be an operation! Even today there is a non-operation API forspawn
via control functions, it is just not encouraged to be used. The same can be said for subscriptions. There is no reason for creating a subscription to be an async operation.spawn
occurs in, rather than using the current scope, solves the same issue that resources were meant to solve with a lot less magic and a lot less connfusion, at the expense of being more verbose and explicit.Given all of these issues, it is pretty clear that while Effection has been great and very useful for BigTest, there are some fundamental changes which will require some very fundamental changes at least, and a complete rewrite probably.
We've been aware of these issues for a while and so have been working on a replacement for Effection in the https://github.com/jnicklas/mini-effection/ repo. In #194 we did a proof of concept for whether this version of Effection could replace the current functionality in the effection monorepo and this experiment was largely successful.
My proposal is as following: