<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: What&#8217;s so hard about Event-Driven Programming?</title>
	<atom:link href="http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming/feed" rel="self" type="application/rss+xml" />
	<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming</link>
	<description>It's all behaviour</description>
	<pubDate>Sat, 11 Oct 2008 19:14:21 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
		<item>
		<title>By: Tom Appleton</title>
		<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming#comment-52</link>
		<dc:creator>Tom Appleton</dc:creator>
		<pubDate>Sat, 17 Jun 2006 23:30:18 +0000</pubDate>
		<guid isPermaLink="false">http://dannorth.net/archives/14#comment-52</guid>
		<description>Hmmm, interesting. I'm currently working on an event driven project and the pixes that take care of the queueing are certainly present. This is because we are using a specific language (yep neither java nor ruby :-) ) that manages the queueing for you. What is puzzling at the moment is how to test this system as it is asynchronous, concurrent and has lots and lots of input streams. The question of emergent behaviour within the business logic that is not covered in any tests is difficult to address at the moment. Maybe that is a separate topic - testing event driven systems.</description>
		<content:encoded><![CDATA[<p>Hmmm, interesting. I&#8217;m currently working on an event driven project and the pixes that take care of the queueing are certainly present. This is because we are using a specific language (yep neither java nor ruby :-) ) that manages the queueing for you. What is puzzling at the moment is how to test this system as it is asynchronous, concurrent and has lots and lots of input streams. The question of emergent behaviour within the business logic that is not covered in any tests is difficult to address at the moment. Maybe that is a separate topic &#8211; testing event driven systems.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Stacy</title>
		<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming#comment-10</link>
		<dc:creator>Stacy</dc:creator>
		<pubDate>Thu, 20 Apr 2006 05:12:44 +0000</pubDate>
		<guid isPermaLink="false">http://dannorth.net/archives/14#comment-10</guid>
		<description>I think it would be interesting to be able write the code in synchronous fashion and then transform it into an asynchronous version, using annotations to mark the asynchronous operations.

For instance suppose I marked Pricer.price(Order) as an asynchronous operation then when loading OrderProcessor the AsynchronousTransformingClassLoader would notice that processOrder calls an asynchronous method and transform processOrder appropriately using futures and addressing concerns that Sam raised about errors occuring early in the pipeline.

Event driven architectures have quite a simple structure and therefore the number of types of transformation would be quite small.

I'd like to end this with an observation: When you look at the original processOrder and add the new piece of information that Pricer.price(Order) is slow you do not add much information to the description. I think the amount of change you need to make to a program to accomodate this new change should be of comparable size to the size of the change, and if this is not so then something is wrong with the model. In this case the model lacks the ability to concisely express asynchronousness.</description>
		<content:encoded><![CDATA[<p>I think it would be interesting to be able write the code in synchronous fashion and then transform it into an asynchronous version, using annotations to mark the asynchronous operations.</p>
<p>For instance suppose I marked Pricer.price(Order) as an asynchronous operation then when loading OrderProcessor the AsynchronousTransformingClassLoader would notice that processOrder calls an asynchronous method and transform processOrder appropriately using futures and addressing concerns that Sam raised about errors occuring early in the pipeline.</p>
<p>Event driven architectures have quite a simple structure and therefore the number of types of transformation would be quite small.</p>
<p>I&#8217;d like to end this with an observation: When you look at the original processOrder and add the new piece of information that Pricer.price(Order) is slow you do not add much information to the description. I think the amount of change you need to make to a program to accomodate this new change should be of comparable size to the size of the change, and if this is not so then something is wrong with the model. In this case the model lacks the ability to concisely express asynchronousness.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Stan</title>
		<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming#comment-8</link>
		<dc:creator>Stan</dc:creator>
		<pubDate>Wed, 12 Apr 2006 18:43:55 +0000</pubDate>
		<guid isPermaLink="false">http://dannorth.net/archives/14#comment-8</guid>
		<description>I read some academic papers on an alternative queuing approach. Instead of a thread per queue it used one thread on one processor. Instead of trying to run StepA, StepB and StepC from multiple requests at the same time, it ran a million StepA and queued the results, then a million StepB, then a million StepC. Giving a CPU a small chunk of code to run many times turns out to be more efficient than having it run a lot of different code and switch contexts all the time. Experimental implementations in web servers ran as quickly as normal threads and degraded more gracefully. There are many ways to carve up a problem!</description>
		<content:encoded><![CDATA[<p>I read some academic papers on an alternative queuing approach. Instead of a thread per queue it used one thread on one processor. Instead of trying to run StepA, StepB and StepC from multiple requests at the same time, it ran a million StepA and queued the results, then a million StepB, then a million StepC. Giving a CPU a small chunk of code to run many times turns out to be more efficient than having it run a lot of different code and switch contexts all the time. Experimental implementations in web servers ran as quickly as normal threads and degraded more gracefully. There are many ways to carve up a problem!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jacob Fugal</title>
		<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming#comment-5</link>
		<dc:creator>Jacob Fugal</dc:creator>
		<pubDate>Mon, 10 Apr 2006 16:36:44 +0000</pubDate>
		<guid isPermaLink="false">http://dannorth.net/archives/14#comment-5</guid>
		<description>&lt;i&gt;"And what about rollback conditions? If persisting a message fails, I don’t want to send a notification - but what if the notificatio has already been sent?"&lt;/i&gt;

The impression I get from this article (I may be wrong) is that the message isn't added to the notification queue until after the persisting queue is finished processing the message. So the three stages of order processing are still sequential, we've just added capability for more concurrent processing of other orders.

However, I'm not sure I understand the benefits here. I'll attempt to translate Dan's example into a more concrete breakdown.

We have three stages of order processing: Pricing, Persistence and Notification. Pricing is an expensive operation, requiring 5 time units. Persistence is cheap, only requiring 1 time unit. Notification is moderate, requiring 3 time units. So, all in all, processing an order requires 9 time units.

Now, imagine we have ten workers and fifty orders come in concurrently. Ten can be processed at a time, and the total time to process the fifty orders is 45 (9 time units / round * 5 rounds) time units.

Alternatively, consider those workers instead handle the three queues mentioned by Dan. Let's divvie them as 5 Pricers, 1 Persister and 3 Notifier. The tenth worker is accepting the requests and placing the initial message on the Pricer queue.

When the fifty concurrent requests arrive, they are all placed on the Pricer queue immediately (not quite, but it's safe to assume the dispatcher worker can fill the queue faster than the pricers can deplete it). Five are taken off the Pricer queue and 5 time units later added to the Persister queue. At this point, five more are taken off and processed. In the ensuing five time units, the persister worker has handled all five requests (1 time unit per request) and passed them on to the Notifier queue. So we see the one persister keeping up with the five pricers. Five more requests are placed on the persister queue and five more taken off the pricer queue. Also, the persister has been placing requests on the notification queue at the rate of one every time unit. The three notifier workers are pulling these off in turn -- by the time the persister has put a fourth request on the notification queue, the first notifier has finished the first request and can grab that one. So the notifiers are also keeping up. Every five time units, the pricers consume five requests of the pricer queue and the others are managing the previous requests apace. After 50 time units all 10 rounds of 5 requests have been processed by the pricers. 5 time units later, the persister queue has finished its processing. 3 time units later the last notifier finishes its requeust. Total time: 58 time units.

Isn't 58 &#62; 45?

Jacob Fugal</description>
		<content:encoded><![CDATA[<p><i>&#8220;And what about rollback conditions? If persisting a message fails, I don’t want to send a notification &#8211; but what if the notificatio has already been sent?&#8221;</i></p>
<p>The impression I get from this article (I may be wrong) is that the message isn&#8217;t added to the notification queue until after the persisting queue is finished processing the message. So the three stages of order processing are still sequential, we&#8217;ve just added capability for more concurrent processing of other orders.</p>
<p>However, I&#8217;m not sure I understand the benefits here. I&#8217;ll attempt to translate Dan&#8217;s example into a more concrete breakdown.</p>
<p>We have three stages of order processing: Pricing, Persistence and Notification. Pricing is an expensive operation, requiring 5 time units. Persistence is cheap, only requiring 1 time unit. Notification is moderate, requiring 3 time units. So, all in all, processing an order requires 9 time units.</p>
<p>Now, imagine we have ten workers and fifty orders come in concurrently. Ten can be processed at a time, and the total time to process the fifty orders is 45 (9 time units / round * 5 rounds) time units.</p>
<p>Alternatively, consider those workers instead handle the three queues mentioned by Dan. Let&#8217;s divvie them as 5 Pricers, 1 Persister and 3 Notifier. The tenth worker is accepting the requests and placing the initial message on the Pricer queue.</p>
<p>When the fifty concurrent requests arrive, they are all placed on the Pricer queue immediately (not quite, but it&#8217;s safe to assume the dispatcher worker can fill the queue faster than the pricers can deplete it). Five are taken off the Pricer queue and 5 time units later added to the Persister queue. At this point, five more are taken off and processed. In the ensuing five time units, the persister worker has handled all five requests (1 time unit per request) and passed them on to the Notifier queue. So we see the one persister keeping up with the five pricers. Five more requests are placed on the persister queue and five more taken off the pricer queue. Also, the persister has been placing requests on the notification queue at the rate of one every time unit. The three notifier workers are pulling these off in turn&#8212;by the time the persister has put a fourth request on the notification queue, the first notifier has finished the first request and can grab that one. So the notifiers are also keeping up. Every five time units, the pricers consume five requests of the pricer queue and the others are managing the previous requests apace. After 50 time units all 10 rounds of 5 requests have been processed by the pricers. 5 time units later, the persister queue has finished its processing. 3 time units later the last notifier finishes its requeust. Total time: 58 time units.</p>
<p>Isn&#8217;t 58 > 45?</p>
<p>Jacob Fugal</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sam Newman</title>
		<link>http://dannorth.net/2006/04/whats-so-hard-about-event-driven-programming#comment-4</link>
		<dc:creator>Sam Newman</dc:creator>
		<pubDate>Mon, 10 Apr 2006 08:25:08 +0000</pubDate>
		<guid isPermaLink="false">http://dannorth.net/archives/14#comment-4</guid>
		<description>And what about rollback conditions? If persisting a message fails, I don't want to send a notification - but what if the notificatio has already been sent? I assume you'd end up needing to fron this stuff with some kind of workflow or something...</description>
		<content:encoded><![CDATA[<p>And what about rollback conditions? If persisting a message fails, I don&#8217;t want to send a notification &#8211; but what if the notificatio has already been sent? I assume you&#8217;d end up needing to fron this stuff with some kind of workflow or something&#8230;</p>
]]></content:encoded>
	</item>
</channel>
</rss>
