forked from vert-x/vert-x.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
core_manual_clojure.html
3445 lines (3374 loc) · 168 KB
/
core_manual_clojure.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<!-- <link rel="stylesheet/less" href="bootstrap/less/bootstrap.less">
<script src="bootstrap/less/less-1.3.3.min.js"></script>
-->
<link href="bootstrap/bootstrap.css" type="text/css" rel="stylesheet"/>
<link href="google-code-prettify/prettify.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="google-code-prettify/prettify.js"></script>
<link href="css/vertx.css" type="text/css" rel="stylesheet"/>
<link href="css/sunburst.css" type="text/css" rel="stylesheet"/>
<title>Vert.x</title>
<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-30144458-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body onload="prettyPrint()" class="hp">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse"
data-target=".nav-collapse">
<span class="i-bar"></span>
<span class="i-bar"></span>
<span class="i-bar"></span>
</a>
<a class="brand" href="/">Vert.x</a>
<div class="nav-collapse">
<ul class="nav">
<li><a href="/">Home</a></li>
<li><a href="downloads.html">Download</a></li>
<li><a href="install.html">Install</a></li>
<li><a href="docs.html">Documentation</a></li>
<li><a href="examples.html">Examples</a></li>
<li><a href="community.html">Project Info</a></li>
<li><a href="https://github.com/vert-x/vert.x">Github</a></li>
<li><a href="http://modulereg.vertx.io/">Module Registry</a></li>
<li><a href="http://groups.google.com/group/vertx">Google Group</a></li>
<li><a href="http://vertxproject.wordpress.com/">Blog</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="span12">
<div class="well">
<h1>Clojure API Manual</h1>
</div>
</div>
</div>
<div class="row">
<div class="span12">
<div class="well">
<div>
<div class="toc">
<ul>
<li><a href="#writing-verticles">Writing Verticles</a><ul>
<li><a href="#accessing-the-vertx-api">Accessing the Vert.x API</a></li>
<li><a href="#verticle-clean-up">Verticle clean-up</a></li>
<li><a href="#getting-configuration-in-a-verticle">Getting Configuration in a Verticle</a></li>
<li><a href="#logging-from-a-verticle">Logging from a Verticle</a></li>
<li><a href="#accessing-environment-variables-from-a-verticle">Accessing environment variables from a Verticle</a></li>
<li><a href="#causing-the-container-to-exit">Causing the container to exit</a></li>
</ul>
</li>
<li><a href="#deploying-and-undeploying-verticles-programmatically">Deploying and Undeploying Verticles Programmatically</a><ul>
<li><a href="#deploying-a-simple-verticle">Deploying a simple verticle</a></li>
<li><a href="#deploying-worker-verticles">Deploying Worker Verticles</a></li>
<li><a href="#deploying-a-module-programmatically">Deploying a module programmatically</a></li>
<li><a href="#passing-configuration-to-a-verticle-programmatically">Passing configuration to a verticle programmatically</a></li>
<li><a href="#using-a-verticle-to-co-ordinate-loading-of-an-application">Using a Verticle to co-ordinate loading of an application</a></li>
<li><a href="#specifying-number-of-instances">Specifying number of instances</a></li>
<li><a href="#getting-notified-when-deployment-is-complete">Getting Notified when Deployment is complete</a></li>
<li><a href="#undeploying-a-verticle">Undeploying a Verticle</a></li>
</ul>
</li>
<li><a href="#the-event-bus">The Event Bus</a><ul>
<li><a href="#the-theory">The Theory</a><ul>
<li><a href="#addressing">Addressing</a></li>
<li><a href="#handlers">Handlers</a></li>
<li><a href="#publish-subscribe-messaging">Publish / subscribe messaging</a></li>
<li><a href="#point-to-point-and-request-response-messaging">Point to point and Request-Response messaging</a></li>
<li><a href="#transient">Transient</a></li>
<li><a href="#types-of-messages">Types of messages</a></li>
</ul>
</li>
<li><a href="#event-bus-api">Event Bus API</a><ul>
<li><a href="#registering-and-unregistering-handlers">Registering and Unregistering Handlers</a></li>
<li><a href="#publishing-messages">Publishing messages</a></li>
<li><a href="#sending-messages">Sending messages</a></li>
<li><a href="#replying-to-messages">Replying to messages</a><ul>
<li><a href="#specifying-timeouts-for-replies">Specifying timeouts for replies</a></li>
<li><a href="#getting-notified-of-reply-failures">Getting notified of reply failures</a></li>
</ul>
</li>
<li><a href="#message-types">Message types</a></li>
</ul>
</li>
<li><a href="#distributed-event-bus">Distributed event bus</a></li>
</ul>
</li>
<li><a href="#shared-data">Shared Data</a><ul>
<li><a href="#shared-maps">Shared Maps</a></li>
<li><a href="#shared-sets">Shared Sets</a></li>
</ul>
</li>
<li><a href="#buffers">Buffers</a><ul>
<li><a href="#creating-buffers">Creating Buffers</a></li>
<li><a href="#writing-to-a-buffer">Writing to a Buffer</a><ul>
<li><a href="#appending-to-a-buffer">Appending to a Buffer</a></li>
<li><a href="#random-access-buffer-writes">Random access buffer writes</a></li>
</ul>
</li>
<li><a href="#reading-from-a-buffer">Reading from a Buffer</a></li>
</ul>
</li>
<li><a href="#delayed-and-periodic-tasks">Delayed and Periodic Tasks</a><ul>
<li><a href="#one-shot-timers">One-shot Timers</a></li>
<li><a href="#periodic-timers">Periodic Timers</a></li>
<li><a href="#cancelling-timers">Cancelling timers</a></li>
</ul>
</li>
<li><a href="#writing-tcp-servers-and-clients">Writing TCP Servers and Clients</a><ul>
<li><a href="#net-server">Net Server</a><ul>
<li><a href="#creating-a-net-server">Creating a Net Server</a></li>
<li><a href="#start-the-server-listening">Start the Server Listening</a></li>
<li><a href="#getting-notified-of-incoming-connections">Getting Notified of Incoming Connections</a></li>
<li><a href="#closing-a-net-server">Closing a Net Server</a></li>
<li><a href="#net-server-properties">Net Server Properties</a></li>
<li><a href="#handling-data">Handling Data</a><ul>
<li><a href="#reading-data-from-the-socket">Reading Data from the Socket</a></li>
<li><a href="#writing-data-to-a-socket">Writing Data to a Socket</a></li>
</ul>
</li>
<li><a href="#closing-a-socket">Closing a socket</a></li>
<li><a href="#closed-handler">Closed Handler</a></li>
<li><a href="#exception-handler">Exception handler</a></li>
<li><a href="#event-bus-write-handler">Event Bus Write Handler</a></li>
<li><a href="#read-and-write-streams">Read and Write Streams</a></li>
</ul>
</li>
<li><a href="#scaling-tcp-servers">Scaling TCP Servers</a></li>
<li><a href="#netclient">NetClient</a><ul>
<li><a href="#creating-a-net-client">Creating a Net Client</a></li>
<li><a href="#making-a-connection">Making a Connection</a></li>
<li><a href="#configuring-reconnection">Configuring Reconnection</a></li>
</ul>
</li>
<li><a href="#ssl-servers">SSL Servers</a></li>
<li><a href="#ssl-clients">SSL Clients</a></li>
</ul>
</li>
<li><a href="#user-datagram-protocol-udp">User Datagram Protocol (UDP)</a><ul>
<li><a href="#creating-a-datagramsocket">Creating a DatagramSocket</a></li>
<li><a href="#sending-datagram-packets">Sending Datagram packets</a></li>
<li><a href="#receiving-datagram-packets">Receiving Datagram packets</a></li>
<li><a href="#multicast">Multicast</a><ul>
<li><a href="#sending-multicast-packets">Sending Multicast packets</a></li>
<li><a href="#receiving-multicast-packets">Receiving Multicast packets</a></li>
<li><a href="#leaving-a-multicast-group">Leaving a Multicast group</a></li>
<li><a href="#blocking-multicast">Blocking multicast</a></li>
</ul>
</li>
<li><a href="#datagramsocket-properties">DatagramSocket properties</a></li>
<li><a href="#datagramsocket-local-address">DatagramSocket Local Address</a></li>
<li><a href="#closing-a-datagramsocket">Closing a DatagramSocket</a></li>
</ul>
</li>
<li><a href="#flow-control-streams-and-pumps">Flow Control - Streams and Pumps</a><ul>
<li><a href="#readstream">ReadStream</a></li>
<li><a href="#writestream">WriteStream</a></li>
<li><a href="#pump">Pump</a></li>
</ul>
</li>
<li><a href="#writing-http-servers-and-clients">Writing HTTP Servers and Clients</a><ul>
<li><a href="#writing-http-servers">Writing HTTP servers</a><ul>
<li><a href="#creating-an-http-server">Creating an HTTP Server</a></li>
<li><a href="#start-the-server-listening_1">Start the Server Listening</a></li>
<li><a href="#getting-notified-of-incoming-requests">Getting Notified of Incoming Requests</a></li>
<li><a href="#handling-http-requests">Handling HTTP Requests</a><ul>
<li><a href="#request-method">Request Method</a></li>
<li><a href="#request-version">Request Version</a></li>
<li><a href="#request-uri">Request URI</a></li>
<li><a href="#request-path">Request Path</a></li>
<li><a href="#request-query">Request Query</a></li>
<li><a href="#request-headers">Request Headers</a></li>
<li><a href="#request-params">Request params</a></li>
<li><a href="#remote-address">Remote Address</a></li>
<li><a href="#absolute-uri">Absolute URI</a></li>
<li><a href="#reading-data-from-the-request-body">Reading Data from the Request Body</a></li>
<li><a href="#handling-multipart-form-uploads">Handling Multipart Form Uploads</a></li>
<li><a href="#handling-multipart-form-attributes">Handling Multipart Form Attributes</a></li>
</ul>
</li>
<li><a href="#http-server-responses">HTTP Server Responses</a></li>
<li><a href="#setting-status-code-and-message">Setting Status Code and Message</a><ul>
<li><a href="#writing-http-responses">Writing HTTP responses</a></li>
<li><a href="#ending-http-responses">Ending HTTP responses</a></li>
<li><a href="#closing-the-underlying-connection">Closing the underlying connection</a></li>
<li><a href="#response-headers">Response headers</a></li>
<li><a href="#chunked-http-responses-and-trailers">Chunked HTTP Responses and Trailers</a></li>
</ul>
</li>
<li><a href="#serving-files-directly-from-disk">Serving files directly from disk</a></li>
<li><a href="#pumping-responses">Pumping Responses</a></li>
</ul>
</li>
<li><a href="#writing-http-clients">Writing HTTP Clients</a><ul>
<li><a href="#creating-an-http-client">Creating an HTTP Client</a></li>
<li><a href="#pooling-and-keep-alive">Pooling and Keep Alive</a></li>
<li><a href="#closing-the-client">Closing the client</a></li>
<li><a href="#making-requests">Making Requests</a><ul>
<li><a href="#handling-exceptions">Handling exceptions</a></li>
<li><a href="#writing-to-the-request-body">Writing to the request body</a></li>
<li><a href="#ending-http-responses_1">Ending HTTP responses</a></li>
<li><a href="#writing-request-headers">Writing Request Headers</a></li>
<li><a href="#request-timeouts">Request timeouts</a></li>
<li><a href="#http-chunked-requests">HTTP chunked requests</a></li>
</ul>
</li>
<li><a href="#http-client-responses">HTTP Client Responses</a><ul>
<li><a href="#reading-data-from-the-response-body">Reading Data from the Response Body</a></li>
<li><a href="#reading-cookies">Reading cookies</a></li>
</ul>
</li>
<li><a href="#100-continue-handling">100-Continue Handling</a></li>
<li><a href="#http-compression">HTTP Compression</a></li>
</ul>
</li>
<li><a href="#pumping-requests-and-responses">Pumping Requests and Responses</a></li>
<li><a href="#https-servers">HTTPS Servers</a></li>
<li><a href="#https-clients">HTTPS Clients</a></li>
<li><a href="#scaling-http-servers">Scaling HTTP servers</a></li>
</ul>
</li>
<li><a href="#routing-http-requests-with-pattern-matching">Routing HTTP requests with Pattern Matching</a><ul>
<li><a href="#specifying-matches">Specifying matches.</a></li>
<li><a href="#extracting-parameters-from-the-path">Extracting parameters from the path</a></li>
<li><a href="#extracting-params-using-regular-expressions">Extracting params using Regular Expressions</a></li>
<li><a href="#handling-requests-where-nothing-matches">Handling requests where nothing matches</a></li>
</ul>
</li>
<li><a href="#websockets">WebSockets</a><ul>
<li><a href="#websockets-on-the-server">WebSockets on the server</a><ul>
<li><a href="#reading-from-and-writing-to-websockets">Reading from and Writing to WebSockets</a></li>
<li><a href="#rejecting-websockets">Rejecting WebSockets</a></li>
<li><a href="#event-bus-write-handler_1">Event Bus Write Handler</a></li>
<li><a href="#headers-on-the-websocket">Headers on the websocket</a></li>
</ul>
</li>
<li><a href="#websockets-on-the-http-client">WebSockets on the HTTP client</a></li>
<li><a href="#websockets-in-the-browser">WebSockets in the browser</a><ul>
<li><a href="#set-a-max-frame-size-for-websockets">Set a max frame size for WebSockets</a></li>
</ul>
</li>
<li><a href="#routing-websockets-with-pattern-matching">Routing WebSockets with Pattern Matching</a></li>
</ul>
</li>
<li><a href="#sockjs">SockJS</a><ul>
<li><a href="#sockjs-server">SockJS Server</a></li>
<li><a href="#reading-and-writing-data-from-a-sockjs-server">Reading and writing data from a SockJS server</a></li>
<li><a href="#sockjs-client">SockJS client</a></li>
</ul>
</li>
<li><a href="#sockjs-eventbus-bridge">SockJS - EventBus Bridge</a><ul>
<li><a href="#setting-up-the-bridge">Setting up the Bridge</a></li>
<li><a href="#using-the-event-bus-from-client-side-javascript">Using the Event Bus from client-side JavaScript</a></li>
<li><a href="#using-the-event-bus-from-client-side-clojurescript">Using the Event Bus from client-side ClojureScript</a></li>
<li><a href="#securing-the-bridge">Securing the Bridge</a></li>
<li><a href="#messages-that-require-authorisation">Messages that require authorisation</a></li>
</ul>
</li>
<li><a href="#file-system">File System</a><ul>
<li><a href="#synchronous-forms">Synchronous forms</a></li>
<li><a href="#copy">copy</a></li>
<li><a href="#move">move</a></li>
<li><a href="#truncate">truncate</a></li>
<li><a href="#chmod">chmod</a></li>
<li><a href="#properties">properties</a></li>
<li><a href="#link">link</a></li>
<li><a href="#resolve-symlink">resolve-symlink</a></li>
<li><a href="#delete">delete</a></li>
<li><a href="#mkdir">mkdir</a></li>
<li><a href="#read_dir">read_dir</a></li>
<li><a href="#read-file">read-file</a></li>
<li><a href="#write-file">write-file</a></li>
<li><a href="#create_file">create_file</a></li>
<li><a href="#exists">exists?</a></li>
<li><a href="#file-system-properties">file-system-properties</a></li>
<li><a href="#open">open</a></li>
<li><a href="#asyncfile">AsyncFile</a><ul>
<li><a href="#random-access-writes">Random access writes</a></li>
<li><a href="#random-access-reads">Random access reads</a></li>
<li><a href="#flushing-data-to-underlying-storage">Flushing data to underlying storage.</a></li>
<li><a href="#using-asyncfile-as-readstream-and-writestream">Using AsyncFile as ReadStream and WriteStream</a></li>
<li><a href="#closing-an-asyncfile">Closing an AsyncFile</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#dns-client">DNS Client</a><ul>
<li><a href="#lookup">lookup</a></li>
<li><a href="#resolve">resolve</a></li>
<li><a href="#reverselookup">reverseLookup</a></li>
<li><a href="#error-handling">Error handling</a></li>
</ul>
</li>
<li><a href="#using-nrepl">Using nREPL</a></li>
</ul>
</div>
<h1 id="writing-verticles">Writing Verticles</h1><br/>
<p>As was described in the <a href="manual.html#verticle">main manual</a>, a
verticle is the execution unit of Vert.x.</p>
<p>To recap, Vert.x is a container which executed packages of code called
Verticles, and it ensures that the code in the verticle is never
executed concurrently by more than one thread. You can write your
verticles in any of the languages that Vert.x supports, and Vert.x
supports running many verticle instances concurrently in the same
Vert.x instance.</p>
<p>All the code you write in a Vert.x application runs inside a Verticle
instance.</p>
<p>For simple prototyping and trivial tasks you can write raw verticles
and run them directly on the command line, but in most cases you will
always wrap your verticles inside Vert.x <a href="mods_manual.html">modules</a>.</p>
<p>For now, let's try writing a simple raw verticle.</p>
<p>As an example we'll write a simple TCP echo server. The server just
accepts connections and any data received by it is echoed back on the
connection.</p>
<p>Copy the following into a text editor and save it as <code>server.clj</code></p>
<pre class="prettyprint">(ns example.server
(:require [vertx.core :as core]
[vertx.net :as net]
[vertx.stream :as stream]))
(let [server (net/server)]
(-> server
(net/on-connect #(stream/pump % %))
(net/listen 1234 "localhost"))
(core/on-stop
(.close server)))
</pre>
<p>Now, go to the directory where you saved the file and type</p>
<pre class="prettyprint">vertx run server.clj
</pre>
<p>The server will now be running. Connect to it using telnet:</p>
<pre class="prettyprint">telnet localhost 1234
</pre>
<p>And notice how data you send (and hit enter) is echoed back to you.</p>
<p>Congratulations! You've written your first verticle.</p>
<p>In the rest of this manual we'll assume the code snippets are running
inside a verticle.</p>
<h2 id="accessing-the-vertx-api">Accessing the Vert.x API</h2><br/>
<p>The Clojure Vert.x API consists of several namespaces that you will
need to require directly or as part of the namespace declaration in
your verticle main file.</p>
<h2 id="verticle-clean-up">Verticle clean-up</h2><br/>
<p>Servers, clients and event bus handlers will be automatically closed
when the verticles is stopped, however if you need to provide any
custom clean-up code when the verticle is stopped you can register any
number of bodies or functions with the <code>vertx.core/on-stop</code> macro and
<code>vertx.core/on-stop*</code> function, respectively. Vert.x will invoke all
of the registered bodies/functions when the verticle is stopped.</p>
<h2 id="getting-configuration-in-a-verticle">Getting Configuration in a Verticle</h2><br/>
<p>You can pass configuration to a module or verticle from the command
line using the <code>-conf</code> option, for example:</p>
<pre class="prettyprint">vertx runmod com.mycompany~my-mod~1.0 -conf myconf.json
</pre>
<p>or for a raw verticle</p>
<pre class="prettyprint">vertx run foo.clj -conf myconf.json
</pre>
<p>The argument to <code>-conf</code> is the name of a text file containing a valid
JSON object.</p>
<p>The configuration is available in the verticle as a Clojure map using
the <code>vertx.core/config</code> function. For example:</p>
<pre class="prettyprint">(require '[vertx.core :as core])
;; Do something with config
(println "number of wibbles is #{config.wibble_number}"
(:wibble-number (core/config)))
</pre>
<p>The config returned is a Clojure map with keyword keys. You can use
this object to configure the verticle. Allowing verticles to be
configured in a consistent way like this allows configuration to be
easily passed to them irrespective of the language.</p>
<h2 id="logging-from-a-verticle">Logging from a Verticle</h2><br/>
<p>Each verticle is given its own logger. You can log to it using the
functions in <code>vertx.logging</code>:</p>
<pre class="prettyprint">(require '[vertx.logging :as log])
(log/info "I am logging something")
</pre>
<p><code>vertx.logging</code> provides the following macros:</p>
<ul>
<li>trace</li>
<li>debug</li>
<li>info</li>
<li>warn</li>
<li>error</li>
<li>fatal</li>
</ul>
<p>Which have the normal meanings you would expect.</p>
<p>The log files by default go in a file called <code>vertx.log</code> in the system
temp directory. On my Linux box this is <code>/tmp</code>.</p>
<p>For more information on configuring logging, please see the
<a href="manual.html#logging">main manual</a>.</p>
<h2 id="accessing-environment-variables-from-a-verticle">Accessing environment variables from a Verticle</h2><br/>
<p>You can access a map of environment variables from a Verticle with the
<code>vertx.core/env</code> function.</p>
<h2 id="causing-the-container-to-exit">Causing the container to exit</h2><br/>
<p>You can call the <code>vertx.core/exit</code> function to cause the Vert.x
instance to make a clean shutdown.</p>
<h1 id="deploying-and-undeploying-verticles-programmatically">Deploying and Undeploying Verticles Programmatically</h1><br/>
<p>You can deploy and undeploy verticles programmatically from inside
another verticle. Any verticles deployed this way will be able to see
resources (classes, scripts, other files) of the main verticle.</p>
<h2 id="deploying-a-simple-verticle">Deploying a simple verticle</h2><br/>
<p>To deploy a verticle programmatically call the
<code>vertx.core/deploy-verticle</code> function.</p>
<p>To deploy a single instance of a verticle :</p>
<pre class="prettyprint">(core/deploy-verticle main)
</pre>
<p>Where <code>main</code> is the name of the Verticle (i.e. the name of the script
or FQCN of the class).</p>
<p>See the chapter on <a href="manual.html#running-vertx">"running Vert.x"</a> in
the main manual for a description of what a main is.</p>
<h2 id="deploying-worker-verticles">Deploying Worker Verticles</h2><br/>
<p>The <code>vertx.core/deploy-verticle</code> function deploys standard (non
worker) verticles. If you want to deploy worker verticles use the
<code>vertx.core/deploy-worker-verticle</code> function. This function takes the
same parameters as <code>vertx.core/deploy-verticle</code> with the same
meanings.</p>
<h2 id="deploying-a-module-programmatically">Deploying a module programmatically</h2><br/>
<p>You should use <code>vertx.core/deploy-module</code> to deploy a module, for example:</p>
<pre class="prettyprint">(core/deploy-module "io.vertx~mod-mailer~2.0.0-beta1"
:config config)
</pre>
<p>Would deploy an instance of the <code>io.vertx~mod-mailer~2.0.0-beta1</code>
module with the specified configuration map. Please see the
<a href="mods_manual.html">modules manual</a> for more information about modules.</p>
<h2 id="passing-configuration-to-a-verticle-programmatically">Passing configuration to a verticle programmatically</h2><br/>
<p>Configuration can be passed to a verticle that is deployed
programmatically. Inside the deployed verticle the configuration is
accessed with the <code>vertx.core/config</code> function. For example:</p>
<pre class="prettyprint">(core/deploy-verticle "my_verticle.clj"
:config {:name "foo" :age 234})
</pre>
<p>Then, in <code>my_verticle.clj</code> you can access the config via
<code>vertx.core/config</code> as previously explained.</p>
<h2 id="using-a-verticle-to-co-ordinate-loading-of-an-application">Using a Verticle to co-ordinate loading of an application</h2><br/>
<p>If you have an application that is composed of multiple verticles that
all need to be started at application start-up, then you can use
another verticle that maintains the application configuration and
starts all the other verticles. You can think of this as your
application starter verticle.</p>
<p>For example, you could create a verticle <code>app.clj</code> as follows:</p>
<pre class="prettyprint">(ns my.app
(:require [vertx.core :refer
[config deploy-verticle deploy-worker-verticle]]))
(let [cfg (config)]
;; start the verticles that make up the app
(deploy-verticle "verticle1.clj"
:config (:verticle1Config cfg))
(deploy-verticle "verticle2.clj"
:config (:verticle2Config cfg)
:instances 5)
(deploy-verticle "verticle3.clj"
:config (:verticle3Config cfg))
(deploy-worker-verticle "verticle4.clj"
:config (:verticle4Config cfg))
(deploy-worker-verticle "verticle5.clj"
:config (:verticle5Config cfg)
:instances 10))
</pre>
<p>Then set the <code>app.clj</code> verticle as the main of your module and then
you can start your entire application by simply running:</p>
<pre class="prettyprint">vertx runmod com.mycompany~my-mod~1.0 -conf conf.json
</pre>
<p>Where conf.json is a config file like:</p>
<pre class="prettyprint">// Application config
{
verticle1Config: {
// Config for verticle1
},
verticle2Config: {
// Config for verticle2
},
verticle3Config: {
// Config for verticle3
},
verticle4Config: {
// Config for verticle4
},
verticle5Config: {
// Config for verticle5
}
}
</pre>
<p>If your application is large and actually composed of multiple modules
rather than verticles you can use the same technique.</p>
<h2 id="specifying-number-of-instances">Specifying number of instances</h2><br/>
<p>By default, when you deploy a verticle only one instance of the
verticle is deployed. Verticles instances are strictly single threaded
so this means you will use at most one core on your server.</p>
<p>Vert.x scales by deploying many verticle instances concurrently.</p>
<p>If you want more than one instance of a particular verticle or module
to be deployed, you can specify the number of instances as follows:</p>
<pre class="prettyprint">(core/deploy-verticle "foo.ChildVerticle"
:instances 10)
</pre>
<p>Or</p>
<pre class="prettyprint">(core/deploy-module "io.vertx~some-mod~1.0"
:instances 10)
</pre>
<p>The above examples would deploy 10 instances.</p>
<h2 id="getting-notified-when-deployment-is-complete">Getting Notified when Deployment is complete</h2><br/>
<p>The actual verticle deployment is asynchronous and might not complete
until some time after the call to <code>deploy-verticle</code> or <code>deploy-module</code>
has returned. If you want to be notified when the verticle/module has
completed being deployed, you can pass a function to <code>deploy-verticle</code>,
which will be called when it's complete:</p>
<pre class="prettyprint">(core/deploy-verticle "my_verticle.clj"
:handler (fn [err deploy-id]
(when-not err
(println "It's been deployed OK!"))))
</pre>
<p>The first parameter passed to the fn is an exception-map which will be not
<code>nil</code> if a failure occurred, otherwise it will be <code>nil</code>.</p>
<p>The second parameter is the deployment id string. It will be <code>nil</code> if
a failure occurred. You will need this if you later want to undeploy
the verticle or module.</p>
<h2 id="undeploying-a-verticle">Undeploying a Verticle</h2><br/>
<p>Any verticles that you deploy programmatically from within a verticle
and all of their children are automatically undeployed when the parent
verticle is undeployed, so in most cases you will not need to undeploy
a verticle manually, however if you do want to do this, it can be done
by calling the <code>vertx.core/undeploy-verticle</code> function, passing in the
deployment id.</p>
<pre class="prettyprint">(core/deploy-verticle "my_verticle.rb"
:handler (fn [err deploy-id]
;; Immediately undeploy it
(when-not err
(core/undeploy-verticle deploy-id))))
</pre>
<p>A verticle instance is almost always single threaded (the only
exception is multi-threaded worker verticles which are an advanced
feature not intended for normal development), this means a single
instance can at most utilise one core of your server.</p>
<p>In order to scale across cores you need to deploy more verticle
instances. The exact numbers depend on your application - how many
verticles there are and of what type.</p>
<p>You can deploy more verticle instances programmatically or on the
command line when deploying your module using the <code>-instances</code> command
line option.</p>
<h1 id="the-event-bus">The Event Bus</h1><br/>
<p>The event bus is the nervous system of Vert.x.</p>
<p>It allows verticles to communicate with each other irrespective of
what language they are written in, and whether they're in the same
Vert.x instance, or in a different Vert.x instance.</p>
<p>It even allows client side JavaScript running in a browser to
communicate on the same event bus. (More on that later).</p>
<p>The event bus forms a distributed polyglot overlay network spanning
multiple server nodes and multiple browsers.</p>
<p>The event bus API is incredibly simple. It basically involves
registering handlers, unregistering handlers and sending and
publishing messages.</p>
<p>First some theory:</p>
<h2 id="the-theory">The Theory</h2><br/>
<h3 id="addressing">Addressing</h3><br/>
<p>Messages are sent on the event bus to an <em>address</em>.</p>
<p>Vert.x doesn't bother with any fancy addressing schemes. In Vert.x an
address is simply a string, any string is valid. However it is wise to
use some kind of scheme, e.g. using periods to demarcate a namespace.</p>
<p>Some examples of valid addresses are <code>europe.news.feed1</code>,
<code>acme.games.pacman</code>, <code>sausages</code>, and <code>X</code>.</p>
<h3 id="handlers">Handlers</h3><br/>
<p>A handler is a thing that receives messages from the bus. You register
a handler at an address.</p>
<p>Many different handlers from the same or different verticles can be
registered at the same address. A single handler can be registered by
the verticle at many different addresses.</p>
<h3 id="publish-subscribe-messaging">Publish / subscribe messaging</h3><br/>
<p>The event bus supports <em>publishing</em> messages. Messages are published
to an address. Publishing means delivering the message to all handlers
that are registered at that address. This is the familiar
<em>publish/subscribe</em> messaging pattern.</p>
<h3 id="point-to-point-and-request-response-messaging">Point to point and Request-Response messaging</h3><br/>
<p>The event bus supports <em>point to point</em> messaging. Messages are sent
to an address. Vert.x will then route it to just one of the handlers
registered at that address. If there is more than one handler
registered at the address, one will be chosen using a non-strict
round-robin algorithm.</p>
<p>With point to point messaging, an optional reply handler can be
specified when sending the message. When a message is received by a
recipient, and has been handled, the recipient can optionally decide
to reply to the message. If they do so that reply handler will be
called.</p>
<p>When the reply is received back at the sender, it too can be replied
to. This can be repeated ad-infinitum, and allows a dialog to be
set-up between two different verticles. This is a common messaging
pattern called the <em>Request-Response</em> pattern.</p>
<h3 id="transient">Transient</h3><br/>
<p><em>All messages in the event bus are transient, and in case of failure
of all or parts of the event bus, there is a possibility messages
will be lost. If your application cares about lost messages, you
should code your handlers to be idempotent, and your senders to retry
after recovery.</em></p>
<p>If you want to persist your messages you can use a persistent work
queue module for that.</p>
<h3 id="types-of-messages">Types of messages</h3><br/>
<p>Messages that you send on the event bus can be as simple as a string,
a number or a boolean. You can also send vert.x buffers or JSON.</p>
<p>It's highly recommended you use JSON messages to communicate between
verticles. JSON is easy to create and parse in all the languages that
vert.x supports.</p>
<h2 id="event-bus-api">Event Bus API</h2><br/>
<p>Let's jump into the API</p>
<h3 id="registering-and-unregistering-handlers">Registering and Unregistering Handlers</h3><br/>
<p>To set a message handler on the address <code>test.address</code>, you call the
<code>vertx.eventbus/on-message</code> function:</p>
<pre class="prettyprint">(require '[vertx.eventbus :as eb])
(eb/on-message "test.address"
(fn [message]
(println "Got message body" (eb/body message))))
</pre>
<p>It's as simple as that. The handler will then receive any messages
sent to that address. The object passed into the handler is an
instance of class <code>Message</code>. The body of the message is available via
the <code>vertx.eventbus/body</code> function.</p>
<p>The return value of <code>on-message</code> is a unique handler id which
can used later to unregister the handler.</p>
<p>When you register a handler on an address and you're in a cluster it
can take some time for the knowledge of that new handler to be
propagated across the entire cluster. If you want to be notified when
that has completed you can optionally specify a function to the
<code>on-message</code> function as the third argument. This function will then
be called once the information has reached all nodes of the
cluster. E.g. :</p>
<pre class="prettyprint">(eb/on-message "test.address" my-handler
(fn [err]
(println "Yippee! The handler info has been propagated across the cluster")))
</pre>
<p>To unregister a handler it's just as straightforward. You simply call
<code>unregister-handler</code> passing in the id of the handler:</p>
<pre class="prettyprint">(eb/unregister-handler "test.address" id)
</pre>
<p>As with registering, when you unregister a handler and you're in a
cluster it can also take some time for the knowledge of that
unregistration to be propagated across the entire to cluster. If you
want to be notified when that has completed you can optionally specify
another function to the <code>unregister-handler</code> method:</p>
<pre class="prettyprint">(eb/unregister-handler "test.address" id
(fn [err]
(println "Yippee! The handler unregister has been propagated across the cluster")))
</pre>
<p>If you want your handler to live for the full lifetime of your
verticle there is no need to unregister it explicitly - vert.x will
automatically unregister any handlers when the verticle is stopped.</p>
<h3 id="publishing-messages">Publishing messages</h3><br/>
<p>Publishing a message is also trivially easy. Just publish it
specifying the address, for example:</p>
<pre class="prettyprint">(eb/publish "test.address" "hello world")
</pre>
<p>That message will then be delivered to all handlers registered against
the address "test.address".</p>
<h3 id="sending-messages">Sending messages</h3><br/>
<p>Sending a message will result in only one handler registered at the
address receiving the message. This is the point to point messaging
pattern. The handler is chosen in a non strict round-robin fashion.</p>
<pre class="prettyprint">(eb/send "test.address" "hello world")
</pre>
<h3 id="replying-to-messages">Replying to messages</h3><br/>
<p>Sometimes after you send a message you want to receive a reply from
the recipient. This is known as the <em>request-response pattern</em>.</p>
<p>To do this you send a message, and specify a function as a reply
handler. When the receiver receives the message, it can use the
<code>vertx.eventbus/reply</code> function to send a reply.</p>
<p>When this function is invoked it causes a reply to be sent back to the
sender where the reply handler is invoked. An example will make this
clear:</p>
<p>The receiver:</p>
<pre class="prettyprint">(eb/on-message "test.address"
(fn [message]
(println "I received a message" (eb/body message))
;; Do some stuff...
;; Now reply to it
(eb/reply message "This is a reply")))
</pre>
<p>The sender:</p>
<pre class="prettyprint">(eb/send "test.address" "This is a message"
(fn [reply-msg]
(println "I received a reply" (eb/body reply-msg))))
</pre>
<p>It is legal also to send an empty reply or null reply.</p>
<p>The replies themselves can also be replied to so you can create a
dialog between two different verticles consisting of multiple rounds.</p>
<h4 id="specifying-timeouts-for-replies">Specifying timeouts for replies</h4><br/>
<p>If you send a message specifying a reply handler, and the reply never
comes, then, by default, you'll be left with a handler that never gets
unregistered.</p>
<p>To remedy this you can also specify a timeout in ms and a two-arity
reply handler function. If a reply is received before timeout your
handler will be called with the message as the second parameter,
but if no reply is received before timeout, the handler will be
automatically unregistered and your handler will be called with an
exception-map as the first parameter you can deal with it in your code.</p>
<p>Here's an example:</p>
<pre class="prettyprint">(eb/send "test.address" "This is a message" 1000
(fn [err m]
(if err
(println "No reply was received before the 1 second timeout!")
(println "I received a reply" m))))
</pre>
<p>If the send times out, first parameter to the handler function will be
an exception map of the form:</p>
<pre class="prettyprint">{:type :TIMEOUT
:message "Timed out waiting for reply"
:basis the-ReplyException-object}
</pre>
<p>You can also set a default timeout on the event bus itself - this
timeout will be used if you are using the <code>send</code> function without a
timeout. The default value of the default timeout is <code>-1</code> which means
that reply handlers will never timeout (this is for backward
compatibility reasons with earlier versions of Vert.x). Note that when
using the <code>send</code> function without a timeout, your handler will never
be passed an exception-map when a timeout occurs.</p>
<pre class="prettyprint">(eb/set-default-reply-timeout! 5000)
</pre>
<p>When replying to messages you can also provide a timeout and a
two-arity reply handler function to get replies to the replies within a
timeout. The API used is similar to before:</p>
<pre class="prettyprint">(eb/on-message "test.address"
(fn [m]
(eb/reply "This is a reply" 1000
(fn [err m]
(if err
(println "No reply was received before the 1 second timeout!")
(println "I received a reply" m))))))
</pre>
<h4 id="getting-notified-of-reply-failures">Getting notified of reply failures</h4><br/>
<p>If you send a message with a timeout and result handler function, and
there are no handlers available to send the message to, the handler
function will be called with an exception-map containing <code>:type
:NO_HANDLERS</code>.</p>
<p>If you send a message with a timeout and result handler, and the
recipent of the message responds by calling <code>vertx.eventbus/fail</code>, the
handler function will be called with an exception map of the form:</p>
<pre class="prettyprint">{:type :RECIPIENT_FAILURE
:message "an application specific error message"
:code an-application-specific-int-code
:basis the-ReplyException-object}
</pre>
<p>For example:</p>
<pre class="prettyprint">(eb/on-message "test.address"
(fn [m]
(eb/fail 123 "Not enough aardvarks")))
(eb/send "test.address" "This is a message" 1000
(fn [err m]
(if err
(do
(println "Failure type:" (:type err))
(println "Failure code:" (:code err))
(println "Failure message: (:message err)))
(println "I received a reply" m))))
</pre>
<h3 id="message-types">Message types</h3><br/>
<p>The message you send can be any of the following types:</p>
<ul>
<li>Integer</li>
<li>Long</li>
<li>Short</li>
<li>clojure.lang.BigInt - will be converted to a Long</li>
<li>Float</li>
<li>Double</li>
<li>java.math.BigDecimal - will be converted to a double</li>
<li>clojure.lang.Ratio - will be converted to a double</li>
<li>String</li>
<li>Boolean</li>
<li>clojure.lang.Seqable (includes clojure lists, vectors, sets) - converted to a JSON array </li>
<li>map - converted to a JSON map</li>
<li>byte[]</li>
<li>Vert.x Buffer</li>
</ul>
<p>Vert.x buffers are copied before delivery if they are delivered in the
same JVM, so different verticles can't access the exact same object
instance.</p>
<p>Here are some more examples:</p>
<p>Send some numbers:
(eb/send "test.address" 1234)
(eb/send "test.address" 22/7)
(eb/send "test.address" 1N)</p>
<p>Send a boolean:</p>
<pre class="prettyprint">(eb/send "test.address" true)
</pre>
<p>Send a map (will be converted to a JSON object):</p>
<pre class="prettyprint">(eb/send "test.address" {:name "Tim"
:address "The Moon"
:age 457})
</pre>
<p>Send a vector (will be converted to a JSON array):</p>
<pre class="prettyprint">(eb/send "test.address" ["a" :b 0xC])
</pre>
<p><code>nil</code> messages can also be sent:</p>
<pre class="prettyprint">(eb/send "test.address" nil)
</pre>
<p>It's a good convention to have your verticles communicating using
JSON - this is because JSON is easy to generate and parse for all the
languages that Vert.x supports.</p>
<h2 id="distributed-event-bus">Distributed event bus</h2><br/>
<p>To make each Vert.x instance on your network participate on the same
event bus, start each Vert.x instance with the <code>-cluster</code> command line
switch.</p>
<p>See the chapter in the main manual on
<a href="manual.html#running-vertx"><em>running Vert.x</em></a> for more information on
this.</p>
<p>Once you've done that, any Vert.x instances started in cluster mode
will merge to form a distributed event bus.</p>
<h1 id="shared-data">Shared Data</h1><br/>
<p>Sometimes it makes sense to allow different verticles instances to
share data in a safe way. Vert.x allows simple <em>Map</em> and <em>Set</em> data
structures to be shared between verticles. </p>
<p>There is a caveat: Vert.x ensures that objects are copied where
appropriate on insertion to prevent other verticles having access to
the same instance which could lead to race conditions.</p>
<p>Currently data can only be shared between verticles in the <em>same
vert.x instance</em>. In later versions of vert.x we aim to extend this to
allow data to be shared by all vert.x instances in the cluster. </p>
<p>All Clojure verticles deployed in a single vert.x instance share the
same Clojure runtime, so you can use the Clojure's existing mechanisms
for concurrent coordination. If you have a mix of verticles from other
languages in the same vert.x instance and need to share data, you will
need to use the vert.x shared data mechanisms.</p>
<h2 id="shared-maps">Shared Maps</h2><br/>
<p>To use a shared map to share data between verticles first get a
reference to the map, and then we just use map operations to put and
get the data:</p>
<pre class="prettyprint">(require '[vertx.shareddata :as sd])
(-> (sd/get-map "demo.mymap")
(sd/put! "some-key" "some-value"))
</pre>
<p>And then, in a different verticle:</p>
<pre class="prettyprint">(println "value of some-key is"
(-> (sd/get-map "demo.mymap")
(get "some-key")))
</pre>
<h2 id="shared-sets">Shared Sets</h2><br/>
<p>To use a shared set to share data between verticles first get a
reference to the set:</p>
<pre class="prettyprint">(-> (sd/get-set "demo.myset")
(sd/add! "some-value"))
</pre>
<p>And then, in a different verticle:</p>
<pre class="prettyprint">(println "does the set contain some-value?"
(-> (sd/get-set "demo.myset")
(contains? "some-key")))
</pre>
<p>The <code>vertx.shareddata</code> namespace provides a few functions for mutating
its maps and sets (<code>add!</code>, <code>put!</code>, <code>remove!</code>, and <code>clear!</code>). For
retrieving values from the maps/sets, you can use the built-in clojure
functions (<code>get</code>, <code>contains?</code>, <code>count</code>, <code>empty?</code>, etc.).</p>
<p>As a convenience, <code>add!</code>, <code>put!</code>, <code>remove!</code>, and <code>clear!</code> can be given
a string or keyword name for a set or map instead of the collection
object and will look it up.</p>
<p>Currently, no conversion is performed on keys
or values placed in shared data. The onus is on you to make sure you
are storing a type that will be readable in any other verticles that
access it.</p>
<h1 id="buffers">Buffers</h1><br/>
<p>Most data in vert.x is shuffled around using instances of
<code>org.vertx.java.core.buffer.Buffer</code>, which are provided and
manipulated by functions in the <code>vertx.buffer</code> namespace.</p>
<p>A Buffer represents a sequence of zero or more bytes that can be
written to or read from, and which expands automatically as necessary
to accomodate any bytes written to it.</p>
<h2 id="creating-buffers">Creating Buffers</h2><br/>
<p>Create an empty buffer:</p>
<pre class="prettyprint">(require '[vertx.buffer :as buf])
(buf/buffer)
</pre>
<p>Create a buffer from a String. The String will be encoded in the
buffer using UTF-8:</p>
<pre class="prettyprint">(buf/buffer "some-string")
</pre>
<p>Create a buffer from a String. The String will be encoded using the
specified encoding, e.g:</p>
<pre class="prettyprint">(buf/buffer "some-string" "UTF-16")
</pre>
<p>Create a buffer with an initial size hint. If you know your buffer
will have a certain amount of data written to it you can create the
buffer and specify this size. This makes the buffer initially allocate
that much memory and is more efficient than the buffer automatically
resizing multiple times as data is written to it:</p>
<pre class="prettyprint">(buf/buffer 100000)
</pre>
<p>Note that buffers created this way <em>are empty</em>. It does not create a
buffer filled with zeros up to the specified size.</p>
<p>Also note that buffers are <em>mutable</em>. To emphasize that, we recommend
naming any vars that point to buffers with a trailing <code>!</code>. Example:</p>
<pre class="prettyprint">(let [some-buf! (buf/buffer)
;;mutate away!
)
</pre>
<h2 id="writing-to-a-buffer">Writing to a Buffer</h2><br/>
<p>There are two ways to write to a buffer: appending, and random
access. In either case buffers will always expand automatically to
encompass the bytes. It's not possible to write outside the bounds of
the buffer.</p>
<h3 id="appending-to-a-buffer">Appending to a Buffer</h3><br/>
<p>To append to a buffer, you use <code>vertx.buffer/append!</code>. <code>append!</code> can
append other buffers, Bytes, byte[]'s, Doubles, BigDecimals (as
Doubles), Ratios (as Doubles), Floats, Integers, Longs, BigInts (as
Longs), Shorts, and Strings.</p>
<p>The return value of <code>append!</code> is the buffer itself, so calls can be
chained:</p>
<pre class="prettyprint">(-> (buf/buffer)
(buf/append! 100)
(buf/append! "hi") ;; as UTF-8
(buf/append! "hello" "UTF-16")
(buf/append! some-other-buffer))
</pre>
<h3 id="random-access-buffer-writes">Random access buffer writes</h3><br/>
<p>You can also write into the buffer at a specific index, by using
<code>vertx.buffer/set!</code>. <code>set!</code> can handle the same types as <code>append!</code>.
<code>set!</code> takes an index as the first argument - this represents the
position in the buffer where to start writing the data.</p>
<p>The buffer will always expand as necessary to accomodate the data.</p>
<p>The return value of <code>append!</code> is the buffer itself, so calls can be
chained:</p>
<pre class="prettyprint">(-> (buf/buffer)
(buf/set! 0 100)
(buf/set! 23 "hi") ;; as UTF-8
(buf/set! 99 "hello" "UTF-16")
(buf/set! 2000 some-other-buffer))
</pre>
<h2 id="reading-from-a-buffer">Reading from a Buffer</h2><br/>
<p>Data is read from a buffer using the <code>vertx.buffer/get-XXX</code>
functions. Get functions exist for Buffer, byte, int, long, double,
float, short, byte[], and String. The first argument to these methods
is an index in the buffer from where to get the data.</p>
<pre class="prettyprint">(buf/get-byte a-buf 100) ;; Get a byte from pos 100 in buffer
(buf/get-float a-buf 100) ;; Get a float from pos 100
(buf/get-string a-buf 100) ;; Get a float from pos 100 as UTF-8
(buf/get-string a-buf 100 "UTF-16") ;; Get a float from pos 100 as UTF-8
(buf/get-buffer a-buf 100 110) ;; Get 10 bytes as a new buffer starting at position 100
</pre>
<h1 id="delayed-and-periodic-tasks">Delayed and Periodic Tasks</h1><br/>
<p>It's very common in vert.x to want to perform an action after a delay,
or periodically.</p>
<p>In standard verticles you can't just make the thread sleep to
introduce a delay, as that will block the event loop thread.</p>
<p>Instead you use vert.x timers. Timers can be <em>one-shot</em> or
<em>periodic</em>. We'll discuss both.</p>
<h2 id="one-shot-timers">One-shot Timers</h2><br/>
<p>A one shot timer calls an event handler after a certain delay,
expressed in milliseconds.</p>
<p>To set a timer to fire once you use the <code>vertx.core/timer</code> macro,
passing in the delay and specifying a handler body which will be
called after the delay:</p>
<pre class="prettyprint">(require '[vertx.core :as core])
(core/timer 1000
(println "And one second later this is printed"))
(println "First this is printed")
</pre>
<p>The return value of the function is a unique timer id. You can use this