Skip to content

Understanding concurrency

Rodney Lopes Gomes edited this page Sep 24, 2010 · 3 revisions

Concurrency in DTF is very simple to use but still requires that you're careful about certain things. This includes things such as not running more threads than your system can actually handle before it starts spending more time doing context switching then actually getting work done. With this in mind lets first visit the simplest way to make two actions execute in parallel with in DTF:

<parallel>
	<for property="j" range="[1..4]">
		<local>
			<echo>Echo ${j}</echo>
		</local>
	</for>
	<for property="j" range="[5,6]">
		<local>
			<echo>Echo ${j}</echo>
		</local>
	</for>
	<for property="j" range="[7,8,9,10]">
		<local>
			<echo>Echo ${j}</echo>
		</local>
	</for>
</parallel>

The parallel tag will simply parallelize the underlying execution of the children tag that are direct descendants of the parallel tag. Its very easy to read require very little understanding of how to use it making it a great tag to use when you just want to run a few tasks in parallel quickly.

Now when you want to parallelize the same task n times there is a much better suited tag by the name of parallelloop which does exactly what the name says. This tag parallelizes the underlying child tag amongst the number of threads specified in the range attribute and makes sure that each thread can see the value of the property identified by the attribute property so that each thread can now which of the n threads it is. With this you can start up 10 thread as easy as the following:

<parallelloop property="i" range="1..10">
    <log>${i}</log>
</parallelloop>

Again understanding this tag isn't the hard part but the thing to start noticing is that you can easily do the wrong thing with this tag such as doing trying to execute the following:

<parallelloop property="i" range="1..10">
    <parallelloop property="j" range="1..20">
        <log>${i}.${j}</log>
    </parallelloop>
</parallelloop>

Now it may look pretty innocent but the above code would actually spawn 200 threads concurrently and because in this case they're short lived and just log a small message this won't result in anything negative, but if you were trying to execute an actual test from a single machine and had 200 threads trying to concurrently use some API you'd find your system's load would spike and that your test would in fact spent way more time doing context switching between threads than actually getting work done.

The last of the parallelization tags that are available within DTF is the distribute tag which is capable of doing much more than just spawning a certain number of concurrent actions. The distribute tag can be used to spawn N threads and guarantee that they execute the underlying child tag at a rate that you specify with the func attribute. The func attribute can be used to specify the distribution function for the executions per unit of time that you'd like to see your action occurring over the time or iterations that you specified. Lets look at a simple usage of the distribute tag to use 5 threads and make sure to execute 10 times per second:

<distribute func="const(10)" range="1..5" timer="1m">
    <log>Executed once!</log>
</distribute>

When this tag is unable to hit the expected distribution that the user desired it will log as well as add information to the events thrown by the tag that can be used to easily fail the test case or at least warn the user that the expected distribution wasn't hit. For more information on using those advanced features have a look at the generated documentation

Clone this wiki locally