What's a thread doing / Erlang-style processes / Message passing

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

What's a thread doing / Erlang-style processes / Message passing

Joel Reymont
I'm finding myself in dire need of monitoring the Haskell runtime.  
More precisely, I would like to know what each that I launch is doing  
at a given point in time.

Is there a way to obtain this information now? I would be fine with  
knowing if a thread is blocking on a foreign call, MVar or something  
like that.

The question is prompted by my current project and the issues I'm  
facing now. I believe I minimized the amount of garbage that I'm  
generating by moving to unboxed arrays from lists (thanks dcoutts)  
but I still have memory utilization issues.

I currently have each thread associated with a TChan and I'm going to  
try to abstract that today by creating a special type of a thread  
object that is associated with two mailboxes (in and out). When  
starting this thread you would supply the event loop to read from the  
inbox and another one to write to the mailbox. I would also add stats  
to the TChan mailboxes so that I know the number of messages pending  
in each mailbox and can monitor it.

This mirrors my current architecture where I have each poker bot as  
three threads:

#1 reading messages from a socket and posting to #3,
#2 reading messages sent by #3 and writing to the socket,
#3 reading messages sent by #1, processing them and posting to #2.

I suppose I'm trying to implement Erlang-like processes where each  
process has a mailbox for incoming messages and can send messages to  
any other process. In Erlang you can also check how many messages are  
pending to each process, etc. I don't think implementing message  
passing on top of exceptions is a good idea but please correct me if  
I'm wrong.

In Erlang you are tasked with implementing the message loop yourself  
and retrieve messages by using a "receive" construct where you can  
pattern-match on the type of message inside. It seems that custom  
messages would need to be implemented on top of Dynamic but is there  
a way to pattern-match on that?

I have messages implemented like this now but is there a better  
abstraction?

data Event
     = Enter
     | Exit
     | Quit
     | Timeout String
     | Connected
     | Disconnected
     | Error String
     | Cmd Command
     | Custom Dynamic -- can't pattern-match on this?
     deriving Show

Last but not least, to be able to send messages to any thread I would  
need to keep those around in some sort of a table. I would need to  
create records and keep the thread id, the mailbox and possibly some  
sort of a per-thread string so that threads can update me on their  
doings.

Do you have any suggestions?

        Thanks, Joel

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What's a thread doing / Erlang-style processes / Message passing

Bulat Ziganshin
Hello Joel,

Tuesday, December 06, 2005, 1:27:58 PM, you wrote:

JR> #1 reading messages from a socket and posting to #3,
JR> #2 reading messages sent by #3 and writing to the socket,
JR> #3 reading messages sent by #1, processing them and posting to #2.

what you get by dividing this into 3 threads? i think that this have
meaning ONLY if you then join all socket reading threads together and
use one select to wait on them all

JR> data Event
JR>      = Enter
JR>      | Exit
JR>      | Quit
JR>      | Timeout String
JR>      | Connected
JR>      | Disconnected
JR>      | Error String
JR>      | Cmd Command
JR>      | Custom Dynamic -- can't pattern-match on this?
JR>      deriving Show

using "Dynamic" have meaning only if you don't know at compile time what
messsages can be sent. is that really the case?

JR> Last but not least, to be able to send messages to any thread I would  
JR> need to keep those around in some sort of a table. I would need to  
JR> create records and keep the thread id, the mailbox and possibly some  
JR> sort of a per-thread string so that threads can update me on their  
JR> doings.

imho, you are think in Erlang style, which is ultimately dynamic and
run-time oriented. what you really need - is an abstraction "Poker
server" which have interface consisting of several functions, which
includes ability to create new server, send it a fixed (at compile
time) set of messages, and that's all (may be i don't know about
something more). plus abstraction "Logger", which have facility "log
to me", this facility passed to routine which creates "Poker server"

data Logger = Logger {log :: String -> IO () }

createLogger = do c <- newChan
                  forkIO $ loggerThread (readChan c)
                  return $ Logger (log = writeChan c}

data Server = Server { send :: Event -> IO ()
                     , kill :: IO ()
                     }

createServer logger socket = do
  c <- newChan
  t <- forkIO $ serverThread (log logger) socket (readChan c)
  return $ Server {send = writeChan c, kill = killThread t}

main = do l <- createLogger
          s <- mapM (createServer l) [1..1000]
          ...


--
Best regards,
 Bulat                            mailto:[hidden email]



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: What's a thread doing / Erlang-style processes / Message passing

Joel Reymont
On Dec 6, 2005, at 1:49 PM, Bulat Ziganshin wrote:

