2
title: HawtDispatch Stomp Example
3
--- name:overview pipeline:jade
9
--- name:content pipeline:markdown
13
HawtDispatch makes it easy to create multi-threaded NIO based applications.
14
To illustrate this, the source distribution includes an example messaging server
15
that implements the main parts of the
16
[STOMP](http://activemq.apache.org/stomp/stomp10/specification.html) protocol. The
17
server supports topics and 'simplistic' queues.
19
You can browse it's source code online at: [github](http://github.com/fusesource/hawtdispatch/blob/master/hawtdispatch-example/src/main/scala/org/fusesource/hawtdispatch/example/stomp)
23
Once you [build the code](community/building.html), start 2 terminals in
24
the [`hawtdispatch/hawtdispatch-example`](http://github.com/chirino/hawtdispatch/blob/master/hawtdispatch-example/)
25
directory. In both terminals execute the `mvn scala:console` command to start a
26
Scala interactive interpreter.
28
### Starting the Broker
30
The first terminal will be used to run the STOMP based message broker. Execute the
31
following statements in that terminal:
34
val broker = org.fusesource.hawtdispatch.example.stomp.StompBroker
38
You should see output similar to the following:
41
scala> val broker = org.fusesource.hawtdispatch.example.stomp.StompBroker
42
broker: org.fusesource.hawtdispatch.example.stomp.StompBroker.type =
43
--------------------------------------
44
StompBroker Properties
45
--------------------------------------
51
Starting stomp broker...
55
### Starting the Clients
57
The second terminal will be used to run a performance sampling STOMP
58
producer and consumer. Execute the following statements in that terminal:
61
val client = org.fusesource.hawtdispatch.example.stomp.StompLoadClient
64
You should see output similar to the following:
67
scala> val client = org.fusesource.hawtdispatch.example.stomp.StompLoadClient
68
client: org.fusesource.hawtdispatch.example.stomp.StompLoadClient.type =
69
--------------------------------------
70
StompLoadClient Properties
71
--------------------------------------
72
uri = stomp://127.0.0.1:61613
75
destinationType = queue
81
useContentLength = true
86
The client object allows you to configure several parameters of the load test. For example,
87
you can control the number consumer and producer connections, the type of destination used.
88
If we wanted to test out a pub/sub fan out scenario where 10 consumers are receiving message
89
broadcasts from one producer, you would execute the following statements:
92
client.destinationType = "topic"
97
Once you are happy with the client configuration, you just need to execute `client.run` for
98
it to start executing. Pressing enter will end the execution and allow you to tweak the
99
configuration before running it again.
101
When run, you should see output similar to the following:
104
scala> client.destinationType = "topic"
106
scala> client.producers = 1
108
scala> client.consumers = 10
111
=======================
112
Press ENTER to shutdown
113
=======================
115
Producer rate: 22,708.520 per second
116
Consumer rate: 226,332.781 per second
117
Producer rate: 24,306.738 per second
118
Consumer rate: 242,921.375 per second
119
Producer rate: 24,907.004 per second
120
Consumer rate: 249,344.063 per second
121
=======================
123
=======================
126
The client was implemented using traditional blocking IO and java threads. If time allows,
127
we should also implement this using HawtDispatch.
129
### Interesting Implementation Notes
131
* Not a single synchronized keyword was used
133
* Each connection is assigned 1 HawtDispatch serial queue and that serial
134
dispatch queue is pined to 1 thread queue by setting the serial
135
queue's target to be a random thread queue.
137
* Producer connections send message to consumer connection using a credit
138
based transfer window. This allows producer connections to send many
139
messages to a consumer connection without much blocking or contention.
141
* When there is credit in the transfer window, a custom dispatch source is
142
used so that the messages 'batch' up and transferred from the producer
143
thread to a consumer thread in as a batch.
145
* Broker will periodically "colocate" producer connections with consumer
146
connections by re-pinning the producer's serial queue to match the thread
147
queue of the consumer connection. This allows the producer to avoid
148
cross thread contention.