-
Notifications
You must be signed in to change notification settings - Fork 419
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
1.0 Roadmap #142
Comments
Things we may want to include in a 1.0 release:
|
If you plan to implement a new Promise API, you should allow some time for it to stabilize. Once you go 1.0, the API should really be frozen (assuming you are following semantic versioning). So, I’d recommend a 0.8 (or similar) to allow time for any new APIs to shake out before declaring 1.0. On Aug 6, 2014, at 9:13 AM, jdantonio notifications@github.com wrote:
|
I will recommit to having the fork-join stuff in over the next couple of weeks. |
other things to consider:
I think we are getting close too, but I would do 0.8 first. If that works out we can promote to 1.0 with just few bugfixes and freeze the API. |
We should be careful that the world object doesn't become something that tries to own too much or is too self-important. I like the fact at the moment that you can drop our features in and out of a program. I think we want to avoid a case where you have to create or init a global world object at the start of your program. I remember libraries like SDL or wxWidgets that always wanted to 'own' your program like that. |
@chrisseaton i see your point, we need to keep it simple to use. That's why I've also suggested to create a global world for convenience if user chooses to require it. On the other hand forcing the global world always can be problematic in tests and when combining e.g. two rails engines where both were already using concurrent-ruby in different ways. Having an global objects bit me too many times already, so I try to use suggested pattern to keep flexibility. # file:world.rb
class World
attr_reader :configuration # or possibly merge configuration into World
# etc.
end
# file:single_world.rb, needs to be required
WORLD = World.new |
I see the use case - multiple parts of an application all using concurrency in different ways. That does seem like good software engineering in general, but with concurrency things are different - you don't want two thread pools that each think they should create as many threads as there are cores. I think concurrency is just a global concern. Even the name I think this suits your actor stuff well where the framework needs to own the program to an extent, but works less well for things like futures and dataflow where it's very much the program just adding a few extra method calls here and there. |
@jdantonio Regarding Scala promises - I think they're basically an All these terms a bit muddled between different implementations.
|
@chrisseaton the |
world: @chrisseaton hm I did not think about the two big pools issue. An user would need to reduce the sizes to be able to keep both because of different overflow policies for example or inject one pool to the second world. What about: keeping the global thread pools but remove any configuration so they are always same in any application. If user needs custom configured thread-pool he can create other pool and use it as needed inserting it into his objects. This may be an unpopular step, but I think it makes sense to keep the global thread pools only for its specified usage and disallow reconfiguration for other purpose. |
The reason I created a global thread pool was to keep the simple use cases as simple as possible. This blog post is the perfect example. A user creates a bunch of futures for a simple task. If we don't have a global thread pool then the program changes entirely. One option would be for each future to get its own thread, which would be very inefficient. Another option would be to require the every user to manually configure a thread pool any time they want to use the gem. This would be a huge barrier to adoption. There are a couple of things that I like about the current setup:
One of my influences for the global thread pool was Clojure's agent which creates a single global pool for all agents. Unlike our current global thread pool, a user of Clojure's agents cannot reconfigure the pool. I'm definitely willing to revisit the idea of a global thread pool and change the way we do things. But I think we do a disservice if we force our users to always manually configure the gem. I this we should try to provide a simple yet reasonably performant default that serves the need of users like the one in the previously linked blog post. One other thing we need to consider is they type of application most likely to be written by our users. This is a Ruby library, not a Java or Scala library. I don't personally know any Ruby programmers who are writing processor-intensive applications. All of the Ruby programmers I know write IO-intensive applications. Limiting the global thread pool to one-thread-per-processor probably wouldn't be a very efficient approach. And it wouldn't help MRI users at all since MRI only uses one core. I know that it's impossible to know in advance how our users are going to use this gem, but I think we can make some reasonable guesses given the domains Ruby is most commonly used in. |
I think we might need a couple more releases before |
@jdantonio yeah i think in general we agree. I want to keep simplicity and flexibility too. I worry about the case of integrating two applications where each configures the global threads differently. To improve that use case I think there are 2 ways.
I think the 3. option is enough for the flexibility. If we agree on removing the configuration of global thread pools we could remove configuration and move the global pools directly under Concurrent module. Second: I think we can go either way. Did I omit other options? Btw what are your thoughts one the other points I wrote in #142 (comment)? |
Sorry for the delay!
|
@mighe I am starting to incline to the first option: to remove configuration from the global pools. It would be same as in clojure agents: there are |
@pitr-ch Sorry for the late reply. I've been very busy the past couple of weeks. I plan to spend the day today catching up. I'll post some additional thoughts later today. |
Random thoughts, in no particular order:
|
agents: I was referring to e.g. #70 but we should probably go through agent clojure's documentation in detail and check the behavior. Another point was integration with STM transaction as in clojure (functions are dispatched to agents after commit and only once). Then we should be compatible with clujure enough to be able to use clujure's implementation on JRuby (this is possibly after 1.0). The OOPing of the agents needs more discussion, it may be a nonsense. E.g. class MyAgent < Agent
def do_stuff(old_value)
old_value + 1
end
end
agent = MyAgent.new
agent.post :do_stuff # but what if :do_stuf is blocking and should go to #post_off? channel integration: channels are like blocking queues but user can |
Moved to #257 |
I'd like us to consider making our next release after 0.7 our 1.0 release. We've made significant gains over the spring and summer. We've deprecated a ton of my earlier experimental stuff, fixed many bugs, greatly improved the reliability of our test suite, merged ruby-atomic, created an automated build process for compiling platform-specific gems, and added an entirely new and feature-rich actor framework. That's an amazing amount of work. It seems to me that we've now implemented most of the "must have" items and are now looking mostly at optimizations, refactoring, and "nice to have" features. If everyone else agrees, then I think we can start planning a 1.0 release.
We've had previous discussions here and here but a lot has changed since then. Starting the discussion anew seems appropriate.
Thoughts?
We can use this issue to discuss specific features and updates for the eventual 1.0 release.
The text was updated successfully, but these errors were encountered: