I have posted the latest build and updated the online docs.
The primary new feature of this build is the new Actor Framework. I am pretty excited how it turned out.
Note: the .NET implementation is still not quite complete yet.
For this one build, I have maintained the old Thread API side-by-side with the new Actor API. Hopefully this will help ease transition issues if you have code to refactor. I refactored all of our Bespin code which was heavily concurrent, and it went pretty smoothly. Let me know if you have any issues.
Starting tomorrow I will remove the old Thread API from the Mercurial tip. Then immediately begin on it-blocks.
Change Log
Build 1.0.40 (2 Apr 09)
Added sys::Actor API
Added sys::Service API
Renamed UnknownThreadErr to UnknownServiceErr
Refactor fand to work with Services
SqlService API changed from Thread to Service
Image resize
ScrollBar added
ProgressBar.value renamed val
cbeustFri 3 Apr 2009
This is looking great, Brian!
Quick remark: the first example says "with receive function", but don't you mean this comment for the second piece of code?
-- Cedric
brianFri 3 Apr 2009
The old Thread API has been removed from Mercurial tip.
I also re-organized the source tree a bit:
src/jfan => src/sys/java
src/nfan => src/sys/dotnet
This keeps the sys pod consistent with how the other pods with native code are structured (good idea from qualidafial). Note that the java/C# build scripts still work like they used.
brianFri 3 Apr 2009
Quick remark: the first example says "with receive function", but don't you mean this comment for the second piece of code?
Hi Cedric - glad to see you pop in!
My comment was probably a little confusing, I reworded to be a little more clear:
// pass receive to constructor as a closure function
a := Actor(group) |Int msg->Int| { msg + 1 }
// subclass and override receive
const class IncrActor : Actor
{
new make(ActorGroup g) : super(g) {}
override Obj? receive(Obj? msg, Context cx) { msg->increment }
}
cbeustFri 3 Apr 2009
A few additional remarks:
everytime it receives a message:
"every time"
echo("Count is now " + a.send("ignored").get)
Don't you mean "count" instead of "ignored"?
If a timeout used
"is used"?
Often when sending messages to a actor
"an actor"
The coalescing example confuses me somewhat. I'll have to read it again more carefully, but I think my confusion comes mostly from the fact that I'm not sure how much of the behavior that you describe is performed by the Actor framework and how much of it is done by the user but not described in the code snippet.
Is coalescing that common or is it just a need you came across in FWT and decided to incorporate in the Actors framework?
peek of 100 threads
"peak"
actor's currently have work.
"actors"
Once all actor's
"actors"
Finally, just a minor style issue: when you write
|Repaint a, Repaint b->Obj|
Because of the spaces, I visually see two portions: "Repaint a" and "Repaint b->Obj", which tripped me a few times when reading the code. I prefer to write
|Repaint a, Repaint b -> Obj|
No need to respond, it's just personal taste :-)
brianFri 3 Apr 2009
Thanks for catching all the typos Cedric. I've posted fixes to the online docs.
Is coalescing that common or is it just a need you came across in FWT and decided to incorporate in the Actors framework?
I don't actually use it in the FWT, I just picked what I figured was one of the most common examples. But I do use coalescing in probably 50% of all my actors in SkyFoundry's production code - it is one the most important features for building high performance queues. So it is a pretty important feature. Originally we were going to make it pluggable, but since it requires low level knowledge of the queue and futures I put it directly into the framework.
All the user code does is provide a toKey and coalescing function, the framework takes care of the rest.
cbeustFri 3 Apr 2009
I don't actually use it in the FWT, I just picked what I figured was one of the most common examples. But I do use coalescing in probably 50% of all my actors in SkyFoundry's production code - it is one the most important features for building high performance queues. So it is a pretty important feature. Originally we were going to make it pluggable, but since it requires low level knowledge of the queue and futures I put it directly into the framework.
Alright, I'll take your word for it. I have never written Actor-based software myself, so I don't know.
All the user code does is provide a toKey and coalescing function, the framework takes care of the rest.
Ah, that wasn't immediately clear to me from reading the code. You might want to specify that these two methods need to be provided by the developer in order to use Coalescing.
-- Cedric
qualidafialFri 3 Apr 2009
I'm wondering whether the toKey function sent to Actor.makeCoalescing should allow returning null as a magic value, given that null is a valid message for Actor.send.
brianFri 3 Apr 2009
I'm wondering whether the toKey function sent to Actor.makeCoalescing should allow returning null as a magic value, given that null is a valid message for Actor.send.
Null indicates that the message can't be coalesced. So I think it this is OK. The key used for coalescing is orthogonal to the actual messages. So even if null was actually a message you wanted to coalesce you could potentially use some non-null key such as "_null_".
qualidafialFri 3 Apr 2009
From the fandoc:
If coalesce is null, then we use the incoming message (last one wins).
When I read this I thought this meant if the result of calling coalesce(), not whether coalesce == null. It would help if this were clarified in the fandocs.
Null indicates that the message can't be coalesced.
This is not explained in the fandocs.
brianFri 3 Apr 2009
When I read this I thought this meant if the result of calling coalesce(), not whether coalesce == null. It would help if this were clarified in the fandocs.
It is meant to be read as "if the coalesce function itself is null". I will update the fandoc.
This is not explained in the fandocs.
This is the specification in the fandoc regarding the toKey function:
The toKey function is used to derive a key for each message, or if null then the
message itself is used as the key. If the toKey function returns null, then the
message is not considered for coalescing.
qualidafialFri 3 Apr 2009
This is the specification in the fandoc regarding the toKey function:
Actually I was speaking about coalesce, not toKey.
qualidafialFri 3 Apr 2009
I see I said toKey in my original comment when I meant to say coalesce. Sorry for the confusion. Let me start over:
If toKey returns non-null and the coalesce function is non-null, then what happens if coalesce decides that two events that are keyed the same cannot be coalesced? Return null?
brianSat 4 Apr 2009
If toKey returns non-null and the coalesce function is non-null, then what happens if coalesce decides that two events that are keyed the same cannot be coalesced? Return null?
OK, I was confused then - thought you were talking about the toKey function. Your only hook to opt out of coalescing is the toKey function. If two messages have the same key they are going to be coalesced regardless of what coalesce returns. If the coalesce function returns null, then the messages are coalesced into null (since that is a valid message, one I happen to use all the time actually).
But I can't ever really see it being a problem, because you have the toKey function to make a coalescing decision. Remember you can always coalesce into something, even if it just means keeping track of both messages. For example in one of my actors all coalescing does it create a linked list of the messages (the key is a time range).
brianFri 24 Apr 2009
I was thinking today that maybe ActorPool would be a better class name than ActorGroup. Just throwing it out there. If there is strong consensus to rename that class, I think it might be a more accurate name.
JohnDGSat 25 Apr 2009
ActorPool is indeed a better name than ActorGroup, which was itself better than ActorService.
brian Thu 2 Apr 2009
I have posted the latest build and updated the online docs.
The primary new feature of this build is the new Actor Framework. I am pretty excited how it turned out.
Note: the .NET implementation is still not quite complete yet.
For this one build, I have maintained the old
Thread
API side-by-side with the newActor
API. Hopefully this will help ease transition issues if you have code to refactor. I refactored all of our Bespin code which was heavily concurrent, and it went pretty smoothly. Let me know if you have any issues.Starting tomorrow I will remove the old Thread API from the Mercurial tip. Then immediately begin on it-blocks.
Change Log
Build 1.0.40 (2 Apr 09)
cbeust Fri 3 Apr 2009
This is looking great, Brian!
Quick remark: the first example says "with receive function", but don't you mean this comment for the second piece of code?
-- Cedric
brian Fri 3 Apr 2009
The old Thread API has been removed from Mercurial tip.
I also re-organized the source tree a bit:
This keeps the sys pod consistent with how the other pods with native code are structured (good idea from qualidafial). Note that the java/C# build scripts still work like they used.
brian Fri 3 Apr 2009
Hi Cedric - glad to see you pop in!
My comment was probably a little confusing, I reworded to be a little more clear:
cbeust Fri 3 Apr 2009
A few additional remarks:
"every time"
Don't you mean "count" instead of "ignored"?
"is used"?
"an actor"
The coalescing example confuses me somewhat. I'll have to read it again more carefully, but I think my confusion comes mostly from the fact that I'm not sure how much of the behavior that you describe is performed by the Actor framework and how much of it is done by the user but not described in the code snippet.
Is coalescing that common or is it just a need you came across in FWT and decided to incorporate in the Actors framework?
"peak"
"actors"
"actors"
Finally, just a minor style issue: when you write
|Repaint a, Repaint b->Obj|
Because of the spaces, I visually see two portions: "Repaint a" and "Repaint b->Obj", which tripped me a few times when reading the code. I prefer to write
|Repaint a, Repaint b -> Obj|
No need to respond, it's just personal taste :-)
brian Fri 3 Apr 2009
Thanks for catching all the typos Cedric. I've posted fixes to the online docs.
I don't actually use it in the FWT, I just picked what I figured was one of the most common examples. But I do use coalescing in probably 50% of all my actors in SkyFoundry's production code - it is one the most important features for building high performance queues. So it is a pretty important feature. Originally we were going to make it pluggable, but since it requires low level knowledge of the queue and futures I put it directly into the framework.
All the user code does is provide a
toKey
andcoalescing
function, the framework takes care of the rest.cbeust Fri 3 Apr 2009
Alright, I'll take your word for it. I have never written Actor-based software myself, so I don't know.
Ah, that wasn't immediately clear to me from reading the code. You might want to specify that these two methods need to be provided by the developer in order to use Coalescing.
-- Cedric
qualidafial Fri 3 Apr 2009
I'm wondering whether the toKey function sent to Actor.makeCoalescing should allow returning null as a magic value, given that null is a valid message for Actor.send.
brian Fri 3 Apr 2009
Null indicates that the message can't be coalesced. So I think it this is OK. The key used for coalescing is orthogonal to the actual messages. So even if
null
was actually a message you wanted to coalesce you could potentially use some non-null key such as "_null_".qualidafial Fri 3 Apr 2009
From the fandoc:
When I read this I thought this meant if the result of calling
coalesce()
, not whethercoalesce == null
. It would help if this were clarified in the fandocs.This is not explained in the fandocs.
brian Fri 3 Apr 2009
It is meant to be read as "if the coalesce function itself is null". I will update the fandoc.
This is the specification in the fandoc regarding the toKey function:
qualidafial Fri 3 Apr 2009
Actually I was speaking about
coalesce
, nottoKey
.qualidafial Fri 3 Apr 2009
I see I said
toKey
in my original comment when I meant to saycoalesce
. Sorry for the confusion. Let me start over:If
toKey
returns non-null and the coalesce function is non-null, then what happens ifcoalesce
decides that two events that are keyed the same cannot be coalesced? Return null?brian Sat 4 Apr 2009
OK, I was confused then - thought you were talking about the toKey function. Your only hook to opt out of coalescing is the toKey function. If two messages have the same key they are going to be coalesced regardless of what coalesce returns. If the coalesce function returns null, then the messages are coalesced into null (since that is a valid message, one I happen to use all the time actually).
But I can't ever really see it being a problem, because you have the toKey function to make a coalescing decision. Remember you can always coalesce into something, even if it just means keeping track of both messages. For example in one of my actors all coalescing does it create a linked list of the messages (the key is a time range).
brian Fri 24 Apr 2009
I was thinking today that maybe
ActorPool
would be a better class name thanActorGroup
. Just throwing it out there. If there is strong consensus to rename that class, I think it might be a more accurate name.JohnDG Sat 25 Apr 2009
ActorPool
is indeed a better name thanActorGroup
, which was itself better thanActorService
.brian Thu 30 Apr 2009
I renamed ActorGroup to ActorPool