- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
[newbie] Question about actor concurrency?
Mon, 2009-04-27, 19:42
Hi ... scala newbie with a question on actors and concurrency. I've been
reading
several articles and tutorials but haven't understood how to answer my own
question and
a search of this archive did not reveal an answer that seemed to apply ...
I'm considering using scala as a backend option to a web/database app. The
web page
would allow the user to request a PDF report. Since that will be a long
running process
I want to pass that off to a scala program. But I also don't want to
process the PDF reports
one at a time, because if 100 people request a PDF, then they could end up
waiting
30+ minutes for results.
If I have some sort of:
loop {
react {
case .... create_the_pdf(user)
}
}
is that all that is needed? I mean if 100 people request a PDF and I send
100 messages to this
actor to create the pdf, will it automatically spawn off 100 copies of
itself to process simultaneously?
Related, if I only wanted to process say 20 PDFs at a time (to avoid using
up system resources), how
does one limit the processing to 20 a time for example?
Thanks for you time and patience.
Rogelio
Tue, 2009-04-28, 09:27
#2
Re: [newbie] Question about actor concurrency?
2009/4/28 Szymon Jachim :
> If an actor is blocked by a time consuming blocking operation it is
> blocked... no matter if it's a loop-react (I find the name thread-less quite
> unfortunate) or while-receive type actor.
>
> It's easy to be checked with:
>
> import scala.actors._
> import Actor._
>
> val a = actor { loop { react {
> | case msg => println("starting"); Thread.sleep(2000);
> println("done"); reply(msg);
> | }}}
> a: scala.actors.Actor = scala.actors.Actor$$anon$1@1eb8f71
>
> a ! 1; a ! 2; a ! 3
>
> You can either make the bocking operation more granular so parts of it can
> be done by separate actors in parrallel or make copies of the executor actor
> to make use of all the cores... because obiously, if the target machine
> isn't capable of doing things in parallel you won't get anything.
>
> To create multiple copies of an executor actor I like to clone them like
> this
>
> val archetype = actor { loop { react { ... } } }
> val pool = 8 * archetype
>
> See my blogpost to see how to implement the magic multiply operator
> http://dzhigital.blogspot.com/2009/03/cloning-scala-actors.html
>
That looks rather needlessly magic and error prone compared to val
pool = List.range(0, 8).map{i => actor { loop { react { ... } } } }.
Tue, 2009-04-28, 09:37
#3
Re: [newbie] Question about actor concurrency?
FP allows to be so terse and put so much in one line but I'm not sure that I want to do it...
That said I won't protest against something like:
def createPool(n: Int, a: => Actor) = List.range(0, n).map{ i => a }
val pool = createPool(8, actor { })
Now is
val pool = 8 * actor { }
really that less readable? :-)
Szymon
On Tue, Apr 28, 2009 at 10:22 AM, David MacIver <david.maciver@gmail.com> wrote:
--
ʎɐqǝ uo pɹɐoqʎǝʞ ɐ ʎnq ı ǝɯıʇ ʇsɐן ǝɥʇ sı sıɥʇ
That said I won't protest against something like:
def createPool(n: Int, a: => Actor) = List.range(0, n).map{ i => a }
val pool = createPool(8, actor { })
Now is
val pool = 8 * actor { }
really that less readable? :-)
Szymon
On Tue, Apr 28, 2009 at 10:22 AM, David MacIver <david.maciver@gmail.com> wrote:
2009/4/28 Szymon Jachim <sjachim@gmail.com>:
> If an actor is blocked by a time consuming blocking operation it is
> blocked... no matter if it's a loop-react (I find the name thread-less quite
> unfortunate) or while-receive type actor.
>
> It's easy to be checked with:
>
> import scala.actors._
> import Actor._
>
> val a = actor { loop { react {
> | case msg => println("starting"); Thread.sleep(2000);
> println("done"); reply(msg);
> | }}}
> a: scala.actors.Actor = scala.actors.Actor$$anon$1@1eb8f71
>
> a ! 1; a ! 2; a ! 3
>
> You can either make the bocking operation more granular so parts of it can
> be done by separate actors in parrallel or make copies of the executor actor
> to make use of all the cores... because obiously, if the target machine
> isn't capable of doing things in parallel you won't get anything.
>
> To create multiple copies of an executor actor I like to clone them like
> this
>
> val archetype = actor { loop { react { ... } } }
> val pool = 8 * archetype
>
> See my blogpost to see how to implement the magic multiply operator
> http://dzhigital.blogspot.com/2009/03/cloning-scala-actors.html
>
That looks rather needlessly magic and error prone compared to val
pool = List.range(0, 8).map{i => actor { loop { react { ... } } } }.
--
ʎɐqǝ uo pɹɐoqʎǝʞ ɐ ʎnq ı ǝɯıʇ ʇsɐן ǝɥʇ sı sıɥʇ
It's easy to be checked with:
import scala.actors._
import Actor._
val a = actor { loop { react {
| case msg => println("starting"); Thread.sleep(2000); println("done"); reply(msg);
| }}}
a: scala.actors.Actor = scala.actors.Actor$$anon$1@1eb8f71
a ! 1; a ! 2; a ! 3
You can either make the bocking operation more granular so parts of it can be done by separate actors in parrallel or make copies of the executor actor to make use of all the cores... because obiously, if the target machine isn't capable of doing things in parallel you won't get anything.
To create multiple copies of an executor actor I like to clone them like this
val archetype = actor { loop { react { ... } } }
val pool = 8 * archetype
See my blogpost to see how to implement the magic multiply operator http://dzhigital.blogspot.com/2009/03/cloning-scala-actors.html
You can then create an actor that will just load balance the work between them and forward the messages in a round-robin fashion.
Szymon
On Mon, Apr 27, 2009 at 8:42 PM, Rogelio <rogboone@yahoo.com> wrote:
--
ʎɐqǝ uo pɹɐoqʎǝʞ ɐ ʎnq ı ǝɯıʇ ʇsɐן ǝɥʇ sı sıɥʇ