From rch at umail.ucsb.edu Thu Nov 8 23:09:53 2007 From: rch at umail.ucsb.edu (Rama Hoetzlein) Date: Thu Nov 8 23:09:52 2007 Subject: [Tdg] Re: Sequential actions Message-ID: <473407C1.1070503@umail.ucsb.edu> Wes, So, regarding a command that must do a number of actions over a network sequentially, I've discovered that its just not possible to write it using normal program flow.. Basically, i can formalize the problem. Consider the following: CmdCreateWindow () { EnumerateDisplays (over network) MatchDisplay AttachDisplay (over network) CreateOSWindow (over network) } This is what the handler for a CreateWindow event should do. However, each function above must be allowed to run over the network, so they must wait until network events are processed.. But the wait should also not block the core scheduler so that events can continue in other systems (including networking) One solution is to have some kind of Wait() function that returns control to the core scheduler, waiting for a result event. CmdCreateWindow () { EnumerateDisplays Wait ( EnumerateOk ) MatchDisplay Wait ( MatchOk) AttachDisplay Wait ( AttachOk ) CreateOSWindow Wait ( CreateOSWindowOk ) } The problem is, Wait() must return to the core scheduler.. But, if it returns control to the core, then it cannot continue where it left off... Thus, Wait could not possible work unless it did some funky, undesirable stuff with the stack. This means that "normal looking" programs must all be replaced with Event code blocks, with an internal state to trigger the next action. CmdDrawWindow () { case state1: EnumerateDisplays Trigger ( EnumerateOk, state2) case state2: MatchDisplay Trigger ( MatchOK, state3 ) case state3: AttachDisplay Trigger ( AttachOK, state4 ) case state4: CreateOSWindow } So the Trigger function registers with the core for an event to go to the next state in a previously started Cmd.. For example, after the state1, the trigger causes the core to detects if EnumerateOk comes in, and if it does, it consumes it and automatically generates a CmdDrawWindow event in state 2. But the bottom line is, no matter what, I don't see how you're going to keep to "normal looking procedural code" (such as at very top of this email) when doing certain things that require non-blocking initialization.. Even with Triggers to help you out, functions like this have to be done as switches on state. Which means events have to include a state number (or call it a sequence number). I don't see any other way. Rama From wesley.hoke at gmail.com Thu Nov 8 23:22:19 2007 From: wesley.hoke at gmail.com (Wesley Smith) Date: Thu Nov 8 23:22:27 2007 Subject: [Tdg] Re: Sequential actions In-Reply-To: <473407C1.1070503@umail.ucsb.edu> References: <473407C1.1070503@umail.ucsb.edu> Message-ID: <1079b050711082322u54ea5daehdf4f9b0f9b6609f1@mail.gmail.com> After talking about this today and going through the code I think you're right. I think this is also a very special case. What I was worried about at first was that alot library code would have to be reconfigured this way which would would really suck and defeat alot of the gains of our design. The two systems I currently see as needed this kind of behavior are graphics for networked displays and networking for computer discovery. These two things both require remote procedure calls with return values. Most everything else I can think of just needs to be able to send events and forget about them so there's no need for such a state machine or break in typical procedural programming style. That said, the RPC implementation for network discovery and networked graphics can leverage the mint event system as you're already doing to make it less of a headache to get going. I'm not sure that it has to be done with switches as there are myriad ways to implement a state mahcine. I think for this stuff we should do a bit more research on RPC techniques and figure out what could work well with our event system. wes On 11/8/07, Rama Hoetzlein wrote: > Wes, > > So, regarding a command that must do a number of actions over a network > sequentially, I've discovered that its just not possible to write it > using normal program flow.. Basically, i can formalize the problem. > Consider the following: > > CmdCreateWindow () > { > EnumerateDisplays (over network) > MatchDisplay > AttachDisplay (over network) > CreateOSWindow (over network) > } > > This is what the handler for a CreateWindow event should do. However, > each function above must be allowed to run over the network, so they > must wait until network events are processed.. But the wait should also > not block the core scheduler so that events can continue in other > systems (including networking) > > One solution is to have some kind of Wait() function that returns > control to the core scheduler, waiting for a result event. > > CmdCreateWindow () > { > EnumerateDisplays > Wait ( EnumerateOk ) > MatchDisplay > Wait ( MatchOk) > AttachDisplay > Wait ( AttachOk ) > CreateOSWindow > Wait ( CreateOSWindowOk ) > } > > The problem is, Wait() must return to the core scheduler.. But, if it > returns control to the core, then it cannot continue where it left > off... Thus, Wait could not possible work unless it did some funky, > undesirable stuff with the stack. > > This means that "normal looking" programs must all be replaced with > Event code blocks, with an internal state to trigger the next action. > > CmdDrawWindow () > { > case state1: > EnumerateDisplays > Trigger ( EnumerateOk, state2) > case state2: > MatchDisplay > Trigger ( MatchOK, state3 ) > case state3: > AttachDisplay > Trigger ( AttachOK, state4 ) > case state4: > CreateOSWindow > } > > So the Trigger function registers with the core for an event to go to > the next state in a previously started Cmd.. For example, after the > state1, the trigger causes the core to detects if EnumerateOk comes in, > and if it does, it consumes it and automatically generates a > CmdDrawWindow event in state 2. > > But the bottom line is, no matter what, I don't see how you're going to > keep to "normal looking procedural code" (such as at very top of this > email) when doing certain things that require non-blocking initialization.. > > Even with Triggers to help you out, functions like this have to be done > as switches on state. Which means events have to include a state number > (or call it a sequence number). I don't see any other way. > > Rama > > _______________________________________________ > Tdg mailing list > Tdg@mat.ucsb.edu > http://zydeco.mat.ucsb.edu/mailman/listinfo/tdg > From rch at umail.ucsb.edu Thu Nov 8 23:09:53 2007 From: rch at umail.ucsb.edu (Rama Hoetzlein) Date: Thu, 08 Nov 2007 23:09:53 -0800 Subject: [Tdg] Re: Sequential actions Message-ID: <473407C1.1070503@umail.ucsb.edu> Wes, So, regarding a command that must do a number of actions over a network sequentially, I've discovered that its just not possible to write it using normal program flow.. Basically, i can formalize the problem. Consider the following: CmdCreateWindow () { EnumerateDisplays (over network) MatchDisplay AttachDisplay (over network) CreateOSWindow (over network) } This is what the handler for a CreateWindow event should do. However, each function above must be allowed to run over the network, so they must wait until network events are processed.. But the wait should also not block the core scheduler so that events can continue in other systems (including networking) One solution is to have some kind of Wait() function that returns control to the core scheduler, waiting for a result event. CmdCreateWindow () { EnumerateDisplays Wait ( EnumerateOk ) MatchDisplay Wait ( MatchOk) AttachDisplay Wait ( AttachOk ) CreateOSWindow Wait ( CreateOSWindowOk ) } The problem is, Wait() must return to the core scheduler.. But, if it returns control to the core, then it cannot continue where it left off... Thus, Wait could not possible work unless it did some funky, undesirable stuff with the stack. This means that "normal looking" programs must all be replaced with Event code blocks, with an internal state to trigger the next action. CmdDrawWindow () { case state1: EnumerateDisplays Trigger ( EnumerateOk, state2) case state2: MatchDisplay Trigger ( MatchOK, state3 ) case state3: AttachDisplay Trigger ( AttachOK, state4 ) case state4: CreateOSWindow } So the Trigger function registers with the core for an event to go to the next state in a previously started Cmd.. For example, after the state1, the trigger causes the core to detects if EnumerateOk comes in, and if it does, it consumes it and automatically generates a CmdDrawWindow event in state 2. But the bottom line is, no matter what, I don't see how you're going to keep to "normal looking procedural code" (such as at very top of this email) when doing certain things that require non-blocking initialization.. Even with Triggers to help you out, functions like this have to be done as switches on state. Which means events have to include a state number (or call it a sequence number). I don't see any other way. Rama From wesley.hoke at gmail.com Thu Nov 8 23:22:19 2007 From: wesley.hoke at gmail.com (Wesley Smith) Date: Thu, 8 Nov 2007 23:22:19 -0800 Subject: [Tdg] Re: Sequential actions In-Reply-To: <473407C1.1070503@umail.ucsb.edu> References: <473407C1.1070503@umail.ucsb.edu> Message-ID: <1079b050711082322u54ea5daehdf4f9b0f9b6609f1@mail.gmail.com> After talking about this today and going through the code I think you're right. I think this is also a very special case. What I was worried about at first was that alot library code would have to be reconfigured this way which would would really suck and defeat alot of the gains of our design. The two systems I currently see as needed this kind of behavior are graphics for networked displays and networking for computer discovery. These two things both require remote procedure calls with return values. Most everything else I can think of just needs to be able to send events and forget about them so there's no need for such a state machine or break in typical procedural programming style. That said, the RPC implementation for network discovery and networked graphics can leverage the mint event system as you're already doing to make it less of a headache to get going. I'm not sure that it has to be done with switches as there are myriad ways to implement a state mahcine. I think for this stuff we should do a bit more research on RPC techniques and figure out what could work well with our event system. wes On 11/8/07, Rama Hoetzlein wrote: > Wes, > > So, regarding a command that must do a number of actions over a network > sequentially, I've discovered that its just not possible to write it > using normal program flow.. Basically, i can formalize the problem. > Consider the following: > > CmdCreateWindow () > { > EnumerateDisplays (over network) > MatchDisplay > AttachDisplay (over network) > CreateOSWindow (over network) > } > > This is what the handler for a CreateWindow event should do. However, > each function above must be allowed to run over the network, so they > must wait until network events are processed.. But the wait should also > not block the core scheduler so that events can continue in other > systems (including networking) > > One solution is to have some kind of Wait() function that returns > control to the core scheduler, waiting for a result event. > > CmdCreateWindow () > { > EnumerateDisplays > Wait ( EnumerateOk ) > MatchDisplay > Wait ( MatchOk) > AttachDisplay > Wait ( AttachOk ) > CreateOSWindow > Wait ( CreateOSWindowOk ) > } > > The problem is, Wait() must return to the core scheduler.. But, if it > returns control to the core, then it cannot continue where it left > off... Thus, Wait could not possible work unless it did some funky, > undesirable stuff with the stack. > > This means that "normal looking" programs must all be replaced with > Event code blocks, with an internal state to trigger the next action. > > CmdDrawWindow () > { > case state1: > EnumerateDisplays > Trigger ( EnumerateOk, state2) > case state2: > MatchDisplay > Trigger ( MatchOK, state3 ) > case state3: > AttachDisplay > Trigger ( AttachOK, state4 ) > case state4: > CreateOSWindow > } > > So the Trigger function registers with the core for an event to go to > the next state in a previously started Cmd.. For example, after the > state1, the trigger causes the core to detects if EnumerateOk comes in, > and if it does, it consumes it and automatically generates a > CmdDrawWindow event in state 2. > > But the bottom line is, no matter what, I don't see how you're going to > keep to "normal looking procedural code" (such as at very top of this > email) when doing certain things that require non-blocking initialization.. > > Even with Triggers to help you out, functions like this have to be done > as switches on state. Which means events have to include a state number > (or call it a sequence number). I don't see any other way. > > Rama > > _______________________________________________ > Tdg mailing list > Tdg at mat.ucsb.edu > http://zydeco.mat.ucsb.edu/mailman/listinfo/tdg >