How is it intended to write something like a cache in Fan? Or a database pool? Something where an object is shared between multiple threads.
// java
ConcurrentMap cache = enw ConcurrentHashMap();
Heavyweight bar = cache.get("foo");
if (bar == null) {
bar = createHeavyweight("foo");
cache.putIfAbsent("foo", bar);
bar = cache.get("foo");
}
Basically, the kind of thing we normally use synchronization for, but without needing threads. Have I missed something obvious?
cgrindsWed 26 Nov 2008
It's my understanding you would do this via Namespaces.
Note the warnings.
I'm frustrated I haven't had more time to work on the message passing problems in Fan lately. I'm also frustrated no one else has worked on them either - they're a fundamential part of Fan that is suboptimal (maybe broken?) at the moment.
brianWed 26 Nov 2008
It depends on if the objects you caching are immutable or not. And it depends on if you are caching per thread or per VM.
If you are going things per thread, then you'd probably use a thread local. This is how we do database connections in the sql API.
If you have immutable objects (or serializable mutable) objects then you'd access them through a service thread or via a namespace.
Designing for concurrency in Fan is quite different than the mindset used in Java. I tend to heavily use immutability between threads and hide mutable stuff behind a thread or namespace interface.
brianWed 26 Nov 2008
I'm frustrated I haven't had more time to work on the message passing problems in Fan lately. I'm also frustrated no one else has worked on them either - they're a fundamential part of Fan that is suboptimal (maybe broken?) at the moment.
I agree they are suboptimal and incomplete. But this aspect of Fan will be coming back to the forefront right after I wrap up the Java FFI feature.
jodastephenWed 26 Nov 2008
Hmmm. But I don't actually need a thread here. The use case was to share objects in a cache across the whole VM. Lets consider them to be immutable for now. It seems odd to have to have one thread for every cache in the system - that doesn't sound scalable.
brianThu 27 Nov 2008
It seems odd to have to have one thread for every cache in the system - that doesn't sound scalable.
It is not odd at all in actor/message passing systems like Erlang which might have 100,000s of "processes". Today Fan threads map 1-to-1 to Java threads (which in turn map to OS threads) - but that isn't the typical or desirable long term design.
But in the simple case you would probably just use namespaces - the default namespace is basically a just concurrent hashmap.
jodastephenThu 27 Nov 2008
Ahhh, OK. The thread != Thread concept is one I'd missed. That makes more sense now.
heliumThu 27 Nov 2008
That's the first time I hear that Fan will have green threads.
alexlamslFri 28 Nov 2008
That's the first time I hear that Fan will have green threads.
Or - "green processes"?
brianSun 30 Nov 2008
That's the first time I hear that Fan will have green threads.
I don't think they would be true green threads. Rather it would be an optimization for messaging. My initial thoughts are that once a thread entered its message receive loop, we'd start servicing it with a dedicated thread pool so that each sys::Thread wasn't actually consuming an OS thread.
I'd also like to come up some similar design for handling async IO.
I've haven't yet investigated what other Java based actor libraries do for thread scalability - but if you know please share.
alexlamslMon 1 Dec 2008
Sounds like creating a Task for the receiver's code in the loop and have the message sender submitting it to a Executor would do the job...
cgrindsTue 2 Dec 2008
I've haven't yet investigated what other Java based actor libraries do for thread scalability - but if you know please share.
Bill Clementson did a nice contrast of Erlang vs. Clojure concurrency. He does a nice job of summarizing some of the different design decisions made in the two languages around concurrency. It's also filled with relevant links.
brianWed 3 Dec 2008
Bill Clementson did a nice contrast of Erlang vs. Clojure concurrency.
Yeah I saw that. I've read thru the basics of Clojure and definitely like the immutable lists/maps. My limited understanding so far is that it is based on mutable references versus something "chunky" like message passing. But I need to take some time to do a deeper dive.
heliumWed 3 Dec 2008
Well, yes, Clojure has Ref-cells with thread semantics on which the STM is based. But additionally there are those agents, which at first seem to be similar to actors, but realy aren't.
An actor is an active things (process/thread). It has a message queue, waits for messages to be send to it and possibly responds to them.
An agent is a lot more passive. You just say "apply this function to the value of the agent and store the result back in that agent". So you just enqueue a function call in a global thread-pool that later on mutates the agent. You can read the value of the agent at any time, but you can't be sure how many of the functions that were enqueued to be applied to it are already applied.
Just because actors are popular in Erlang doesn't mean they are the best solution overall. Erlang is about distributed programming. The code might run on several different computers without shared memory. That's the cool thing about actors. Clojur's agents can't do this. They are meant to be used for concurrent things on one shared memory.
Scala for example thought actors are pretty cool, so they built an actor library. But there are other librarys for Scala, too, e.g. a library based on the join calculus. (Scala is realy great at embedding DSLs. Other languages had to be modiefied to allow stuff like this. Microsoft Research had Polyphonic C#, and there was Join Java. As it's only a library it's eeasy to toy around, e.g. there is an experiment of combining actors with the join calculus.)
And there are other languages with yet other strategies. For example there is one I recently read about (can't remember the name) that has some similarities to actors. But each of these ... things (don't know how to call them) not only have an in-box but possibly many in-boxes and any number of out-boxes. You don't send messages to other actors but to one of your out-boxes. Later on you connect in- and out-boxes from the outside like you connect programs through pipes on a shell. I think they explicitly compared it to that, stdin and the signals are like in-boxes, stdout and stderr are like out-boxes.
jodastephen Wed 26 Nov 2008
How is it intended to write something like a cache in Fan? Or a database pool? Something where an object is shared between multiple threads.
Basically, the kind of thing we normally use synchronization for, but without needing threads. Have I missed something obvious?
cgrinds Wed 26 Nov 2008
It's my understanding you would do this via Namespaces.
Note the warnings.
I'm frustrated I haven't had more time to work on the message passing problems in Fan lately. I'm also frustrated no one else has worked on them either - they're a fundamential part of Fan that is suboptimal (maybe broken?) at the moment.
brian Wed 26 Nov 2008
It depends on if the objects you caching are immutable or not. And it depends on if you are caching per thread or per VM.
If you are going things per thread, then you'd probably use a thread local. This is how we do database connections in the sql API.
If you have immutable objects (or serializable mutable) objects then you'd access them through a service thread or via a namespace.
Designing for concurrency in Fan is quite different than the mindset used in Java. I tend to heavily use immutability between threads and hide mutable stuff behind a thread or namespace interface.
brian Wed 26 Nov 2008
I agree they are suboptimal and incomplete. But this aspect of Fan will be coming back to the forefront right after I wrap up the Java FFI feature.
jodastephen Wed 26 Nov 2008
Hmmm. But I don't actually need a thread here. The use case was to share objects in a cache across the whole VM. Lets consider them to be immutable for now. It seems odd to have to have one thread for every cache in the system - that doesn't sound scalable.
brian Thu 27 Nov 2008
It is not odd at all in actor/message passing systems like Erlang which might have 100,000s of "processes". Today Fan threads map 1-to-1 to Java threads (which in turn map to OS threads) - but that isn't the typical or desirable long term design.
But in the simple case you would probably just use namespaces - the default namespace is basically a just concurrent hashmap.
jodastephen Thu 27 Nov 2008
Ahhh, OK. The thread != Thread concept is one I'd missed. That makes more sense now.
helium Thu 27 Nov 2008
That's the first time I hear that Fan will have green threads.
alexlamsl Fri 28 Nov 2008
Or - "green processes"?
brian Sun 30 Nov 2008
I don't think they would be true green threads. Rather it would be an optimization for messaging. My initial thoughts are that once a thread entered its message receive loop, we'd start servicing it with a dedicated thread pool so that each sys::Thread wasn't actually consuming an OS thread.
I'd also like to come up some similar design for handling async IO.
I've haven't yet investigated what other Java based actor libraries do for thread scalability - but if you know please share.
alexlamsl Mon 1 Dec 2008
Sounds like creating a
Task
for the receiver's code in the loop and have the message sender submitting it to aExecutor
would do the job...cgrinds Tue 2 Dec 2008
Bill Clementson did a nice contrast of Erlang vs. Clojure concurrency. He does a nice job of summarizing some of the different design decisions made in the two languages around concurrency. It's also filled with relevant links.
brian Wed 3 Dec 2008
Yeah I saw that. I've read thru the basics of Clojure and definitely like the immutable lists/maps. My limited understanding so far is that it is based on mutable references versus something "chunky" like message passing. But I need to take some time to do a deeper dive.
helium Wed 3 Dec 2008
Well, yes, Clojure has Ref-cells with thread semantics on which the STM is based. But additionally there are those
agents
, which at first seem to be similar toactors
, but realy aren't.An actor is an active things (process/thread). It has a message queue, waits for messages to be send to it and possibly responds to them.
An agent is a lot more passive. You just say "apply this function to the value of the agent and store the result back in that agent". So you just enqueue a function call in a global thread-pool that later on mutates the agent. You can read the value of the agent at any time, but you can't be sure how many of the functions that were enqueued to be applied to it are already applied.
Just because actors are popular in Erlang doesn't mean they are the best solution overall. Erlang is about distributed programming. The code might run on several different computers without shared memory. That's the cool thing about actors. Clojur's agents can't do this. They are meant to be used for concurrent things on one shared memory.
Scala for example thought actors are pretty cool, so they built an actor library. But there are other librarys for Scala, too, e.g. a library based on the join calculus. (Scala is realy great at embedding DSLs. Other languages had to be modiefied to allow stuff like this. Microsoft Research had Polyphonic C#, and there was Join Java. As it's only a library it's eeasy to toy around, e.g. there is an experiment of combining actors with the join calculus.)
And there are other languages with yet other strategies. For example there is one I recently read about (can't remember the name) that has some similarities to actors. But each of these ... things (don't know how to call them) not only have an in-box but possibly many in-boxes and any number of out-boxes. You don't send messages to other actors but to one of your out-boxes. Later on you connect in- and out-boxes from the outside like you connect programs through pipes on a shell. I think they explicitly compared it to that, stdin and the signals are like in-boxes, stdout and stderr are like out-boxes.