> JR> #1 reading messages from a socket and posting to #3,
> JR> #2 reading messages sent by #3 and writing to the socket,
> JR> #3 reading messages sent by #1, processing them and posting to #2.
>
> what you get by dividing this into 3 threads? i think that this have
> meaning ONLY if you then join all socket reading threads together and
> use one select to wait on them all

I get an abstraction of a thread with two STM-based mailboxes.
My workhorse threads don't need to care what is done with the messages
that they generate and where the ones that they are consuming come from.

> JR>      | Custom Dynamic -- can't pattern-match on this?
> JR>      deriving Show
>
> using "Dynamic" have meaning only if you don't know at compile time  
> what
> messsages can be sent. is that really the case?

That is correct. I deliver a "scripting library" and users can create
messages of their own.

> imho, you are think in Erlang style, which is ultimately dynamic and
> run-time oriented.

I think in the style most suitable to my task at hand. I have a variable
number of poker clients that talk to the server. These all run  
concurrently
so I'm starting threads for them. They can send/receive messages, so  
I added
mailboxes to the threads, etc. Is there anything wrong with this  
approach?

        Thanks, Joel

--
http://wagerlabs.com/


_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re[2]: What's a thread doing / Erlang-style processes / Message passing

Bulat Ziganshin
Hello Joel,

Tuesday, December 06, 2005, 5:12:55 PM, you wrote:

>> using "Dynamic" have meaning only if you don't know at compile time
>> what
>> messsages can be sent. is that really the case?

JR> That is correct. I deliver a "scripting library" and users can create
JR> messages of their own.

creators of Data.List library also don't know about all your types,
but nevertheless you are use all theirs functions ;)

if set of messages is defined at compile time, then it's just:

data Event a = Quit
             | ....
             | User a

user of your library defines additional set of messages with

data UserEvent = Beer Int | Cola | ...

and use smthg like

do chan <- newChan
   sendChan chan (User $ Beer 5)
   sendChan chan Quit

it seems like magic but Haskell will guess what `chan` have type
"Chan (Event UserEvent)" here :)

>> imho, you are think in Erlang style, which is ultimately dynamic and
>> run-time oriented.

JR> I think in the style most suitable to my task at hand. I have a variable
JR> number of poker clients that talk to the server. These all run  
JR> concurrently
JR> so I'm starting threads for them. They can send/receive messages, so  
JR> I added
JR> mailboxes to the threads, etc. Is there anything wrong with this  
JR> approach?

hm, may be that you are mixing interfaces and implementation details.
for example, poker client in my taste must be a record which supports all
operations on this client via its fields, which is just an actions
which accepts/returns some values

in general, your questions contain too few details about your
problems and too much details about solutions you are assume


--
Best regards,
 Bulat                            mailto:[hidden email]



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: Re[2]: What's a thread doing / Erlang-style processes / Message passing

Joel Reymont
Assuming I typed events like that I think I would need a typed sink  
for them as well. I only have one sink for the events and that is my  
message queue. I expect users to want User X, User Y, User Z within  
the same module and that's why I used Dynamic.

On Dec 6, 2005, at 4:07 PM, Bulat Ziganshin wrote:

> creators of Data.List library also don't know about all your types,
> but nevertheless you are use all theirs functions ;)
>
> if set of messages is defined at compile time, then it's just:
>
> data Event a = Quit
>              | ....
>              | User a

--
http://wagerlabs.com/





_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re[4]: What's a thread doing / Erlang-style processes / Message passing

Bulat Ziganshin
Hello Joel,

Tuesday, December 06, 2005, 8:30:32 PM, you wrote:

JR> Assuming I typed events like that I think I would need a typed sink  
JR> for them as well. I only have one sink for the events and that is my  
JR> message queue.

i don't understand you. remember that i'm not native English speaker :)

JR> I expect users to want User X, User Y, User Z within  
JR> the same module and that's why I used Dynamic.

if you can define all these datatags (X, Y and Z) in one type then you
can use pattern matching:

data UserEvent = X ... | Y ... | Z ...

if not - then can't. of course, you can use this "subtyping trick"
several times, but it is not very interesting:

data Event a = ... | User a
data UserEvent1 a = X ... | User2 a
data UserEvent2 a = Y ... | User3 a

send chan (User $ User2 $ Y)  -- type of expression inside brackets is
"Event (UserEvent1 (UserEvent2 a))", where a is unspecified


or you can define

data Event a b c = ... | User1 a | User2 b | User3 c

but this is also bad :(


you can also use classes, but Dynamic actually does the same, and this
gives you no ability to do pattern-matching



--
Best regards,
 Bulat                            mailto:[hidden email]



_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/haskell-cafe