CCR has been using almost idenctical syntax to do what Jeff is showing here for about 4 years (publicly). Jeff was even in some of our videos 3 years ago.
IEnumerator<ITask> CcrReadFileAsync(string file) { var result = new Port<IAsyncResult>(); using (var fs = new FileStream(file,…,FileOptions.Asynchronous)) {
var buf = new byte[fs.Length]; fs.BeginRead(buf, 0, buf.Length, result.Post, null); yield return result.Receive(); var ar = (IAsyncResult)resultPort.Test(); try { fs.EndRead(ar); ProcessData(buf); } catch { // handle exception } } }
Seems like a canned version of popfly and workflow. How does this justify that it doesnt seem to bring ALL that much new stuff to the table?
Hi, VPL 1.0 was actually released as product, last year, going beta over 14 months ago. Popfly is great and follows similar graphical model for composition although that is where the similarities end. They also target different developer segments (at least
right now).
VPL produces high performance service code and is tuned towards a very specific data-flow (or data dependency scheduler) engine underneath, the CCR/DSS runtime. The underlying runtime model is a different approach to an open ended workflow engine. We are a
bit more "strict" and enforce an application model (Henrik talks about our REST-based model more in a companion screen cast).
At some point things will start re-using each other, but until we all figure out what is common between all these approaches, what can run efficiently in a variety of environments, and what it means to have a common application model, its ok to have a bit of
variety
I'm wondering if you could comment on the recommended use of ThreadCausalities in CCR (in my case non-DSS environment). I can see that Causalities will be transferred from the current thread to the post operation, and that they are conversely transferred from
the ITask back to the executing thread, making the context available to delegates as called from Receivers, etc.
The obvious use is to provide an ExceptionPort that can take care of any unhandled exceptions that might have been thrown during events, etc. I have not really seen too many examples, nor is is clear what the appropriate patterns of use really are..
Possible example: I'm inside an iterator doing a number of yield return operations, etc, to Choices, etc. and may want that iterator to have a way to handle any unhandled exceptions during those operations, so I add a CausalityContext within that iterator.
Then perhaps one of the services that I do a yield return call to (it returning a Choice) decides that it needs a 'nested' causality, so it creates one for it's exception handling (of unhandled exceptions in the dispatcher chain).. Once that service posts back
thru the Choice, it appears that the original Iterator has it's restored CausalityContext in place again.
Any insight on the appropriate usage patterns would really be appreciated. Also the intent of the CoordinationPort?
The CCR appears to be an extremely useful library for a vast number off cases and I really appreciate your time in filling in the gaps!
tnx again! Don
Hi Don, we actually use causalities, for exactly the same reasons you guessed Its a generalization, across threads and processors, of the nested exception handling mechanism. Much more powerfull however since it can deal with joins (two different causalities
coming together in a common handler). And no, they are not transactions
Causalities are used for every single operation in the DSS runtime, our services infrastructure. They make sure that when an exception is thrown, within any logically related descendant of a Post operation, that exception can be cleanly caught and dealt with
in one place.
The CoordinationPort allows anyone within a causality to post a message to the "owner" of the causlity, allowing you to implement all kinds of protocols (like N phase commit, etc)
Please post any further questions in the robotics newsgroup since thats the one we acively monitor. Soon we will have a forum in MSDN where we can talk about CCR stuff exclusively (it will be under the Robotics family of forums).
For examples, i have posted something in the past in our robotics newsgroup on this (search for Causalities, Causality)
btw we always want to know how the CCR is used and applied, especially in large scale commercial applications.
Note on the licensing: CCR, which is part of the MSRS runtime is covered by the same license as the robotics runtime. For non-commercial use (please read the license for more details) its use is free. For commercial use however there is a fee (good news is
that with one MSRS license you get permission for multiple runtime instances)
For any questions please refer to the license and also feel free to post to the newsgroups.
Thanks for the reply. Your suggestion worked great. I have another related question.
Could you explain what the runtime does with the return type of IEnumerator<ITask> a little? The runtime seemed to execute the first task, but not the others.
Thanks.
.....
The C# compliler re-writes all functions that return IENumerator to look like a heap allocated class that implements a state machine. Every time you yield, the state machine is updated, and the CCR uses that to do MoveNext when the constraint (for a example
a receive occuring) is satisfied. Basically the CCR figured out how to use iterator for async scheduling. Now, for all this to happen, you must implement the proper Task which can support linked iterators. This is what choice, Receive, Join etc have to do. Its not enough to just derive from task, since you cant yield to a simple task: Its not clear when a task
is "done". To do this, you will need to support the LinkedIterator property plus some other fields.
Its a bit of an advanced subject that i think should be covered by a new article or even book on the ccr
how to make a bot compatable with robotics studio like boe-bot.....please help
Hi we already talk to the boe bot and we have sample code for it. Please download our CTP and review the samples\platforms\parallax. Instructions are on the parallax site in terms of hardware configuration and they are being updated to match our latest CTP
I am trying to create an alternate receiver that would send a message to all predicates and applicable handlers, versus stopping on a single Predicate match.
There is a problem with my implementation not getting a second pass through the EvaluatorAggregateTask's Execute method after the first yield return. I also tried to return an alternate IEnumerator<> from a List<> and received the same behavior.
I was able to get all the EvaluatorTask<> enqueued by calling the DispatchQueue.Enqueue, not sure if this is correct. Do you know if the framework should be executing all of the tasks returned back in the enumerator? Also please mention anything I look at
doing differently.
Thanks.
Code snippets as follows:
public class TestReceiver<T> : Receiver { public TestReceiver(bool persist, IPortReceive port, params Tuple<Predicate<T>, Handler<T>>[] tuples) : base(true, port, new EvaluatorAggregateTask<T>(tuples)) { // no code } }
internal class EvaluatorAggregateTask<V> : ITask { public IEnumerator<ITask> Execute() { foreach (Tuple<Predicate<V>, Handler<V>> tuple in this.tuples) { Predicate<V> predicate = (Predicate<V>)tuple.Item0; Handler<V> handler = (Handler<V>)tuple.Item1; yield return new EvaluatorTask<V>((PortElement<V>)this[0], handler, predicate); } }
[Rest of ITask implementation here ... ] }
internal class EvaluatorTask<V> : ITask { public IEnumerator<ITask> Execute() { if (this.predicate(this.param.TypedItem) == true) { this.handler(this.param.TypedItem); } return null; }
[Rest of ITask implementation here ... ] }
Hi Tasks never get their execute method called more than once. Persistent receivers even, will clone the task that runs the handler, and call it once for each message.
To achieve what you want, there is a different approach. Create the alternate receiver, just like you did. In the receiver's Evaluate method (override it) take the IPortElement.Value contents, and essentially broad cast to any other port or handlers you want.
Make sure you return true from the Evaluate, so the port does not keep the message in its queue
Expert to Expert: Meijer and Chrysanthakopoulos - Concurrency, Coordination and the CCR
Jan 17, 2009 at 4:58 PMVolume licensing will be available as well in the next month or so.
Jeffrey Richter and his AsyncEnumerator
Dec 11, 2008 at 4:29 PMVarious channel9 videos and PDC talk have examples...
http://channel9.msdn.com/pdc2008/TL55/
http://channel9.msdn.com/tags/CCR/
CCR example for file read (from PDC session):
IEnumerator<ITask> CcrReadFileAsync(string file)
{
var result = new Port<IAsyncResult>();
using (var fs = new FileStream(file,…,FileOptions.Asynchronous))
{
var buf = new byte[fs.Length];
fs.BeginRead(buf, 0, buf.Length, result.Post, null);
yield return result.Receive();
var ar = (IAsyncResult)resultPort.Test();
try {
fs.EndRead(ar);
ProcessData(buf);
} catch { // handle exception }
}
}
Andreas Ulbrich demonstrates the Microsoft Visual Programming Language
Aug 07, 2007 at 1:17 PMHi, VPL 1.0 was actually released as product, last year, going beta over 14 months ago. Popfly is great and follows similar graphical model for composition although that is where the similarities end. They also target different developer segments (at least right now).
VPL produces high performance service code and is tuned towards a very specific data-flow (or data dependency scheduler) engine underneath, the CCR/DSS runtime. The underlying runtime model is a different approach to an open ended workflow engine. We are a bit more "strict" and enforce an application model (Henrik talks about our REST-based model more in a companion screen cast).
At some point things will start re-using each other, but until we all figure out what is common between all these approaches, what can run efficiently in a variety of environments, and what it means to have a common application model, its ok to have a bit of variety
g
CCR Programming - Jeffrey Richter and George Chrysanthakopoulos
Mar 15, 2007 at 6:41 PMHi Don, we actually use causalities, for exactly the same reasons you guessed
Causalities are used for every single operation in the DSS runtime, our services infrastructure. They make sure that when an exception is thrown, within any logically related descendant of a Post operation, that exception can be cleanly caught and dealt with in one place.
The CoordinationPort allows anyone within a causality to post a message to the "owner" of the causlity, allowing you to implement all kinds of protocols (like N phase commit, etc)
Please post any further questions in the robotics newsgroup since thats the one we acively monitor. Soon we will have a forum in MSDN where we can talk about CCR stuff exclusively (it will be under the Robotics family of forums).
For examples, i have posted something in the past in our robotics newsgroup on this (search for Causalities, Causality)
btw we always want to know how the CCR is used and applied, especially in large scale commercial applications.
CCR Programming - Jeffrey Richter and George Chrysanthakopoulos
Dec 13, 2006 at 7:00 AMPlease visit www.microsoft.com/robotics for the latest bits.
Note on the licensing: CCR, which is part of the MSRS runtime is covered by the same license as the robotics runtime. For non-commercial use (please read the license for more details) its use is free. For commercial use however there is a fee (good news is that with one MSRS license you get permission for multiple runtime instances)
For any questions please refer to the license and also feel free to post to the newsgroups.
thanks to all for all the great feedback
Microsoft Robotics Studio
Dec 13, 2006 at 6:56 AMThank you to all for the great feedback here and the newsgroups
g
CCR Programming - Jeffrey Richter and George Chrysanthakopoulos
Dec 04, 2006 at 8:05 AMThe C# compliler re-writes all functions that return IENumerator to look like a heap allocated class that implements a state machine. Every time you yield, the state machine is updated, and the CCR uses that to do MoveNext when the constraint (for a example a receive occuring) is satisfied. Basically the CCR figured out how to use iterator for async scheduling.
Now, for all this to happen, you must implement the proper Task which can support linked iterators. This is what choice, Receive, Join etc have to do. Its not enough to just derive from task, since you cant yield to a simple task: Its not clear when a task is "done". To do this, you will need to support the LinkedIterator property plus some other fields.
Its a bit of an advanced subject that i think should be covered by a new article or even book on the ccr
Microsoft Robotics Studio
Dec 04, 2006 at 7:11 AMHi we already talk to the boe bot and we have sample code for it. Please download our CTP and review the samples\platforms\parallax. Instructions are on the parallax site in terms of hardware configuration and they are being updated to match our latest CTP
CCR Programming - Jeffrey Richter and George Chrysanthakopoulos
Nov 30, 2006 at 2:44 PMHi i am not aware of any such library. A CCR C++ version would be nice but its not in our plans at this point.
CCR Programming - Jeffrey Richter and George Chrysanthakopoulos
Nov 30, 2006 at 2:43 PMHi Tasks never get their execute method called more than once. Persistent receivers even, will clone the task that runs the handler, and call it once for each message.
To achieve what you want, there is a different approach. Create the alternate receiver, just like you did. In the receiver's Evaluate method (override it) take the IPortElement.Value contents, and essentially broad cast to any other port or handlers you want. Make sure you return true from the Evaluate, so the port does not keep the message in its queue
See more comments…