From: Steven Parkes Date: 2008-07-27T07:10:18+09:00 Subject: Re: DSL/thread design question > I am writing something which I am calling "suits" for now -- the idea > being "something you make with threads". It's a lightweight > actor model. You might want to look at dramatis: http://dramatis.mischance.net/ Of course, I'm biased, but I did create it out of actor-envy towards Erlang. > s = Suit.new([]) s = Dramatis::Actor.new( [] ) => Dramatis::Actor::Name === s in dramatis. > s.push(1,2,3,4,5) # asynchronous, so ignoring the > return value release( s ).push(1,2,3,4,5) => nil > s[2].now # returns 3 s[2] => 3 > s.length.then{|l| puts l} # prints 5, at some point This rather ungainly syntax: ( interface( s ).continue { |l| puts l } ).length => puts 5 or, in the next release, slightly better: ( continuation( s ) { |l| puts l } ).length => puts 5 > s.join # reap the thread There's no equivalent for this right now ... among other things, each actor doesn't have a unique thread; they're shared as necessary. But there should probably be a way for actors to exit a la Erlang's exit ... or is GC enough? I'm a little unsure on this. > My motivation is to at least make multithreaded Ruby an > attractive option, so > that there is a motivation to remove the Python-esque Global > Interpreter JRuby doesn't have a GIL. But my results of using threads on JRuby are still a little strange (but it may be my fault). (By the way, dramatis also runs on python and some of the examples run on jython but I haven't run the full suite of tests on jython yet). > So, should this be synchronous by default? (Right now, it's > not.) In my past work with actors, making things async by default was painful (but, then, I didn't have lambdas, which help). I haven't made async the default in dramatis: I prefer to start from something close to serial and incrementally expose concurrency. But it is possible to code to get it async by default, for example: s = Dramatis::Actor.new( [] ) s = release( s ) would make all subsequent calls on s async by default. The proxy object maintains the type of continuation that will be used when calls are made against that proxy. > Maybe I > should return a "promise" instead, so that things are > asynchronous until you > actually need information out of the returned value. Dramatis has futures, though they're experimental (actually, all of dramatis is, they're just _more_ experimental.) In my limited tests, each kind of continuation has uses for which it is more natural than the alternatives. > Second, for asynchronous calls, since I'm using a Queue, > things arrive > in-order. Yeah; you're relying on that in your example. Otherwise, you can't guarantee that the #push has executed before the #[] runs. > Would there be an advantage to not requiring that behavior? It generally works out the other way: often people want guaranteed ordered queuing, at least among messages sent between the same pairs of actors (so things like your example work). But while this is easy in a single process, it's more difficult when you're exchanging messages over the network. Writing code that can't rely on ordering can get tricky (think of what you'd have to do to your simple example). Dramatis has selective receive (though implemented differently than Erlang) which helps loosen the need for in-order delivery in some contexts. > And finally, what about exception handling? Right now, dramatis tries to deliver exceptions to the caller where it can, e.g., on blocking/rpc-style calls. I'm really not sure this is a good idea, though it's been helpful in my toy examples. This isn't what Erlang does, where you need to catch the exception explicitly and send it to the caller; otherwise uncaught exceptions kill the actor (Erlang process). Erlang really sets the bar for this: while one may not completely love the way they've implemented things, they have large systems that perform reliability. Their linked actors is a hugely valuable feature. If you made every actor linked by default, then you'd get the behavior you want, where killing an actor killed the program (unless they took measure to stop that.) Dramatis doesn't have this yet but I sure wish it did and hopefully it will ...