├── .gitignore ├── CONTRIBUTING.md ├── Makefile ├── README.html ├── README.md ├── doc ├── BENCHMARK-README.html ├── BENCHMARK1.html ├── BENCHMARK1.md ├── CHANGES.html ├── CHANGES.md └── LICENSE ├── ebin └── empty ├── etc ├── bench │ ├── Makefile │ ├── README.html │ ├── README.md │ ├── bench.config │ ├── bench.erl │ └── benchstart ├── ct_default.css ├── grep ├── include.mk ├── markdown.lua ├── markedoc.sed ├── replace └── test │ ├── basics_SUITE.erl │ ├── depr │ ├── Makefile │ ├── erlunit │ │ ├── erlunit.erl │ │ └── erlunit.hrl │ ├── test1.erl │ ├── test2.erl │ ├── test3.erl │ └── test4.erl │ ├── dialyzer.mk │ ├── environment_SUITE.erl │ └── maketest.mk ├── examples ├── Makefile ├── hello.erl ├── hello_plus.erl ├── hello_pre3.erl ├── parallel.erl ├── parallel_pre3.erl └── voter.erl ├── include ├── erlvolt.hrl └── erlvolt_wire.hrl ├── priv └── empty └── src ├── Makefile ├── erlvolt.app.src ├── erlvolt.erl ├── erlvolt_app.erl ├── erlvolt_conn.erl ├── erlvolt_conn_mgr.erl ├── erlvolt_internal.hrl ├── erlvolt_profiler.erl ├── erlvolt_sup.erl └── erlvolt_wire.erl /.gitignore: -------------------------------------------------------------------------------- 1 | *.beam 2 | *.dump 3 | *~ 4 | .DS_Store 5 | *.orig 6 | *.rej 7 | log 8 | jquery* 9 | .*.html 10 | readme.edoc 11 | changes.edoc 12 | ebin/*.beam 13 | ebin/*.app 14 | etc/test/*.beam 15 | etc/test/*.html 16 | etc/test/ct_run* 17 | etc/test/variables-ct* 18 | etc/test/ct_default.css 19 | bench.log 20 | bench.totals 21 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in contributing. VoltDB uses GitHub to manage reviews of pull requests. We welcome your contributions to VoltDB or to any of the related libraries and tools. 4 | 5 | VoltDB uses the standard github workflow, meaning we make use of forking and pull requests. 6 | 7 | * If you have a trivial fix or improvement, go ahead and create a pull request. 8 | 9 | * If you are interested in contributing something more involved, feel free to discuss your ideas in [VoltDB Public](http://chat.voltdb.com/) on Slack. 10 | 11 | ## Contributor License Agreement 12 | 13 | In order to contribute code to VoltDB, you must first sign the [VoltDB Contributor License Agreement (CLA)](https://www.voltdb.com/contributor-license-agreement/) and email an image or PDF of the document including your hand-written signature to [support@voltdb.com](mailto:support@voltdb.com). VoltDB will sign and return the final copy of the agreement for your records. 14 | 15 | ## How to submit code 16 | 17 | The workflow is essentially the following: 18 | 19 | 1. Fork the VoltDB project 20 | 2. Make a branch. Commit your changes to this branch. (See note below) 21 | 3. Issue a pull request on the VoltDB repository. 22 | 23 | Once you have signed the CLA, a VoltDB engineer will review your pull request. 24 | 25 | Note: 26 | 27 | It will be easier to keep your work merge-able (conflict-free) if you don't work directly on your master branch in your VoltDB fork. Rather, keep your master branch in sync with the VoltDB repository and apply your changes on a branch of your fork. 28 | 29 | For further reading: 30 | 31 | * [How to fork a GitHub repository](https://help.github.com/articles/fork-a-repo) 32 | * [Using pull requests](https://help.github.com/articles/using-pull-requests/) 33 | 34 | ## Additional Resources 35 | 36 | * [VoltDB Wiki](https://github.com/VoltDB/voltdb/wiki) on Github 37 | * [VoltDB Public](http://chat.voltdb.com/) on Slack 38 | * [VoltDB Community Forum](https://forum.voltdb.com/) 39 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ###-------------------------------------------------------------------------### 2 | ### File : Makefile ### 3 | ### Version : 0.3/beta ### 4 | ### Description : Erlang VoltDB driver main build and run rules ### 5 | ### Copyright : VoltDB, LLC - http://www.voltdb.com ### 6 | ### Production : Eonblast Corporation - http://www.eonblast.com ### 7 | ### Author : H. Diedrich ### 8 | ### License : MIT ### 9 | ### Created : 17 Apr 2010 ### 10 | ### Changed : 06 Feb 2013 ### 11 | ###-------------------------------------------------------------------------### 12 | ### ### 13 | ### This driver is being contributed to VoltDB by Eonblast Corporation. ### 14 | ### ### 15 | ###-------------------------------------------------------------------------### 16 | ### ### 17 | ### Erlvolt 0.3/beta - Erlang VoltDB client API. ### 18 | ### ### 19 | ### This file is part of VoltDB. ### 20 | ### Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com ### 21 | ### Author H. Diedrich http://www.eonblast.com ### 22 | ### ### 23 | ### Permission is hereby granted, free of charge, to any person obtaining ### 24 | ### a copy of this software and associated documentation files (the ### 25 | ### "Software"), to deal in the Software without restriction, including ### 26 | ### without limitation the rights to use, copy, modify, merge, publish, ### 27 | ### distribute, sublicense, and/or sell copies of the Software, and to ### 28 | ### permit persons to whom the Software is furnished to do so, subject to ### 29 | ### the following conditions: ### 30 | ### ### 31 | ### The above copyright notice and this permission notice shall be ### 32 | ### included in all copies or substantial portions of the Software. ### 33 | ### ### 34 | ### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ### 35 | ### EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ### 36 | ### MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ### 37 | ### IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR ### 38 | ### OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ### 39 | ### ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ### 40 | ### OTHER DEALINGS IN THE SOFTWARE. ### 41 | ### ### 42 | ###-------------------------------------------------------------------------### 43 | ### ### 44 | ### USAGE ### 45 | ### ### 46 | ### You can run a sample using the 'Hello' tutorial-server discussed ### 47 | ### in the VoltDB manual and present in every VoltDB distribution. ### 48 | ### ### 49 | ### Start that server from your voltdb installation with: ### 50 | ### ### 51 | ### $ cd voltdb/doc/tutorial/helloworld ### 52 | ### $ ./run.sh ### 53 | ### ### 54 | ### Then run the hello world example, using make from the driver root: ### 55 | ### ### 56 | ### $ make hello ### 57 | ### or ### 58 | ### $ make ### 59 | ### $ cd examples ### 60 | ### $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl ### 61 | ### $ erl -pa ../ebin -s hello_plus run -s init stop -noshell ### 62 | ### ### 63 | ### You will see this response, 'Hello, world!' in Swedish: ### 64 | ### ### 65 | ### Hej världen! ### 66 | ### ### 67 | ### The hello world source is found in examples/hello_plus.erl ### 68 | ### ### 69 | ###-------------------------------------------------------------------------### 70 | ### ### 71 | ### See README.md or .html for instructions, examples/ for more examples. ### 72 | ### See doc/BENCHMARKS.md or .html for a description of driver benchmarks. ### 73 | ### ### 74 | ### For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or ### 75 | ### online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. ### 76 | ### ### 77 | ###-------------------------------------------------------------------------### 78 | 79 | LIBDIR=$(shell erl -eval 'io:format("~s~n", [code:lib_dir()])' -s init stop -noshell) 80 | VERSION=0.3.3 81 | PKGNAME=erlvolt 82 | APP_NAME=erlvolt 83 | 84 | MODULES=$(shell ls -1 src/*.erl | awk -F[/.] '{ print $$2 }' | sed '$$q;s/$$/,/g') 85 | MAKETIME=$(shell date) 86 | LESSVERB=--no-print-directory 87 | 88 | # 89 | # Main Build, Hello, Bench 90 | # 91 | 92 | # Build the driver, with debug info compiled in 93 | all: app 94 | @(cd src; $(MAKE) $(LESSVERB) DEBUG=true) 95 | @(cd etc/bench; $(MAKE) $(LESSVERB) DEBUG=true) 96 | 97 | # Hello 'redirects' to a robuster hello world 98 | hello: hello-plus 99 | # This executed examples/hello_plus.erl. 100 | # Simplest source see examples/hello.erl, 101 | # 'make hello-barebones' executes that. 102 | 103 | 104 | # 105 | # Driver compilation variants 106 | # 107 | 108 | fast: app 109 | @(cd src;$(MAKE) $(LESSVERB) NATIVE=true) 110 | @(cd etc/bench; $(MAKE) $(LESSVERB) NATIVE=true) 111 | 112 | profile: app 113 | @(cd src;$(MAKE) $(LESSVERB) PROFILE=true NATIVE=true) 114 | @(cd etc/bench; $(MAKE) $(LESSVERB) PROFILE=true NATIVE=true) 115 | 116 | profile-debug: app 117 | @(cd src;$(MAKE) $(LESSVERB) PROFILE=true DEBUG=true) 118 | @(cd etc/bench;$(MAKE) $(LESSVERB) PROFILE=true DEBUG=true) 119 | 120 | app: ebin/$(PKGNAME).app 121 | 122 | ebin/$(PKGNAME).app: src/$(PKGNAME).app.src 123 | @mkdir -p ebin 124 | @sed -e 's/modules, \[\]/{modules, [$(MODULES)]}/;s/%MAKETIME%/$(MAKETIME)/' < $< > $@ 125 | 126 | # 127 | # Hello variants 128 | # 129 | 130 | # A slightly more robust hello world: hello_plus.erl 131 | hello-plus: all 132 | @(cd examples; $(MAKE) $(LESSVERB) hello-plus DEBUG=true) 133 | erl -pa ./ebin -s hello_plus run -s init stop -noshell 134 | 135 | # A simpler hello.erl 136 | hello-barebones: all 137 | @(cd examples; $(MAKE) $(LESSVERB) hello DEBUG=true) 138 | erl -pa ./ebin -s hello run -s init stop -noshell 139 | 140 | # A simpler hello.erl 141 | hello-barebones-pre3: all 142 | @(cd examples; $(MAKE) $(LESSVERB) hello-barebones-pre3 DEBUG=true) 143 | erl -pa ./ebin -s hello_pre3 run -s init stop -noshell 144 | 145 | # A more Erlang hello world with many processes. 146 | parallel: all 147 | @(cd examples; $(MAKE) $(LESSVERB) parallel DEBUG=true) 148 | erl -pa ./ebin -s parallel run -s init stop -noshell 149 | 150 | # A more Erlang hello world with many processes, for VoltDB pre 3.0. 151 | # The only difference is a switch in the column order in the hello sample. 152 | parallel-pre3: all 153 | @(cd examples; $(MAKE) $(LESSVERB) parallel-pre3 DEBUG=true) 154 | erl -pa ./ebin -s parallel_pre3 run -s init stop -noshell 155 | 156 | 157 | # 158 | # Voter sample 159 | # 160 | 161 | voter: all 162 | @(cd examples; $(MAKE) $(LESSVERB) voter DEBUG=true) 163 | erl -pa ./ebin -s voter run -s init stop -noshell 164 | 165 | # 166 | # Benchmark variants 167 | # 168 | 169 | bench: bench-vsd 170 | # 'make clean fast bench' for faster, HiPE-compiled beams. 171 | # 'make clean profile bench' for rolling stats during bench. 172 | 173 | benches: bench-vsm bench-vsd bench-vbm bench-vbd 174 | 175 | ### Voter steady managed (reference 13,000 T/sec/core) 176 | bench-vsm: 177 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vsm NATIVE=true) 178 | 179 | ### Voter steady direct (reference 21,000 T/sec/core) 180 | bench-vsd: 181 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vsd NATIVE=true) 182 | 183 | ### Voter bursts managed (reference 10,000 T/sec/core) 184 | bench-vbm: 185 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vbm NATIVE=true) 186 | 187 | ### Voter bursts direct (reference 16,000 T/sec/core) 188 | bench-vbd: 189 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vbd NATIVE=true) 190 | 191 | ### Hello steady direct (reference 21,000 T/sec/core) 192 | bench-hsd: 193 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-hsd NATIVE=true) 194 | 195 | ### Multi-VM benchmark (VSD) 196 | # optional parameters (default): 197 | # VMS (5) # of virtual machines (erl Erlang emulators) started 198 | # CORES (1) # number of cores used per VM (erl parameter +S) 199 | # CALLS (100000) # of transactions per VM for the benchmark 200 | # SPAWN (100) # of parallel ('steady') workers = max server load 201 | # use e.g. make bench-mvm CALLS=1000000 202 | bench-mvm: 203 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-mvm) 204 | 205 | bench-help: 206 | @(cd etc/bench; $(MAKE) $(LESSVERB) bench-help) 207 | 208 | # 209 | # Doc Creation 210 | # 211 | 212 | # Create doc HTML from source comments 213 | # IF THIS FAILS, IT'S THE -E 214 | docs: clean-docs 215 | @echo make docs 216 | sed -E -f etc/markedoc.sed README.md > doc/readme.edoc 217 | sed -E -f etc/markedoc.sed CHANGES.md > doc/changes.edoc 218 | erl -noshell -run edoc_run application "'erlvolt'" '"."' '[{def,{vsn,""}},{stylesheet, "erlvolt-style.css"}]' 219 | LANG=C sed -E -i "" -e "s/ 2 | 3 | 4 | 5 | VoltDB Blog: 877,000 TPS with Erlang and VoltDB  6 | 7 | 8 | 9 | 10 |

VoltDB Blog: 877,000 TPS with Erlang and VoltDB 

11 | 12 |

Henning Diedrich - 6 Feb 2013

13 | 14 |

Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.

15 | 16 |

I am Henning Diedrich [1], CEO of Eonblast Corporation [2] a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB [3] and Erlang [4].

17 | 18 |

The Driver

19 | 20 |

I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand [5] what a pain it was to try to scale MySQL and found VoltDB [3] uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact [6].

21 | 22 |

I had also looked for a better language than Java for programming servers and for that, Erlang [7] had caught my attention. To be able to use them together [8], I started creating the Erlang driver for VoltDB [9].

23 | 24 |

Work for this started three years ago and I donated a first version of the driver [10] to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived [11].

25 | 26 |

The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3 [12]. It builds on and incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang MySQL driver, Emysql [13]. The connection pooling and call queueing is modeled after the ones used in that reliable workhorse, originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.

27 | 28 |

To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark [14] I did for VoltDB a while ago. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.

29 | 30 |

The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a synchronous receive (this, of course, does not block all your other processes) or goes on to to use its time as it pleases, should you choose the asynchronous mode. The answer from the server arrives in your processes' mailbox.  (Note, synchronous in this context, when looking at the driver. The call to the VoltDB server is still an asynchronous call. The driver simply has your process wait in a receive block.)

31 | 32 |

There are many options that you can use. E.g. the monitored mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can fire and forget, for writes where you don't care to hear that they succeeded. Or blowout if you don't even care to hear about failure.

33 | 34 |

The Benchmark Application

35 | 36 |

The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the examples/voter directory of your VoltDB installation.

37 | 38 |

The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestants, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query. (In VoltDB parlance, ad-hoc queries are normal queries that are not pre-formulated in a stored procedure.)

39 | 40 |

The benchmark source is under etc/bench [15] of the driver home directory, where you'll also find a detailed README.md that explains the multiple ways to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically:

41 | 42 |

    $ git clone git://github.com/VoltDB/voltdb.git voltdb 43 |     $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt 44 |     $ cd voltdb/examples/voter && ./run.sh & 45 |     $ cd && cd erlvolt && make clean all bench

46 | 47 |

That should give you a screen like this:

48 | 49 |
    metal:~ hd$ cd voltdb-3-com/examples/voter && ./run.sh &
 50 |     [1] 10817
 51 |     metal:~ hd$ Initializing VoltDB...
 52 | 
 53 |      _    __      ____  ____  ____ 
 54 |     | |  / /___  / / /_/ __ \/ __ )
 55 |     | | / / __ \/ / __/ / / / __  |
 56 |     | |/ / /_/ / / /_/ /_/ / /_/ / 
 57 |     |___/\____/_/\__/_____/_____/
 58 | 
 59 |     --------------------------------
 60 | 
 61 |     Build: 3.0 voltdb-3.0-95-gfffab2b Community Edition
 62 |     Connecting to VoltDB cluster as the leader...
 63 |     Initializing initiator ID: 0, SiteID: 0:5
 64 |     WARN: Running without redundancy (k=0) is not recommended for production use.
 65 |     Server completed initialization.
 66 | 
 67 | 
 68 |     metal:erlvolt hd$ cd && cd erlvolt && make clean all bench
 69 |     clean
 70 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt.erl
 71 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_app.erl
 72 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_conn.erl
 73 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_conn_mgr.erl
 74 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_profiler.erl
 75 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_sup.erl
 76 |     erlc -W -I ../include  +debug_info -o ../ebin erlvolt_wire.erl
 77 |     erlc -W -I ../../include  +debug_info -o ../../ebin bench.erl
 78 | 
 79 | 
 80 |     Erlvolt Bench 0.9 (client 'VSD')
 81 |     -------------------------------------------------------------------------------------------------------------------------------------
 82 |     Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
 83 |     Hosts: localhost:21212 
 84 |     connect ...
 85 |     preparation ...
 86 |     Start at: 2013-02-06 18:56:20 .....................
 87 |     Starting: 2013-02-06 18:56:20
 88 |     calls ... ..................................
 89 |     cool down ... 
 90 |     check writes ... ok
 91 |     results ...  votes:     100,000 (6 contestants)
 92 |     .....Edwina Burnam:      16,817
 93 |     ....Jessie Alloway:      16,808
 94 |     ...Tabatha Gehling:      16,669
 95 |     .....Alana Bregman:      16,613
 96 |     ....Jessie Eichman:      16,556
 97 |     ......Kelly Clauss:      16,537
 98 |     close pool ...
 99 |     Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
100 |     -------------------------------------------------------------------------------------------------------------------------------------
101 | 
102 |     Client 'VSD' overall: 14,357 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 6.965sec 
103 |     Erlvolt 0.3.3, bench started 2013-02-06 18:56:20, ended 2013-02-06 18:56:26, database: +100,000 new votes
104 |     [++++++++++++++]
105 | 
106 | 107 | 108 | 109 |

For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.md [16], or verbatim doc/BENCHMARK-README.html, in your driver home folder.

110 | 111 | 112 |

The Benchmark Results

113 | 114 |

When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of 26,500 transactions per second (TPS) and more per one core. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of 260,000 transactions per second per machine. (CPU specs see below.)

115 | 116 |

Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a cluster total of 877,519 TPS.

117 | 118 |

Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters would reflect the network limitations of the EC2 cloud, even for the bigger cluster instances [17] where the hope would be that a benchmark would not end up network-bound.

119 | 120 |

Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' [18] when the server does not allow further requests for being at capacity. However, the fastest benchmarks resulted when not overloading the server.

121 | 122 | 123 |

The Environment

124 | 125 |

I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page [17]:

126 | 127 |

Cluster Compute Eight Extra Large Instance (cc2.8xlarge)

128 | 129 | 136 | 137 |

These nodes were configured with:

138 | 139 | 145 | 146 |

On advice from VoltDB, each of the five server nodes was set to six partitions, so I had 30 partitions across the database cluster.

147 | 148 |

This benchmark would perform the same on the free Community Edition of Volt 3.0.

149 | 150 | 151 |

The Transactions

152 | 153 |

The clients "firehose" the VoltDB cluster by calling Voter's vote() stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations:

154 | 155 | 161 | 162 |

On top of this, each insert also triggers an update to two different materialized views.

163 | 164 |

Here are the actual queries that define the used stored procedures [19]:

165 | 166 |
// Checks if the vote is for a valid contestant
167 | SELECT contestant_number FROM contestants WHERE contestant_number = ?;
168 | 
169 | // Checks if the voter has exceeded their allowed number of votes
170 | SELECT num_votes FROM v_votes_by_phone_number WHERE phone_number = ?;
171 | 
172 | // Checks an area code to retrieve the corresponding state
173 | SELECT state FROM area_code_state WHERE area_code = ?;
174 | 
175 | // Records a vote
176 | INSERT INTO votes (phone_number, state, contestant_number) VALUES (?, ?, ?);
177 | 
178 | 179 |

Consequently, the 877,000 TPS performed 3.5 million SQL operations per second, i.e. three selects and one insert.

180 | 181 | 182 |

Observations & Notes

183 | 184 |

The most important number from this, to my mind, is the 26,500 transactions per second per CPU core that I saw, which translates into 100,000 operations. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB client side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there. Note that many machines will show a significantly higher performance profile than EC2 instances.

185 | 186 |

We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently.

187 | 188 |

As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from VoltDB [20]. The README.md [21] of the driver, and of the benchmark [16] have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try the Eonblast Erlvolt repo at git [22]. The free VoltDB community edition is also on github [23].

189 | 190 |

[1] Author on Twitter: https://twitter.com/hdiedrich
191 | [2] Eonblast: http://www.eonblast.com
192 | [3] VoltDB: http://www.voltdb.com
193 | [4] Erlang: http://www.erlang.org
194 | [5] Deepolis: http://www.deepolis.com
195 | [6] Choosing the Best Database For a Game: http://voltdb.com/dig-deeper/webinars.php
196 | [7] Why Erlang? http://www.slideshare.net/eonblast/why-erlang-gdc-online-2012
197 | [8] Erlang and VoltDB: http://www.slideshare.net/eonblast/voltdb-and-erlang-tech-planet-2012
198 | [9] Erlvolt 0.2: https://github.com/Eonblast/Erlvolt/tree/01b304f8975c2168be105c1b9c972386264c0a4e
199 | [10] http://blog.voltdb.com/community-contributions-erlang-client-library/
200 | [11] Erlvolt 0.3: https://github.com/VoltDB/voltdb-client-erlang
201 | [12] VoltDB 3: http://blog.voltdb.com/introducing-voltdb-3-0/
202 | [13] Emysql: https://github.com/Eonblast/Emysql
203 | [14] 695k with Node.js: http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/
204 | [15] bench.erl: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench/bench.erl
205 | [16] Bench README: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench
206 | [17] Amazon EC2 Cluster Instances: http://aws.amazon.com/ec2/instance-types/
207 | [18] Backpressure: http://voltdb.com/docs/UsingVoltDB/DesignAppLogic.php
208 | [19] Query Source: https://github.com/VoltDB/voltdb/blob/master/examples/voter/src/voter/procedures/Vote.java
209 | [20] VoltDB Downloads: VoltDB http://voltdb.com/community/downloads.php
210 | [21] Driver README: https://github.com/VoltDB/voltdb-client-erlang
211 | [22] Erlvolt Development: https://github.com/Eonblast/Erlvolt
212 | [23] VoltDB Community Edition: https://github.com/VoltDB/voltdb

213 | 214 |

/hd 6 feb 13

215 | 216 | -------------------------------------------------------------------------------- /doc/BENCHMARK1.md: -------------------------------------------------------------------------------- 1 | VoltDB Blog: 877,000 TPS with Erlang and VoltDB  2 | =============================================== 3 | 4 | Henning Diedrich - 6 Feb 2013 5 | 6 | **Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.** 7 | 8 | I am Henning Diedrich [1], CEO of Eonblast Corporation [2] a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB [3] and Erlang [4]. 9 | 10 | The Driver 11 | -------------- 12 | 13 | I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand [5] what a pain it was to try to scale MySQL and found **VoltDB** [3] uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact [6]. 14 | 15 | I had also looked for a better language than Java for programming servers and for that, **Erlang** [7] had caught my attention. To be able to use them together [8], I started creating the Erlang driver for VoltDB [9]. 16 | 17 | Work for this started three years ago and I donated a first version of the driver [10] to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived [11]. 18 | 19 | The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3 [12]. It builds on and incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang **MySQL** driver, Emysql [13]. The connection pooling and call queueing is modeled after the ones used in that reliable workhorse, originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes. 20 | 21 | To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark [14] I did for VoltDB a while ago. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use. 22 | 23 | The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a *synchronous* receive (this, of course, does *not* block all your *other* processes) or goes on to to use its time as it pleases, should you choose the *asynchronous* mode. The answer from the server arrives in your processes' mailbox.  (Note, *synchronous* in this context, when looking at the driver. The call to the VoltDB server is still an asynchronous call. The driver simply has your process wait in a receive block.) 24 | 25 | There are many options that you can use. E.g. the *monitored* mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can *fire and forget*, for writes where you don't care to hear that they succeeded. Or *blowout* if you don't even care to hear about failure. 26 | 27 | The Benchmark Application 28 | ------------------------------------- 29 | 30 | The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the `examples/voter` directory of your *VoltDB* installation. 31 | 32 | The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestants, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query. (In VoltDB parlance, ad-hoc queries are normal queries that are not pre-formulated in a stored procedure.) 33 | 34 | The benchmark source is under etc/bench [15] of the *driver* home directory, where you'll also find a detailed README.md that explains the multiple ways to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically: 35 | 36 |     $ git clone git://github.com/VoltDB/voltdb.git voltdb 37 |     $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt 38 |     $ cd voltdb/examples/voter && ./run.sh & 39 |     $ cd && cd erlvolt && make clean all bench 40 | 41 | That should give you a screen like this: 42 | 43 | metal:~ hd$ cd voltdb-3-com/examples/voter && ./run.sh & 44 | [1] 10817 45 | metal:~ hd$ Initializing VoltDB... 46 | 47 | _ __ ____ ____ ____ 48 | | | / /___ / / /_/ __ \/ __ ) 49 | | | / / __ \/ / __/ / / / __ | 50 | | |/ / /_/ / / /_/ /_/ / /_/ / 51 | |___/\____/_/\__/_____/_____/ 52 | 53 | -------------------------------- 54 | 55 | Build: 3.0 voltdb-3.0-95-gfffab2b Community Edition 56 | Connecting to VoltDB cluster as the leader... 57 | Initializing initiator ID: 0, SiteID: 0:5 58 | WARN: Running without redundancy (k=0) is not recommended for production use. 59 | Server completed initialization. 60 | 61 | 62 | metal:erlvolt hd$ cd && cd erlvolt && make clean all bench 63 | clean 64 | erlc -W -I ../include +debug_info -o ../ebin erlvolt.erl 65 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_app.erl 66 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn.erl 67 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn_mgr.erl 68 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_profiler.erl 69 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_sup.erl 70 | erlc -W -I ../include +debug_info -o ../ebin erlvolt_wire.erl 71 | erlc -W -I ../../include +debug_info -o ../../ebin bench.erl 72 | 73 | 74 | Erlvolt Bench 0.9 (client 'VSD') 75 | ------------------------------------------------------------------------------------------------------------------------------------- 76 | Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec 77 | Hosts: localhost:21212 78 | connect ... 79 | preparation ... 80 | Start at: 2013-02-06 18:56:20 ..................... 81 | Starting: 2013-02-06 18:56:20 82 | calls ... .................................. 83 | cool down ... 84 | check writes ... ok 85 | results ... votes: 100,000 (6 contestants) 86 | .....Edwina Burnam: 16,817 87 | ....Jessie Alloway: 16,808 88 | ...Tabatha Gehling: 16,669 89 | .....Alana Bregman: 16,613 90 | ....Jessie Eichman: 16,556 91 | ......Kelly Clauss: 16,537 92 | close pool ... 93 | Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec 94 | ------------------------------------------------------------------------------------------------------------------------------------- 95 | 96 | Client 'VSD' overall: 14,357 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 6.965sec 97 | Erlvolt 0.3.3, bench started 2013-02-06 18:56:20, ended 2013-02-06 18:56:26, database: +100,000 new votes 98 | [++++++++++++++] 99 | 100 | 101 | 102 | For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.md [16], or verbatim doc/BENCHMARK-README.html, in your driver home folder. 103 | 104 | 105 | The Benchmark Results 106 | -------------------------------- 107 | 108 | When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of **26,500 transactions per second (TPS) and more per one core**. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of **260,000 transactions per second per machine**. (CPU specs see below.) 109 | 110 | Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a **cluster total of 877,519 TPS**. 111 | 112 | Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters would reflect the network limitations of the EC2 cloud, even for the bigger cluster instances [17] where the hope would be that a benchmark would not end up network-bound. 113 | 114 | Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' [18] when the server does not allow further requests for being at capacity. However, the fastest benchmarks resulted when not overloading the server. 115 | 116 | 117 | The Environment 118 | ----------------------- 119 | 120 | I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page [17]: 121 | 122 | ### Cluster Compute Eight Extra Large Instance (cc2.8xlarge) 123 | 124 | * 60.5 GiB of memory 125 | * 88 EC2 Compute Units (2 x Intel Xeon E5-2670, eight-core) 126 | * 3370 GB of instance storage 127 | * 64-bit platform 128 | * I/O Performance: Very High (10 Gigabit Ethernet) 129 | 130 | These nodes were configured with: 131 | 132 | * Ubuntu Server 12.04 LTS for Cluster Instances AMI 133 | * Oracle Java JDK 1.7 134 | * Erlang R15B03 135 | * VoltDB Enterprise Edition 3.0 RC 136 | 137 | On advice from VoltDB, each of the five server nodes was set to six partitions, so I had 30 partitions across the database cluster. 138 | 139 | This benchmark would perform the same on the free Community Edition of Volt 3.0. 140 | 141 | 142 | The Transactions 143 | ----------------------- 144 | 145 | The clients "firehose" the VoltDB cluster by calling Voter's `vote()` stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations: 146 | 147 | * It retrieves the caller's location (a `select`) 148 | * Verifies that the caller has not exceeded his/her vote maximum (a `select`) 149 | * Verifies that the caller was voting for a valid contestant (a `select`) 150 | * And if yes to all of the above, a vote is cast on behalf of that caller (an `insert`) 151 | 152 | On top of this, each `insert` also triggers an update to two different materialized views. 153 | 154 | Here are the actual queries that define the used stored procedures [19]: 155 | 156 | // Checks if the vote is for a valid contestant 157 | SELECT contestant_number FROM contestants WHERE contestant_number = ?; 158 | 159 | // Checks if the voter has exceeded their allowed number of votes 160 | SELECT num_votes FROM v_votes_by_phone_number WHERE phone_number = ?; 161 | 162 | // Checks an area code to retrieve the corresponding state 163 | SELECT state FROM area_code_state WHERE area_code = ?; 164 | 165 | // Records a vote 166 | INSERT INTO votes (phone_number, state, contestant_number) VALUES (?, ?, ?); 167 | 168 | Consequently, the 877,000 TPS performed **3.5 million SQL operations per second**, i.e. three selects and one insert. 169 | 170 | 171 | Observations & Notes 172 | ----------------------------- 173 | 174 | The most important number from this, to my mind, is the **26,500 transactions per second per CPU core** that I saw, which translates into 100,000 operations. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB client side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there. Note that many machines will show a significantly higher performance profile than EC2 instances. 175 | 176 | We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently. 177 | 178 | As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from VoltDB [20]. The README.md [21] of the driver, and of the benchmark [16] have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try the Eonblast Erlvolt repo at git [22]. The free VoltDB community edition is also on github [23]. 179 | 180 | [1] Author on Twitter: https://twitter.com/hdiedrich 181 | [2] Eonblast: http://www.eonblast.com 182 | [3] VoltDB: http://www.voltdb.com 183 | [4] Erlang: http://www.erlang.org 184 | [5] Deepolis: http://www.deepolis.com 185 | [6] Choosing the Best Database For a Game: http://voltdb.com/dig-deeper/webinars.php 186 | [7] Why Erlang? http://www.slideshare.net/eonblast/why-erlang-gdc-online-2012 187 | [8] Erlang and VoltDB: http://www.slideshare.net/eonblast/voltdb-and-erlang-tech-planet-2012 188 | [9] Erlvolt 0.2: https://github.com/Eonblast/Erlvolt/tree/01b304f8975c2168be105c1b9c972386264c0a4e 189 | [10] http://blog.voltdb.com/community-contributions-erlang-client-library/ 190 | [11] Erlvolt 0.3: https://github.com/VoltDB/voltdb-client-erlang 191 | [12] VoltDB 3: http://blog.voltdb.com/introducing-voltdb-3-0/ 192 | [13] Emysql: https://github.com/Eonblast/Emysql 193 | [14] 695k with Node.js: http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/ 194 | [15] bench.erl: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench/bench.erl 195 | [16] Bench README: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench 196 | [17] Amazon EC2 Cluster Instances: http://aws.amazon.com/ec2/instance-types/ 197 | [18] Backpressure: http://voltdb.com/docs/UsingVoltDB/DesignAppLogic.php 198 | [19] Query Source: https://github.com/VoltDB/voltdb/blob/master/examples/voter/src/voter/procedures/Vote.java 199 | [20] VoltDB Downloads: VoltDB http://voltdb.com/community/downloads.php 200 | [21] Driver README: https://github.com/VoltDB/voltdb-client-erlang 201 | [22] Erlvolt Development: https://github.com/Eonblast/Erlvolt 202 | [23] VoltDB Community Edition: https://github.com/VoltDB/voltdb 203 | 204 | /hd 6 feb 13 205 | -------------------------------------------------------------------------------- /doc/CHANGES.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Changes 6 | 7 | 8 | 9 | 10 |

Changes

11 | 12 |

Release: 'Erlvolt 0.3.3' 13 | Author: H. Diedrich 14 | Production: Eonblast Corporation 15 | Copyright: (c) 2013 VoltDB, Inc 16 | Licence: MIT 17 | Date: Feb 11 2013

18 | 19 |

0.3.3 11 Feb 2013 hd

20 | 21 |
    * Compatibility
22 |     * Ease of Build
23 | 
24 |     + add: R16 compatibility
25 |     + add: VoltDB 3 samples compatibility
26 |     + fix: make dialyzer 
27 |     + add: make make-test
28 |     + fix: empty table catch
29 |     + fix: status value
30 |     + fix: parallel.erl sample
31 |     + alt: cleanup
32 | 
33 | 34 |

0.3.02 03 Feb 2013 hd

35 | 36 |
    * Asynchronous Release
37 |     * 877k Benchmark version
38 |     * Major extensions
39 | 
40 |     + add: asynchronous procedure calls
41 |     + add: call queue manager
42 |     + add: monitored mode
43 |     + add: benchmarks
44 |     + add: new samples
45 |     + add: new unit tests
46 |     + add: dialyzer checked
47 |     + add: optional profiler
48 |     + add: minute call options
49 |     + add: more documentation
50 | 
51 | 52 |

0.3.01 08 Jul 2012 hd

53 | 54 |
    + add: auth response codes and output in login()
55 |     + fix: tiny int array element count encoding
56 |     + add: service name as parameter instead of hard coded string
57 |     + add: updated comment for roundtrip time value in invocation response
58 |     + alt: reworked Makefile for tests
59 | 
60 | 61 |

0.3.00 07 Jul 2012 hd

62 | 63 |
    + add: Makefiles
64 |     + alt: dir structure, moved tests into test/, erlunit stripped to etc/
65 |     + add: fixed error/1,2 ambiguity in erlunit
66 | 
67 | 68 |

0.2.01 15 Jun 2010 hd

69 | 70 |
    + add: extensive tests for callback id list (test3.erl)
71 |     + alt: changes in heads and body of callProcedure, now w/callback
72 |     + ext: connection record replaces socket-only parameter
73 |     + add: close(Connection) added, and added to all samples.
74 | 
75 | 76 |

0.1.03 11 Jun 2010 hd

77 | 78 |
    + ext: default encoding of array, (binary) string and integer parameters
79 |     + alt: default parameter encoding attempt of any type as string dropped
80 |     + add: more parameter conversion tests
81 | 
82 | 83 |

0.1.02 11 Jun 2010 hd

84 | 85 |
    + fix: timestamps now interpreted as microseconds (thx Ning)
86 |     + License tags now termed precisely as they should
87 | 
88 | 89 |

0.1.01 11 Jun 2010 hd

90 | 91 |
    + Minor changes
92 | 
93 | 94 |

0.1 11 Jun 2010 hd

95 | 96 |
    * First public release
97 | 
98 | -------------------------------------------------------------------------------- /doc/CHANGES.md: -------------------------------------------------------------------------------- 1 | Changes 2 | ======= 3 | 4 | **Release: 'Erlvolt 0.3.3'** 5 | **Author: H. Diedrich** 6 | **Production: Eonblast Corporation** 7 | **Copyright: (c) 2013 VoltDB, Inc** 8 | **Licence: MIT** 9 | **Date: Feb 11 2013** 10 | 11 | 0.3.3 11 Feb 2013 hd 12 | 13 | * Compatibility 14 | * Ease of Build 15 | 16 | + add: R16 compatibility 17 | + add: VoltDB 3 samples compatibility 18 | + fix: make dialyzer 19 | + add: make make-test 20 | + fix: empty table catch 21 | + fix: status value 22 | + fix: parallel.erl sample 23 | + alt: cleanup 24 | 25 | 0.3.02 03 Feb 2013 hd 26 | 27 | * Asynchronous Release 28 | * 877k Benchmark version 29 | * Major extensions 30 | 31 | + add: asynchronous procedure calls 32 | + add: call queue manager 33 | + add: monitored mode 34 | + add: benchmarks 35 | + add: new samples 36 | + add: new unit tests 37 | + add: dialyzer checked 38 | + add: optional profiler 39 | + add: minute call options 40 | + add: more documentation 41 | 42 | 0.3.01 08 Jul 2012 hd 43 | 44 | + add: auth response codes and output in login() 45 | + fix: tiny int array element count encoding 46 | + add: service name as parameter instead of hard coded string 47 | + add: updated comment for roundtrip time value in invocation response 48 | + alt: reworked Makefile for tests 49 | 50 | 0.3.00 07 Jul 2012 hd 51 | 52 | + add: Makefiles 53 | + alt: dir structure, moved tests into test/, erlunit stripped to etc/ 54 | + add: fixed error/1,2 ambiguity in erlunit 55 | 56 | 0.2.01 15 Jun 2010 hd 57 | 58 | + add: extensive tests for callback id list (test3.erl) 59 | + alt: changes in heads and body of callProcedure, now w/callback 60 | + ext: connection record replaces socket-only parameter 61 | + add: close(Connection) added, and added to all samples. 62 | 63 | 0.1.03 11 Jun 2010 hd 64 | 65 | + ext: default encoding of array, (binary) string and integer parameters 66 | + alt: default parameter encoding attempt of any type as string dropped 67 | + add: more parameter conversion tests 68 | 69 | 0.1.02 11 Jun 2010 hd 70 | 71 | + fix: timestamps now interpreted as microseconds (thx Ning) 72 | + License tags now termed precisely as they should 73 | 74 | 0.1.01 11 Jun 2010 hd 75 | 76 | + Minor changes 77 | 78 | 0.1 11 Jun 2010 hd 79 | 80 | * First public release -------------------------------------------------------------------------------- /doc/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 2 | Henning Diedrich , 3 | Eonblast Corporation [http://www.eonblast.com]. 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the "Software"), to deal in the Software without 8 | restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or 10 | sell copies of the Software, and to permit persons to whom 11 | the Software is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /ebin/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoltDB/voltdb-client-erlang/606ee807248f9fb7beaca982ae159d1becdf25d2/ebin/empty -------------------------------------------------------------------------------- /etc/bench/Makefile: -------------------------------------------------------------------------------- 1 | INCLUDE_DIRS := ../../include 2 | EBIN_DIR := ../../ebin 3 | include ../../etc/include.mk 4 | 5 | all: $(EBIN_DIR)/bench.beam 6 | @: 7 | 8 | %.beam: %.erl 9 | $(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< 10 | 11 | bench-vsm: $(EBIN_DIR)/bench.beam 12 | @### Voter steady managed (reference 13,000 T/sec/core) 13 | @# VMID, Bench, ACallTarget, Rhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 14 | @erl -pa ../../ebin -s bench run VSM voter 100000 steady 200 x managed 100000 200 100 verbose 100 -s init stop -noshell +P 1000000 -smp +S 1 -config bench 15 | 16 | bench-vsd: $(EBIN_DIR)/bench.beam 17 | @### Voter steady direct (reference 21,000 T/sec/core) 18 | @# VMID, Bench, ACallTarget, Rhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 19 | @erl -pa ../../ebin -s bench run VSD voter 100000 steady 200 x direct x x x verbose 200 -s init stop -noshell +P 1000000 -smp +S 1 -config bench 20 | 21 | bench-vbm: $(EBIN_DIR)/bench.beam 22 | @### Voter bursts managed (reference 10,000 T/sec/core) 23 | @# VMID, Bench, ACallTarget, Rhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 24 | @erl -pa ../../ebin -s bench run VBM voter 100000 bursts 100 1 managed 10000 100 100 verbose 200 -s init stop -noshell +P 1000000 -smp +S 1 -config bench 25 | 26 | bench-vbd: $(EBIN_DIR)/bench.beam 27 | @### Voter bursts direct (reference 16,000 T/sec/core) 28 | @# VMID, Bench, ACallTarget, Rhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 29 | @erl -pa ../../ebin -s bench run VBD voter 100000 bursts 100 5 direct x x 100 verbose 200 -s init stop -noshell +P 1000000 -smp +S 1 -config bench 30 | 31 | bench-hsd: $(EBIN_DIR)/bench.beam 32 | @### Hello steady direct (reference 21,000 T/sec/core) 33 | @# VMID, Bench, ACallTarget, Rhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 34 | @erl -pa ../../ebin -s bench run HSD hello 100000 steady 200 x direct x x x verbose 200 -s init stop -noshell +P 1000000 -smp +S 1 -config bench 35 | 36 | ### Mulit-VM benchmark VSD using etc/bench/benchstart shell script 37 | VMS ?= 1 # of virtual machines (erl Erlang emulators) started 38 | CORES ?= 1 # number of cores used per VM (erl parameter +S) 39 | CALLS ?= 10000 # of transactions per VM for the benchmark 40 | WORKERS ?= 100 # of parallel ('steady') workers = max server load 41 | RHYTHM ?= steady 42 | MODE ?= direct 43 | bench-mvm: $(EBIN_DIR)/bench.beam 44 | sudo ./benchstart $(VMS) $(CORES) $(CALLS) $(WORKERS) $(RHYTHM) $(MODE) 45 | 46 | bench-help: 47 | # You need to run the VoltDB 'Voter' example database, 48 | # e.g. by 'cd voltdb/examples/voter && ./run.sh' 49 | # 50 | # Benchmarks can be configured with multiple options, 51 | # inspect etc/bench/Makefile for samples. The easiest 52 | # way to start out is 'make bench' from Erlvolt root. 53 | # Six setups are pre-configured, available via make: 54 | # 55 | # bench-vsd: parallel workers, directly on the database 56 | # the standard bench, same as 'make bench' 57 | # bench-vsm: parallel workers, managed with a queue 58 | # the queue is the driver's overload protection 59 | # bench-vbm: timed bursts, managed with a queue 60 | # testing the queue to buffer away peaks 61 | # bench-vbd: timed bursts, directly on the database 62 | # easy to crash, showing the queue's value 63 | # bench-mvm: Multiple virtual machines running bench-vsd 64 | # parameters: VMS, CORES, CALLS, WORKERS 65 | # e.g. 'make bench-mvm VMS=10' 66 | # 67 | # Parameters to the bench module are, in this order: 68 | # 69 | # VMID: Virtual Machine ID, trails screen logs 70 | # Bench: type of benchmark calls, 'voter' or 'hello' 71 | # CallTarget: number of calls before benchmark ends 72 | # Rhythm: timed 'bursts' or 'steady' synched calls 73 | # BurstSize: calls per burst or # of steady workers 74 | # Delay: millisec delay between bursts 75 | # Mode: 'direct' calls or using 'managed' driver queue 76 | # QueueSize: max processes that can wait in queue 77 | # Slots: max pending request before queueing next ones 78 | # Target: 'managed': queue size, 'direct': # pending 79 | # Verbosity: quiet, nonverbose, verbose, veryverbose 80 | # DumpInterval: for 'make profile' msec between stats 81 | @# /hd Jan'13 82 | 83 | clean: 84 | @rm -f *.log 85 | @rm -f *.totals 86 | @rm -f *.dump 87 | @rm -f *.beam 88 | @rm -f EBIN_DIR/bench.beam 89 | 90 | 91 | -------------------------------------------------------------------------------- /etc/bench/bench.config: -------------------------------------------------------------------------------- 1 | [ {erlvolt, [ 2 | {hosts, [ 3 | {"localhost", 21212} 4 | ]}, 5 | %% This is used to synchronous benchmarks across multiple machines 6 | %% e.g. EC2 instances. Use e.g. 20 to have twenty seconds to start 7 | %% all benchmarks on all machines. All benchmarks will start after 8 | %% 20 to 40 seconds, all at the same wallclock time. 9 | {start_delay, 20} 10 | 11 | ]}]. 12 | -------------------------------------------------------------------------------- /etc/bench/benchstart: -------------------------------------------------------------------------------- 1 | # usage: bench <# VMs> <# cores> <# calls total> <# parallel workers> 2 | # 'make clean fast' for fastest build 3 | # 'make clean profile' to see rolling stats 4 | 5 | VMS=$1 6 | CORES=$2 7 | CALLS=$3 8 | WORKERS=$4 9 | RHYTHM=$5 10 | MODE=$6 11 | 12 | # prep logging 13 | sudo pkill -f "tail -f bench.log" 14 | echo "Mulitple VM Erlvolt Bench Log" > bench.log 15 | echo -n "" > bench.totals 16 | tail -f bench.log & 17 | 18 | # start processes 19 | for cid in $(seq 1 1 $VMS) ; do 20 | # parameters to run: VMID, Bench, ACallTarget, ARhythm, ABurstSize, ADelay, Mode, AQueueSize, ASlots, ATarget, AVerbosity, ADumpInterval 21 | erl -pa ../../ebin -s bench run VSD$cid voter $CALLS $RHYTHM $WORKERS x $MODE x x x nonverbose 500 -s init stop -noshell +P 1000000 -smp +S $CORES -config bench >> bench.log 2>> bench.log & 22 | done 23 | echo "This is the followed tail of the file bench.log, which is written to by $1 separate Erlang VMs running the benchmark." 24 | 25 | # Wait for all processes to finish, then 2 seconds more. 26 | wait $! 27 | sleep 5 28 | 29 | # Sum and print totals of processes 30 | echo -n "VM performances: " 31 | while read -r line 32 | do 33 | echo -n $line " " 34 | done < bench.totals 35 | echo 36 | echo "Total transactions per second:" `cat bench.totals | awk '{total = total + $1}END{print total}'` "T/sec" 37 | -------------------------------------------------------------------------------- /etc/ct_default.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet for Common Test */ 2 | 3 | body { 4 | padding: 10px; margin: 10px; 5 | -webkit-font-smoothing: antialiased; 6 | background-color: #FBFFFC; 7 | } 8 | 9 | a:link { 10 | color: #2B507D; 11 | } 12 | 13 | a:visited { 14 | color: #85ABD5 15 | } 16 | 17 | h1 { 18 | font-family: verdana, arial, sans-serif; font-size: 200%; 19 | letter-spacing: -2px; word-spacing: 2px; font-weight: bold; 20 | color: #3F3F3F; 21 | } 22 | 23 | h2 { 24 | font-family: verdana, arial, sans-serif; font-size: 175%; 25 | letter-spacing: -2px; word-spacing: 2px; font-weight: normal; 26 | color: #3F3F3F; 27 | } 28 | 29 | h3 { 30 | font-family: verdana, arial, sans-serif; font-size: 140%; 31 | letter-spacing: -2px; word-spacing: 2px; font-weight: bold; 32 | color: #3F3F3F; 33 | } 34 | 35 | h4 { 36 | font-family: verdana, arial, sans-serif; font-size: 120%; 37 | letter-spacing: -2px; word-spacing: 2px; font-weight: normal; 38 | color: #3F3F3F; 39 | } 40 | 41 | p { 42 | font-family: "Trebuchet MS", "Lucida Sans Unicode", verdana, arial, sans-serif; 43 | font-size: .9em; color: #000000; 44 | } 45 | 46 | ul { 47 | list-style-type: none; 48 | padding: 0em; 49 | margin: 1em; 50 | } 51 | li { 52 | font-size: 0.95em; color: #000000; 53 | margin: .3em 0; 54 | } 55 | 56 | pre { 57 | color: black; 58 | font-family: "Monaco", "Andale Mono", "Consolas", monospace; 59 | font-size: .8em; 60 | } 61 | 62 | code { 63 | color: black; 64 | font-family: "Monaco", "Andale Mono", "Consolas", monospace; 65 | font-size: .8em; 66 | } 67 | 68 | div.mono_sm { 69 | font-family: "Courier New", monospace; font-size: .75em; 70 | word-spacing: 1px; color: #000000; 71 | } 72 | 73 | div.mono_la { 74 | font-family: "Courier New", monospace; font-size: .8em; 75 | color: #000000; 76 | } 77 | 78 | div.copyright { 79 | padding: 20px 0px 0px 0px; 80 | font-family: "Courier New", monospace; font-size: .7em; 81 | color: #000000; 82 | } 83 | 84 | div.ct_internal { 85 | background: lightgrey; color: black; 86 | font-family: "Monaco", "Andale Mono", "Consolas", monospace; 87 | font-size: .95em; 88 | margin: .2em 0 0 0; 89 | } 90 | 91 | div.ct_error_notify { 92 | background: #CC0000; 93 | color: #FFFFFF; 94 | font-family: "Monaco", "Andale Mono", "Consolas", monospace; 95 | font-size: 1.05em; 96 | margin: .2em 0 0 0; 97 | } 98 | 99 | div.default { 100 | background: lightgreen; color: black; 101 | font-family: "Monaco", "Andale Mono", "Consolas", monospace; 102 | font-size: 1.05em; 103 | margin: .2em 0 0 0; 104 | } 105 | 106 | div.label { 107 | font-family: verdana, arial, sans-serif; font-size: 200%; 108 | letter-spacing: -2.5px; word-spacing: 2px; 109 | font-weight: bold; color: #2B507D; 110 | } 111 | 112 | table { 113 | border-collapse: collapse; border: 6px solid #3F3F3F; 114 | background: #FFFFFF; 115 | font: .8em/1.2em "Lucida Sans Unicode", verdana, arial, sans-serif; 116 | color: #222; 117 | } 118 | 119 | caption { 120 | font-size: 1.3em; font-weight: bold; 121 | text-align: center; padding: 1em 4px; 122 | } 123 | 124 | td, th { 125 | padding: .5em 7px .5em 7px; line-height: 1.3em; 126 | border-bottom: 3px solid #F5C4C1; 127 | border-left: 2px dashed #809FFF; 128 | } 129 | 130 | th { 131 | background: #3F3F3F; color: #fff; 132 | font-family: arial, sans-serif; font-size: 120%; 133 | letter-spacing: -0.5px; 134 | font-weight: bold; text-align: center; 135 | padding-right: .5em; vertical-align: top; 136 | } 137 | 138 | thead th { 139 | background: #3F3F3F; color: #fff; 140 | font-family: arial, sans-serif; font-size: 120%; 141 | letter-spacing: -0.5px; 142 | font-weight: bold; text-align: center; 143 | padding-right: .5em; vertical-align: top; 144 | text-decoration: underline; 145 | } 146 | 147 | tfoot td { 148 | font-family: arial, sans-serif; font-size: 110%; 149 | letter-spacing: -0.5px; 150 | font-weight: bold; 151 | } 152 | 153 | .odd td { 154 | background: #F3F3F3; 155 | } 156 | .odd th { 157 | background: #F3F3F3; 158 | } 159 | 160 | td a, td a:link { 161 | color: #2B507D; 162 | } 163 | 164 | td a:visited { 165 | color: #85ABD5; 166 | } 167 | 168 | tr:hover th[scope=row], tr:hover td { 169 | background-color: #D1D1D1; 170 | color: #fff; 171 | } 172 | 173 | td a:hover, td a:focus { 174 | color: #85ABD5; 175 | } 176 | 177 | th a, td a:active { 178 | color: #85ABD5; 179 | } 180 | 181 | th + td { 182 | padding-left: .5em; 183 | } 184 | 185 | #button_holder { 186 | display: block; float: center; 187 | font-family: arial, verdana, sans-serif; 188 | font-size: 12px; text-shadow: 1px 1px lightgray; 189 | } 190 | 191 | .btn a { 192 | padding: 6px 12px; float: center; 193 | text-decoration: none; color: #3F3F3F; 194 | font-weight: bold; border: 3px outset #3F3F3F; 195 | background-color: #F3F3F3; 196 | } 197 | 198 | .btn a:hover { 199 | color: #fff; 200 | background-color: #809FFF; 201 | } 202 | -------------------------------------------------------------------------------- /etc/grep: -------------------------------------------------------------------------------- 1 | egrep -H $1 include/*.hrl 2 | egrep -H $1 src/*.erl 3 | egrep -H $1 src/*.src 4 | egrep -H $1 examples/*.erl 5 | egrep -H $1 etc/test/*.erl 6 | egrep -H $1 etc/bench/*.erl 7 | egrep -H $1 ./*.md 8 | egrep -H $1 doc/*.md 9 | -------------------------------------------------------------------------------- /etc/include.mk: -------------------------------------------------------------------------------- 1 | ERL := erl 2 | ERLC := $(ERL)c 3 | 4 | INCLUDE_DIRS ?= ../include $(wildcard ../deps/*/include) 5 | EBIN_DIRS ?= $(wildcard ../deps/*/ebin) 6 | ERLC_FLAGS := -W $(INCLUDE_DIRS:../%=-I ../%) $(EBIN_DIRS:%=-pa %) 7 | 8 | ifdef PROFILE 9 | ERLC_FLAGS += -Dprofile 10 | endif 11 | 12 | ifdef DEBUG 13 | ERLC_FLAGS += +debug_info 14 | endif 15 | 16 | ifdef NATIVE 17 | ERLC_FLAGS += +native -smp 18 | endif 19 | 20 | EBIN_DIR ?= ../ebin 21 | DOC_DIR ?= ../doc 22 | EMULATOR := beam 23 | 24 | ERL_TEMPLATE := $(wildcard *.et) 25 | ERL_SOURCES := $(wildcard *.erl) 26 | ERL_HEADERS := $(wildcard *.hrl) $(wildcard ../include/*.hrl) 27 | ERL_OBJECTS := $(ERL_SOURCES:%.erl=$(EBIN_DIR)/%.beam) 28 | ERL_TEMPLATES := $(ERL_TEMPLATE:%.et=$(EBIN_DIR)/%.beam) 29 | ERL_OBJECTS_LOCAL := $(ERL_SOURCES:%.erl=./%.$(EMULATOR)) 30 | EBIN_FILES = $(ERL_OBJECTS) $(APP_FILES:%.app=../ebin/%.app) $(ERL_TEMPLATES) 31 | 32 | $(EBIN_DIR)/%.$(EMULATOR): %.erl $(ERL_HEADERS) 33 | $(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< 34 | 35 | ./%.$(EMULATOR): %.erl 36 | $(ERLC) $(ERLC_FLAGS) -o . $< 37 | 38 | $(DOC_DIR)/%.html: %.erl 39 | $(ERL) -noshell -run edoc file $< -run init stop 40 | mv *.html $(DOC_DIR) 41 | 42 | -------------------------------------------------------------------------------- /etc/markedoc.sed: -------------------------------------------------------------------------------- 1 | # markedoc 0.3.1 - 02/05/11 - H. Diedrich 2 | # ---------------------------------------------------------- 3 | # sed command file to convert markdown format to edoc format 4 | # Linux, FreeBSD and Mac OS X. -- Windows must install sed. 5 | # ---------------------------------------------------------- 6 | # Use it to make a markdown readme file part of an edoc file: 7 | # FrBSD: sed -E -f > 8 | # MacOS: sed -E -f > 9 | # Linux: sed -r -f > 10 | # Only difference, Linux uses -r where the others use -E. 11 | # ---------------------------------------------------------- 12 | # SAMPLE for FreeBSD / Mac OS X: 13 | # sed -E -f markedoc.sed README.markdown > overview.edoc 14 | # SAMPLE for Linux: 15 | # sed -r -f markedoc.sed README.markdown > overview.edoc 16 | # ---------------------------------------------------------- 17 | # SAMPLE FILES: 18 | # https://github.com/hdiedrich/markedoc/tree/master/samples 19 | # SAMPLE RESULTS: 20 | # samples/what-you-should-see/ & samples/what-you-could-see/ 21 | # ---------------------------------------------------------- 22 | # SAMPLE WORKFLOW (change -r to -E for FreeBSD / Mac OS X): 23 | # sed -r -f markedoc.sed README.md > doc/README.edoc 24 | # erl -noshell -run edoc_run application "'myapp'" '"."' '[]' 25 | # ---------------------------------------------------------- 26 | # REQUIREMENTS: sed, Erlang. sed is in all *x distros. 27 | # Windows: http://gnuwin32.sourceforge.net/packages/sed.htm 28 | # ---------------------------------------------------------- 29 | # STATUS: Pre-Beta. 30 | # It can reliably do nice things but likes to trip up EDoc. 31 | # With a bit of patience, and mostly with pretty clean md 32 | # markup, and some blank lines sometimes, most things work. 33 | # ---------------------------------------------------------- 34 | # LICENSE: Free software, no warranties. 35 | # ---------------------------------------------------------- 36 | # edown: http://www.erlang.org/doc/apps/edoc/ 37 | # Markdown: http://daringfireball.net/projects/markdown/ 38 | # Edoc: http://www.erlang.org/doc/apps/edoc/ 39 | # sed: http://www.gnu.org/software/sed/manual/sed.html 40 | # ---------------------------------------------------------- 41 | # Repository: https://github.com/hdiedrich/markedoc/ 42 | # Issues: https://github.com/hdiedrich/markedoc/issues 43 | # Please experiment and push your fixes. - Thanks! 44 | # ---------------------------------------------------------- 45 | 46 | # ********************************************************** 47 | # SCRIPT 48 | # ********************************************************** 49 | # Ach, da kommt der Meister! Herr, die Not ist gross! ~~~ 50 | # ~~~ Die ich rief, die Geister, Werd ich nun nicht los. 51 | # ---------------------------------------------------------- 52 | # This is a sed script for use with -E/-r regexes & NOT -n. 53 | # s/// is the basic sed regex replace 54 | # command. sed normally works strictly line by line. 'N' 55 | # is used to join lines. 't' is a conditional branch, ':' 56 | # is a label. The order of replacement functions matters. 57 | # There are tabs in some patterns that may look like spaces. 58 | # See 'man sed' for more info. If you are a sed master, 59 | # your help making this better is much appreciated. 60 | # ********************************************************** 61 | 62 | # as first line, make the @doc tag 63 | # -------------------------------- 64 | 1 i\ 65 | @doc\ 66 | 67 | # code sample blocks, trying to get them into one
 block
 68 | # -----------------------------------------------------------
 69 | # tabs are consumed for 'navigation'. sed is Turing complete.
 70 | # inserted space is needed by edocs.
 71 | # There are tabs in this pattern.
 72 | /^	/ {
 73 | 	# break ... on last line ('N' would exit)
 74 | 	$ b end_collect_with_last_line_hit
 75 | 	s/^	(.*)$/ \1/
 76 | 	# do ...
 77 | 	: do_collect
 78 | 		# append next line
 79 | 		N
 80 | 		# break ... if we are now into the last line
 81 | 		# (or the test below will eat the tab away.)
 82 | 		$ b end_collect_with_last_line_hit
 83 | 		# does the current last line start with a tab, too?
 84 | 		s/(\n)	(.*)$/\1 \2/
 85 | 		# while: ... yes, then loop
 86 | 		t do_collect
 87 | 	# normal end of collect: got all indendet lines, plus one too many.
 88 | 	# -----------------------------------------------------------------
 89 | 	b normal_course
 90 | 	#
 91 | 	# Run into file end while looping
 92 | 	# -------------------------------
 93 | 	: end_collect_with_last_line_hit
 94 | 	# and does that last line start with a tab, too?
 95 | 	s/(\n)	(.*)$/\1 \2/
 96 | 	s/^	(.*)$/ \1/
 97 | 	# yes, then we're done actually
 98 | 	t wrap_rest_and_done
 99 | 	# else, cut it off and such, as normal
100 | 	# debug i\
101 | 	# debug normal
102 | 	#
103 | 	: normal_course
104 | 	# ... ok, we have multiple lines, and we have one line too much, back it all up.
105 | 	h
106 | 	# Handle the 
 block to be (*):
107 | 	# ---------------------------------
108 | 	# cut off the last line, that doesn't belong and insert newlines
109 | 	s/^(.*)(\n)(.*)$/\2\1\2/
110 | 	# wrap all in the docs code tags ```...'''
111 | 	s/^(.*)$/```\1'''/
112 | 	# protect @ (for edoc related texts that explain @-tags). There is a tab in [].
113 | 	s/([ 	\"\'\`]+@)/\1@/g
114 | 	# send result to stdout  
115 | 	p
116 | 	# Now make sure that that last line is not lost:
117 | 	# ----------------------------------------------
118 | 	# get stored back
119 | 	g
120 | 	# this time discard all but the last line, which is processed further
121 | 	s/^.*\n(.*)$/\1/
122 | 	# jump to end
123 | 	b end_of_code_blocks_handling
124 | 	#
125 | 	# File End Remedy: wrap all to end and done.
126 | 	# ------------------------------------------
127 | 	: wrap_rest_and_done
128 | 	# debug i\
129 | 	# debug rest and done
130 |  	# wrap all in the docs code tags ```...'''
131 | 	s/^(.*)$/```\1'''/
132 | 	# protect @ (for edoc related texts that explain @-tags). There is a tab in [].
133 | 	s/([ 	\"\'\`]+@)/\1@/g
134 | 	b end
135 | 	#
136 | } 
137 | 
138 | :end_of_code_blocks_handling
139 | 
140 | 
141 | # robust alternate for code blocks: each tabbed line
142 | # --------------------------------------------------
143 | # If the above keeps being difficult, use this more robust 
144 | # version. The main difference is merely that it will tag each 
145 | # line separately. If you work with very small margins and 
146 | # paddings for 
 in your css file, that might give just as
147 | # nice a result as the above. There are tabs in this pattern.
148 | # (Really, delete all of the above from '# code sample blocks ...' 
149 | # to # :end_of_code_blocks_handling)
150 | # s/^	(.+)$/```	\1'''/
151 | 
152 | # edoc sugar
153 | # -----------
154 | # won't help the markdown source but make the edoc prettier
155 | 
156 | # footnote signs
157 | # ..............
158 | # superscript 1
159 | s/\(\*1\)/\¹/g
160 | # superscript 2
161 | s/\(\*2\)/\²/g
162 | # superscript 3
163 | s/\(\*3\)/\³/g
164 | # dagger
165 | s/\(\+\)/\†/g
166 | # double dagger
167 | s/\(\+\+\)/\‡/g
168 | # star
169 | s/\(\*\)/\*/g
170 | # double star
171 | s/\(\*\*\)/\*\*/g
172 | # triple star
173 | s/\(\*\*\*\)/\*\*\*/g
174 | 
175 | # special chars
176 | # .............
177 | # middle dot
178 | s/::/\·/g
179 | # guillemot
180 | s/<>/\»/g
182 | 
183 | # copyright
184 | # .........
185 | s/\(c)/\©/g
186 | s/\(C)/\©/g
187 | s/\(R)/\®/g
188 | s/\(r)/\®/g
189 | s/\(tm)/\™/g
190 | s/\(TM)/\™/g
191 | 
192 | # atone for markdown \_
193 | # ---------------------
194 | s/\\_/_/g
195 | 
196 | 
197 | # links
198 | # -----
199 | # external links
200 | s/\[([^]]+)\]\(([^)]+)\)/\1<\/a>/
201 | 
202 | 
203 | # references, '[..]:...'-style
204 | # ----------------------------
205 | # take out markdown anchor relay tricks (see README)
206 | # ..................................................
207 | s/\[[^]]+\]:[ 	]*#.*//
208 | 
209 | # real urls (normal case)
210 | # .......................
211 | s/(\[([^]]+)\]): +\[?(http[s]?:\/\/[^.>" ]+\.[^>" ]+)\]? *	*("([^"]+)") *	*$/
  • \5:\3<\/a><\/li>/ 212 | # check next line "..." description 213 | /(\[([^]]+)\]): +\[?(http[s]?:\/\/[^.>" ]+\.[^>" ]+)\]? *$/ { 214 | # get next line, if the current is not the last 215 | $!N 216 | # try two line spanning, or single (last) line 217 | s/(\[([^]]+)\]): +\[?(http[s]?:\/\/[^.>" ]+\.[^>" ]+)\]? * *\n * *("([^"]*)") * *$/
  • \5:\3<\/a><\/li>/ 218 | t double_line_url_done 219 | # try one line only, rest to be saved 220 | s/(\[([^]]+)\]): +\[?(http[s]?:\/\/[^.>" ]+\.[^>" ]+)\]? * *(\n)/
  • \3<\/a><\/li>\4/ 221 | t double_line_url_done 222 | # case of last line, single, no "..." description 223 | s/(\[([^]]+)\]): +\[?(http[s]?:\/\/[^.>" ]+\.[^>" ]+)\]? * *$/
  • \3<\/a><\/li>/ 224 | : double_line_url_done 225 | # print out up to first \n, delete, start from top with the rest 226 | P 227 | D 228 | } 229 | 230 | # email addresses 231 | # ............... 232 | s/(\[([^]]+)\]): +" ]+@[^.>" ]+\.[^>" ]+)>? * *("([^"]+)") * *$/
  • 287 | s/^\*(.+)$/
  • \1<\/li>/ 288 | 289 | 290 | # emails, urls 291 | # ------------ 292 | s/<([^aA][^@>]+@[^.>]+.[^>]+)>/\1<\/a>/ 293 | s/<(http[s]?:\/\/[^.>]+.[^>]+)>/\1<\/a>/ 294 | 295 | 296 | # line breaks 297 | # ----------- 298 | s/ $/
    / 299 | 300 | 301 | # single backticks 302 | # ---------------- 303 | # make code quotes 304 | s/`([^`]+)`/\1<\/code>/g 305 | 306 | 307 | # protect @ 308 | # --------- 309 | # leading space or tab indicates use as code sample for, well, edoc 310 | # itself most likely, so escape it. 311 | s/([ \"\'\`]+@)/\1@/g 312 | 313 | # protect & 314 | # --------- 315 | # still edoc won't understand code names like → 316 | s/&#/:::AMPERSAND:::#/g 317 | s/&([a-z]{1,7});/:::AMPERSAND:::\1;/g 318 | s/&/\&/g 319 | s/:::AMPERSAND:::/\&/g 320 | 321 | # headlines by underline === or --- 322 | # --------------------------------- 323 | # demoted to h2 and h3, as h1 is reserved in edoc 324 | { 325 | # don't check this for the last line ('N' would exit) 326 | $ b skip_alt_headlines 327 | # get next line 328 | N 329 | # contract === with previous to headline h2 330 | # and in passing weed out explicit anchors and formatting 331 | s/^([^<]+)(<.*>)?[ ]*\n=+ *$/== \1 ==/ 332 | # if substitution took place, goto ... 333 | t substi 334 | # contract --- with previous to headline h2 335 | # and in passing weed out explicit anchors and formatting 336 | s/^([^<]+)(<.*>)?[ ]*\n-+ *$/=== \1 ===/ 337 | # if substitution took place, goto ... 338 | t substi 339 | # no substitution: print the previous line and start with latest from top 340 | # ----------------------------------------------------------------------- 341 | # store the two lines we have now, one is the one formatting is done with 342 | # the next is the fresh one we just pulled. 343 | h 344 | # cut off the last line, print the ready formatted one 345 | P 346 | D 347 | # and this is the goto for successful headline substitutions above: 348 | :substi 349 | } 350 | 351 | :skip_alt_headlines 352 | 353 | :end 354 | 355 | # at the bottom, add JS for the 'smart' direct jump 356 | # ------------------------------------------------- 357 | # to a reference url in trailing '[]:...'-notation 358 | $ a\ 359 | 364 | 365 | # debugger stable 366 | # --------------- 367 | # i\ 368 | # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 369 | # p 370 | # i\ 371 | # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 372 | 373 | # ----------------------------------------------------------------- 374 | # t,b: "In most cases, use of these commands indicates that you are 375 | # probably better off programming in something like awk or Perl." 376 | # sed manual: http://www.gnu.org/software/sed/manual/sed.html 377 | # ----------------------------------------------------------------- 378 | # 'powered by Eonblast' http://www.eonblast.com - all the new tech -------------------------------------------------------------------------------- /etc/replace: -------------------------------------------------------------------------------- 1 | LANG=C sed -E -i "" -e "s/$1/$2/g" include/*.hrl 2 | LANG=C sed -E -i "" -e "s/$1/$2/g" src/*.erl 3 | LANG=C sed -E -i "" -e "s/$1/$2/g" src/*.src 4 | LANG=C sed -E -i "" -e "s/$1/$2/g" examples/*.erl 5 | LANG=C sed -E -i "" -e "s/$1/$2/g" etc/test/*.erl 6 | LANG=C sed -E -i "" -e "s/$1/$2/g" etc/bench/*.erl 7 | LANG=C sed -E -i "" -e "s/$1/$2/g" *.md 8 | LANG=C sed -E -i "" -e "s/$1/$2/g" doc/*.md 9 | -------------------------------------------------------------------------------- /etc/test/basics_SUITE.erl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% File : erlvolt/test/basics_SUITE.erl 3 | %%% Descr : Suite #2: Tests of basic SQL 4 | %%% Author : H. Diedrich 5 | %%% Requires : Erlang 14B (prior may not have ct_run) 6 | %%%------------------------------------------------------------------- 7 | %%% 8 | %%% Run from erlvolt/: 9 | %%% make test 10 | %%% 11 | %%% Results see: 12 | %%% etc/test/index.html 13 | %%% 14 | %%%------------------------------------------------------------------- 15 | 16 | -module(basics_SUITE). 17 | -compile(export_all). 18 | -include_lib("common_test/include/ct.hrl"). 19 | 20 | %% Optional suite settings 21 | %%-------------------------------------------------------------------- 22 | %% Function: suite() -> Info 23 | %% Info = [tuple()] 24 | %%-------------------------------------------------------------------- 25 | 26 | suite() -> 27 | [{timetrap,{seconds,30}}]. 28 | 29 | %% Mandatory list of test cases and test groups, and skip orders. 30 | %%-------------------------------------------------------------------- 31 | %% Function: all() -> GroupsAndTestCases | {skip,Reason} 32 | %% GroupsAndTestCases = [{group,GroupName} | TestCase] 33 | %% GroupName = atom() 34 | %% TestCase = atom() 35 | %% Reason = term() 36 | %%-------------------------------------------------------------------- 37 | 38 | all() -> 39 | [delete_all, 40 | insert_only, 41 | insert_and_read_back]. 42 | 43 | %% Optional suite pre test initialization 44 | %%-------------------------------------------------------------------- 45 | %% Function: init_per_suite(Config0) -> 46 | %% Config1 | {skip,Reason} | {skip_and_save,Reason,Config1} 47 | %% Config0 = Config1 = [tuple()] 48 | %% Reason = term() 49 | %%-------------------------------------------------------------------- 50 | 51 | init_per_suite(Config) -> 52 | 53 | % if this fails, focus on environment_SUITE to fix test setup. 54 | crypto:start(), 55 | application:start(erlvolt), 56 | erlvolt:add_pool(test_pool, [{"localhost", 21212}]), 57 | Config. 58 | 59 | %% Optional suite post test wind down 60 | %%-------------------------------------------------------------------- 61 | %% Function: end_per_suite(Config0) -> void() | {save_config,Config1} 62 | %% Config0 = Config1 = [tuple()] 63 | %%-------------------------------------------------------------------- 64 | 65 | end_per_suite(_Config) -> 66 | erlvolt:close_pool(test_pool), 67 | ok. 68 | 69 | %% A test case. The ok is irrelevant. What matters is, if it returns. 70 | %%-------------------------------------------------------------------- 71 | %% Function: TestCase(Config0) -> 72 | %% ok | exit() | {skip,Reason} | {comment,Comment} | 73 | %% {save_config,Config1} | {skip_and_save,Reason,Config1} 74 | %% Config0 = Config1 = [tuple()] 75 | %% Reason = term() 76 | %% Comment = term() 77 | %%-------------------------------------------------------------------- 78 | 79 | %% Test Case: Delete all records in the test database 80 | %%-------------------------------------------------------------------- 81 | delete_all(_) -> 82 | 83 | erlvolt:call_procedure(test_pool, "@AdHoc", ["DELETE FROM votes"]), 84 | ok. 85 | 86 | 87 | %% Test Case: Make an Insert 88 | %%-------------------------------------------------------------------- 89 | insert_only(_) -> 90 | 91 | erlvolt:call_procedure(test_pool, "Initialize", [3, "Hugo, Bert, Rupert"]), 92 | ok. 93 | 94 | %% Test Case: Make an Insert and Select it back 95 | %%-------------------------------------------------------------------- 96 | insert_and_read_back(_) -> 97 | 98 | delete_all(), 99 | 100 | erlvolt:call_procedure(test_pool, "Initialize", [3, "Hugo, Bert, Rupert"]), 101 | 102 | Result = erlvolt:call_procedure(test_pool, "@AdHoc", ["select COUNT(*) as C from contestants"]), 103 | {result, { voltresponse, _, [ Table | _ ] }} = Result, 104 | Row = erlvolt:get_row(Table, 1), 105 | Count = erlvolt:get_integer(Row, Table, "C"), 106 | 107 | % find this output by clicking on the test name, then case name in test/index.html 108 | io:format("Result: ~n~p ~n", [Result]), 109 | io:format("Should be: ~n~p ~n", ["{result,{voltresponse,{0,<<0,0,_,0,0,0,0,_>>,1,<<>>,128,<<>>,<<>>,_},[{volttable,[<<\"C\">>],[6],[{voltrow,[3]}]}]}}"]), 110 | io:format("Row: ~n~p ~n", [Row]), 111 | io:format("Should be: ~n~p ~n", ["{voltrow,[3]}"]), 112 | io:format("~p (should be 3)~n", [Count]), 113 | {result,{voltresponse,{0,<<0,0,_,0,0,0,0,_>>,1,<<>>,128,<<>>,<<>>,_}, [{volttable,[<<"C">>],[6],[{voltrow,[3]}]}]}} = Result, 114 | Row = {voltrow,[3]}, 115 | Count = 3, 116 | ok. 117 | 118 | delete_all() -> 119 | 120 | erlvolt:call_procedure(test_pool, "@AdHoc", ["DELETE FROM contestants"]), 121 | erlvolt:call_procedure(test_pool, "@AdHoc", ["DELETE FROM area_code_state"]), 122 | erlvolt:call_procedure(test_pool, "@AdHoc", ["DELETE FROM votes"]). 123 | -------------------------------------------------------------------------------- /etc/test/depr/Makefile: -------------------------------------------------------------------------------- 1 | include ../etc/include.mk 2 | 3 | all: $(EBIN_FILES) 4 | 5 | debug: 6 | $(MAKE) DEBUG=-DDEBUG 7 | 8 | clean: 9 | @rm -rf $(EBIN_FILES) 10 | 11 | -------------------------------------------------------------------------------- /etc/test/depr/erlunit/erlunit.hrl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlunit.hrl %%% 3 | %%% Description : Unit test convenience macros %%% 4 | %%% Version : 0.2.8.2/alpha %%% 5 | %%% Copyright : (c) 2010 Eonblast Corporation http://www.eonblast.com %%% 6 | %%% License : MIT - see LICENSE %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% Created : 01 May 2010 %%% 9 | %%% Changed : 10 May 2010 - see CHANGES %%% 10 | %%% Tested on : Erlang R13B01 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% Include this file in your test program to use macros. if you don't use %%% 14 | %%% Macros, you don't need to include this file. %%% 15 | %%% %%% 16 | %%%-------------------------------------------------------------------------%%% 17 | 18 | 19 | %%%-------------------------------------------------------------------------%%% 20 | %%% Imperative Macros %%% 21 | %%%-------------------------------------------------------------------------%%% 22 | 23 | 24 | -define(ERLUNIT_SEQ_TRUE_MSG(F, M), erlunit:true(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 25 | -define(ERLUNIT_SEQ_TRUE(F), erlunit:true(fun() -> F end, ??F, ?MODULE, ?LINE )). 26 | 27 | -define(ERLUNIT_SEQ_FALSE_MSG(F, M), erlunit:false(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 28 | -define(ERLUNIT_SEQ_FALSE(F), erlunit:false(fun() -> F end, ??F, ?MODULE, ?LINE )). 29 | 30 | -define(ERLUNIT_SEQ_NOT_TRUE_MSG(F, M), erlunit:not_true(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 31 | -define(ERLUNIT_SEQ_NOT_TRUE(F), erlunit:not_true(fun() -> F end, ??F, ?MODULE, ?LINE )). 32 | 33 | -define(ERLUNIT_SEQ_NOT_FALSE_MSG(F, M), erlunit:not_false(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 34 | -define(ERLUNIT_SEQ_NOT_FALSE(F), erlunit:not_false(fun() -> F end, ??F, ?MODULE, ?LINE )). 35 | 36 | %%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 37 | 38 | -define(ERLUNIT_SEQ_PASS_MSG(F, M), erlunit:pass(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 39 | -define(ERLUNIT_SEQ_PASS(F), erlunit:pass(fun() -> F end, ??F, ?MODULE, ?LINE )). 40 | 41 | -define(ERLUNIT_SEQ_FAIL_MSG(F, M), erlunit:fail(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 42 | -define(ERLUNIT_SEQ_FAIL(F), erlunit:fail(fun() -> F end, ??F, ?MODULE, ?LINE )). 43 | 44 | -define(ERLUNIT_SEQ_EXITS_MSG(F, M), erlunit:exits(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 45 | -define(ERLUNIT_SEQ_EXITS(F), erlunit:exits(fun() -> F end, ??F, ?MODULE, ?LINE )). 46 | 47 | -define(ERLUNIT_SEQ_ERROR_MSG(F, M), erlunit:error(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 48 | -define(ERLUNIT_SEQ_ERROR(F), erlunit:error(fun() -> F end, ??F, ?MODULE, ?LINE )). 49 | 50 | -define(ERLUNIT_SEQ_THROWS_MSG(F, M), erlunit:throws(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 51 | -define(ERLUNIT_SEQ_THROWS(F), erlunit:throws(fun() -> F end, ??F, ?MODULE, ?LINE )). 52 | 53 | 54 | %%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 55 | 56 | -define(ERLUNIT_SEQ_EQUAL_MSG(F, R, M), erlunit:equal(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 57 | -define(ERLUNIT_SEQ_EQUAL(F, R), erlunit:equal(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 58 | 59 | -define(ERLUNIT_SEQ_NOT_EQUAL_MSG(F, R, M), erlunit:not_equal(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 60 | -define(ERLUNIT_SEQ_NOT_EQUAL(F, R), erlunit:not_equal(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 61 | 62 | -define(ERLUNIT_SEQ_EXACT_MSG(F, R, M), erlunit:exact(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 63 | -define(ERLUNIT_SEQ_EXACT(F, R), erlunit:exact(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 64 | 65 | -define(ERLUNIT_SEQ_BIGGER_MSG(F, R, M), erlunit:bigger(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 66 | -define(ERLUNIT_SEQ_BIGGER(F, R), erlunit:bigger(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 67 | 68 | -define(ERLUNIT_SEQ_LESSER_MSG(F, R, M), erlunit:lesser(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 69 | -define(ERLUNIT_SEQ_LESSER(F, R), erlunit:lesser(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 70 | 71 | %%%-------------------------------------------------------------------------%%% 72 | %%% Message Passing Macros %%% 73 | %%%-------------------------------------------------------------------------%%% 74 | 75 | -define(ERLUNIT_TRUE_MSG(F, M), erlunit:true(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 76 | -define(ERLUNIT_TRUE(F), erlunit:true(fun() -> F end, ??F, ?MODULE, ?LINE )). 77 | 78 | -define(ERLUNIT_FALSE_MSG(F, M), erlunit:false(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 79 | -define(ERLUNIT_FALSE(F), erlunit:false(fun() -> F end, ??F, ?MODULE, ?LINE )). 80 | 81 | -define(ERLUNIT_NOT_TRUE_MSG(F, M), erlunit:not_true(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 82 | -define(ERLUNIT_NOT_TRUE(F), erlunit:not_true(fun() -> F end, ??F, ?MODULE, ?LINE )). 83 | 84 | -define(ERLUNIT_NOT_FALSE_MSG(F, M), erlunit:not_false(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 85 | -define(ERLUNIT_NOT_FALSE(F), erlunit:not_false(fun() -> F end, ??F, ?MODULE, ?LINE )). 86 | 87 | %%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 88 | 89 | -define(ERLUNIT_PASS_MSG(F, M), erlunit:pass(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 90 | -define(ERLUNIT_PASS(F), erlunit:pass(fun() -> F end, ??F, ?MODULE, ?LINE )). 91 | 92 | -define(ERLUNIT_FAIL_MSG(F, M), erlunit:fail(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 93 | -define(ERLUNIT_FAIL(F), erlunit:fail(fun() -> F end, ??F, ?MODULE, ?LINE )). 94 | 95 | -define(ERLUNIT_EXITS_MSG(F, M), erlunit:exits(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 96 | -define(ERLUNIT_EXITS(F), erlunit:exits(fun() -> F end, ??F, ?MODULE, ?LINE )). 97 | 98 | -define(ERLUNIT_ERROR_MSG(F, M), erlunit:error(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 99 | -define(ERLUNIT_ERROR(F), erlunit:error(fun() -> F end, ??F, ?MODULE, ?LINE )). 100 | 101 | -define(ERLUNIT_THROWS_MSG(F, M), erlunit:throws(fun() -> F end, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 102 | -define(ERLUNIT_THROWS(F), erlunit:throws(fun() -> F end, ??F, ?MODULE, ?LINE )). 103 | 104 | 105 | %%% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 106 | 107 | -define(ERLUNIT_EQUAL_MSG(F, R, M), erlunit:equal(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 108 | -define(ERLUNIT_EQUAL(F, R), erlunit:equal(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 109 | 110 | -define(ERLUNIT_NOT_EQUAL_MSG(F, R, M), erlunit:not_equal(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 111 | -define(ERLUNIT_NOT_EQUAL(F, R), erlunit:not_equal(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 112 | 113 | -define(ERLUNIT_EXACT_MSG(F, R, M), erlunit:exact(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 114 | -define(ERLUNIT_EXACT(F, R), erlunit:exact(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 115 | 116 | -define(ERLUNIT_BIGGER_MSG(F, R, M), erlunit:bigger(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 117 | -define(ERLUNIT_BIGGER(F, R), erlunit:bigger(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 118 | 119 | -define(ERLUNIT_LESSER_MSG(F, R, M), erlunit:lesser(fun() -> F end, R, M ++ " | " ++ ??F, ?MODULE, ?LINE )). 120 | -define(ERLUNIT_LESSER(F, R), erlunit:lesser(fun() -> F end, R, "Expect " ++ ??F ++ " == " ++ ??R, ?MODULE, ?LINE)). 121 | -------------------------------------------------------------------------------- /etc/test/depr/test1.erl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoltDB/voltdb-client-erlang/606ee807248f9fb7beaca982ae159d1becdf25d2/etc/test/depr/test1.erl -------------------------------------------------------------------------------- /etc/test/depr/test4.erl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoltDB/voltdb-client-erlang/606ee807248f9fb7beaca982ae159d1becdf25d2/etc/test/depr/test4.erl -------------------------------------------------------------------------------- /etc/test/dialyzer.mk: -------------------------------------------------------------------------------- 1 | # dialyzer.mk 2 | # Dialyzer runs, with or without profiler compiled in. 3 | # 4 | # dialyzer 5 | 6 | dialyzer: 7 | $(MAKE) $(LESSVERB) dialyzer-noprofile 8 | $(MAKE) $(LESSVERB) dialyzer-profile 9 | 10 | dialyzer-noprofile: clean all 11 | @(cd examples; $(MAKE) $(LESSVERB) hello-plus DEBUG=true) 12 | @(cd examples; $(MAKE) $(LESSVERB) hello-barebones DEBUG=true) 13 | @(cd examples; $(MAKE) $(LESSVERB) parallel DEBUG=true) 14 | @(cd examples; $(MAKE) $(LESSVERB) voter DEBUG=true) 15 | @echo The first run with dializer can take a minute for preparations 16 | @echo You should NOT have commented out the +debug_info flag in include.mk 17 | @# the following has to be that separeted out as dialyzer 18 | @# won't catch rebuilt modules using a different set of defines. 19 | @# also otherwise removed functions can persist in the plt. 20 | dialyzer --check_plt --apps erts kernel stdlib crypto 21 | dialyzer --remove_from_plt -r ebin/ 22 | dialyzer --add_to_plt -r ebin/ 23 | dialyzer -r ebin/ 24 | 25 | dialyzer-profile: clean profile-debug 26 | @(cd examples; $(MAKE) $(LESSVERB) hello-plus PROFILE=true DEBUG=true) 27 | @(cd examples; $(MAKE) $(LESSVERB) hello-barebones PROFILE=true DEBUG=true) 28 | @(cd examples; $(MAKE) $(LESSVERB) parallel PROFILE=true DEBUG=true) 29 | @(cd examples; $(MAKE) $(LESSVERB) voter PROFILE=true DEBUG=true) 30 | @echo The first run with dializer can take a minute for preparations 31 | @echo You should NOT have commented out the +debug_info flag in include.mk 32 | @# the following has to be that separeted out as dialyzer 33 | @# won't catch rebuilt modules using a different set of defines 34 | @# also otherwise removed functions can persist in the plt. 35 | dialyzer --check_plt --apps erts kernel stdlib crypto 36 | dialyzer --remove_from_plt -r ebin/ 37 | dialyzer --add_to_plt -r ebin/ 38 | dialyzer -r ebin/ 39 | -------------------------------------------------------------------------------- /etc/test/environment_SUITE.erl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% File : erlvolt/etc/test/environment_SUITE.erl 3 | %%% Descr : Suite #1 - testing the test setup, db and pathes = 4 | %%% availability of crypto app, erlvolt app and test db. 5 | %%% Author : H. Diedrich 6 | %%% Requires : Erlang 14B (prior may not have ct_run) 7 | %%%------------------------------------------------------------------- 8 | %%% 9 | %%% THIS SUITE DOES NO ACTUAL TESTS BUT CHECKS THE TEST DATABASE ETC. 10 | %%% Test Cases are in this high granularity for clear failure reports. 11 | %%% 12 | %%% Run from erlvolt/: 13 | %%% make test 14 | %%% 15 | %%% Results see: 16 | %%% etc/test/index.html 17 | %%% 18 | %%%------------------------------------------------------------------- 19 | 20 | -module(environment_SUITE). 21 | -compile(export_all). 22 | -include_lib("common_test/include/ct.hrl"). 23 | 24 | % List of test cases. 25 | % Test cases have self-explanatory names. 26 | %%-------------------------------------------------------------------- 27 | all() -> 28 | [initializing_crypto_app, 29 | initializing_erlvolt_app, 30 | accessing_erlvolt_module, 31 | connecting_to_db_and_creating_a_pool, 32 | insert, 33 | select 34 | ]. 35 | 36 | % nothing, but forces call of clean up 37 | %%-------------------------------------------------------------------- 38 | init_per_suite(Config) -> 39 | Config. 40 | 41 | % clean up 42 | %%-------------------------------------------------------------------- 43 | end_per_suite(_) -> 44 | erlvolt:close_pool(environment_test_pool), 45 | ok. 46 | 47 | % Test Case: Test if the crypt app is available. This detects a path error. 48 | %%-------------------------------------------------------------------- 49 | initializing_crypto_app(_) -> 50 | crypto:start(), 51 | ok. 52 | 53 | % Test Case: Test if the erlvolt app is available. This detects a path error. 54 | %%-------------------------------------------------------------------- 55 | initializing_erlvolt_app(_) -> 56 | application:start(erlvolt), 57 | ok. 58 | 59 | % Test Case: Test if the erlvolt module is available. This detects a path error. 60 | %%-------------------------------------------------------------------- 61 | accessing_erlvolt_module(_) -> 62 | erlvolt:modules(), 63 | ok. 64 | 65 | % Test Case: Test if we can connect to the test db and create a connection pool. 66 | %%-------------------------------------------------------------------- 67 | connecting_to_db_and_creating_a_pool(_) -> 68 | erlvolt:add_pool(environment_test_pool, [{"localhost", 21212}]), 69 | ok. 70 | 71 | 72 | % Test Case: Test if we can call a procedure, insert a record. 73 | %%-------------------------------------------------------------------- 74 | insert(_) -> 75 | erlvolt:call_procedure(environment_test_pool, "Initialize", [1,"Karl Egon"]), 76 | ok. 77 | 78 | % Test Case: Test if we can select, adhoc. 79 | %%-------------------------------------------------------------------- 80 | select(_) -> 81 | 82 | delete_all(), 83 | 84 | erlvolt:call_procedure(environment_test_pool, "Initialize", [2,"Karl, Egon"]), 85 | Result = erlvolt:call_procedure(environment_test_pool, "@AdHoc", ["select COUNT(*) as CNT from contestants"]), 86 | {result, { voltresponse, _, [ Table | _ ] }} = Result, 87 | Row = erlvolt:get_row(Table, 1), 88 | Count = erlvolt:get_integer(Row, Table, "CNT"), 89 | Count = 2, 90 | ok. 91 | 92 | delete_all() -> 93 | 94 | erlvolt:call_procedure(environment_test_pool, "@AdHoc", ["DELETE FROM contestants"]), 95 | erlvolt:call_procedure(environment_test_pool, "@AdHoc", ["DELETE FROM area_code_state"]), 96 | erlvolt:call_procedure(environment_test_pool, "@AdHoc", ["DELETE FROM votes"]). 97 | -------------------------------------------------------------------------------- /etc/test/maketest.mk: -------------------------------------------------------------------------------- 1 | # maketest.mk 2 | # Tests sequences of compile, example and bench makes. 3 | # 4 | # maketest-hello 5 | # maketest-hello-pre3 6 | # maketest-voter 7 | 8 | maketest-hello: 9 | $(MAKE) clean 10 | $(MAKE) hello 11 | $(MAKE) hello-plus 12 | $(MAKE) hello-barebones 13 | $(MAKE) parallel 14 | $(MAKE) bench-hsd 15 | : 16 | $(MAKE) clean all 17 | $(MAKE) hello 18 | $(MAKE) clean hello 19 | $(MAKE) clean all 20 | $(MAKE) hello-plus 21 | $(MAKE) clean hello-plus 22 | $(MAKE) clean all 23 | $(MAKE) hello-barebones 24 | $(MAKE) clean hello-barebones 25 | $(MAKE) clean all 26 | $(MAKE) parallel 27 | $(MAKE) clean parallel 28 | $(MAKE) bench-hsd 29 | : 30 | $(MAKE) clean fast 31 | $(MAKE) hello 32 | $(MAKE) hello-plus 33 | $(MAKE) hello-barebones 34 | $(MAKE) parallel 35 | $(MAKE) bench-hsd 36 | : 37 | $(MAKE) clean profile 38 | $(MAKE) hello 39 | $(MAKE) hello-plus 40 | $(MAKE) hello-barebones 41 | $(MAKE) parallel 42 | $(MAKE) bench-hsd 43 | : 44 | $(MAKE) clean profile 45 | $(MAKE) hello 46 | $(MAKE) hello-plus 47 | $(MAKE) hello-barebones 48 | $(MAKE) parallel 49 | $(MAKE) bench-hsd 50 | 51 | maketest-hello-pre3: 52 | $(MAKE) clean 53 | $(MAKE) hello 54 | $(MAKE) hello-plus 55 | $(MAKE) hello-barebones-pre3 56 | $(MAKE) parallel-pre3 57 | : 58 | $(MAKE) clean all 59 | $(MAKE) hello 60 | $(MAKE) clean hello 61 | $(MAKE) clean all 62 | $(MAKE) hello-plus 63 | $(MAKE) clean hello-plus 64 | $(MAKE) clean all 65 | $(MAKE) hello-barebones-pre3 66 | $(MAKE) clean hello-barebones-pre3 67 | $(MAKE) clean all 68 | $(MAKE) parallel-pre3 69 | $(MAKE) clean parallel-pre3 70 | : 71 | $(MAKE) clean fast 72 | $(MAKE) hello 73 | $(MAKE) hello-plus 74 | $(MAKE) hello-barebones-pre3 75 | $(MAKE) parallel-pre3 76 | : 77 | $(MAKE) clean profile 78 | $(MAKE) hello 79 | $(MAKE) hello-plus 80 | $(MAKE) hello-barebones-pre3 81 | $(MAKE) parallel-pre3 82 | : 83 | $(MAKE) clean profile 84 | $(MAKE) hello 85 | $(MAKE) hello-plus 86 | $(MAKE) hello-barebones-pre3 87 | $(MAKE) parallel-pre3 88 | 89 | maketest-voter: 90 | $(MAKE) clean all 91 | $(MAKE) voter 92 | $(MAKE) bench 93 | $(MAKE) benches 94 | $(MAKE) bench-mvm 95 | $(MAKE) bench-vsd 96 | $(MAKE) bench-vsm 97 | $(MAKE) bench-vbd 98 | $(MAKE) bench-vbm 99 | : 100 | $(MAKE) clean fast 101 | $(MAKE) voter 102 | $(MAKE) bench 103 | $(MAKE) benches 104 | $(MAKE) bench-mvm 105 | $(MAKE) bench-vsd 106 | $(MAKE) bench-vsm 107 | $(MAKE) bench-vbd 108 | $(MAKE) bench-vbm 109 | : 110 | $(MAKE) clean profile 111 | $(MAKE) voter 112 | $(MAKE) bench 113 | $(MAKE) benches 114 | $(MAKE) bench-mvm 115 | $(MAKE) bench-vsd 116 | $(MAKE) bench-vsm 117 | $(MAKE) bench-vbd 118 | $(MAKE) bench-vbm 119 | : 120 | $(MAKE) clean profile-debug 121 | $(MAKE) voter 122 | $(MAKE) bench 123 | $(MAKE) benches 124 | $(MAKE) bench-mvm 125 | $(MAKE) bench-vsd 126 | $(MAKE) bench-vsm 127 | $(MAKE) bench-vbd 128 | $(MAKE) bench-vbm 129 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | include ../etc/include.mk 2 | 3 | all: $(EXAMPLE_EBIN_FILES) 4 | @: 5 | 6 | %.beam: %.erl 7 | erlc -I ../include -o ../ebin +debug_info $< 8 | 9 | hello: $(EBIN_DIR)/hello.beam 10 | @: 11 | 12 | hello-barebones: $(EBIN_DIR)/hello.beam 13 | @: 14 | 15 | hello-barebones-pre3: $(EBIN_DIR)/hello_pre3.beam 16 | @: 17 | 18 | hello-plus: $(EBIN_DIR)/hello_plus.beam 19 | @: 20 | 21 | parallel: $(EBIN_DIR)/parallel.beam 22 | @: 23 | 24 | parallel-pre3: $(EBIN_DIR)/parallel_pre3.beam 25 | @: 26 | 27 | voter: $(EBIN_DIR)/voter.beam 28 | @: 29 | 30 | clean: 31 | @rm -rf $(EBIN_FILES) 32 | @rm -rf *.beam 33 | @rm -rf *.log 34 | @rm -rf *.dump 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/hello.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : examples/hello.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver minimal 'Hello, world!' example file %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 28 Apr 2012 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run this sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run this hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello-barebones # note the 'barebones' %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello.erl %%% 61 | %%% $ erl -pa ../ebin -s hello run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% For a slightly more comples example see examples/hello_plus.erl. %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | -module(hello). 80 | -export([run/0]). 81 | 82 | -include("erlvolt.hrl"). 83 | 84 | -author("H. Diedrich "). 85 | 86 | run() -> 87 | 88 | %%% 89 | %%% Start driver 90 | %%% 91 | 92 | crypto:start(), 93 | application:start(erlvolt), 94 | 95 | %%% 96 | %%% Connect 97 | %%% 98 | 99 | erlvolt:add_pool(hello_pool, [{"localhost", 21212}]), 100 | 101 | %%% 102 | %%% Load sample data into the database 103 | %%% 104 | 105 | erlvolt:call_procedure(hello_pool, "Insert", ["Swedish", "Hej", "världen"]), 106 | 107 | %%% 108 | %%% Query 109 | %%% 110 | 111 | Result = erlvolt:call_procedure(hello_pool, "Select", ["Swedish"]), 112 | %% note: the stored procedure is called 'Select'. 113 | 114 | %%% 115 | %%% Result 116 | %%% 117 | 118 | Table = erlvolt:get_table(Result, 1), 119 | Row = erlvolt:get_row(Table, 1), 120 | Hello = erlvolt:get_string(Row, Table, "HELLO"), 121 | World = erlvolt:get_string(Row, Table, "WORLD"), 122 | 123 | io:format("~n~s ~s!~n~n", [Hello, World]), 124 | 125 | %%% 126 | %%% Close 127 | %%% 128 | 129 | erlvolt:close_pool(hello_pool). 130 | 131 | -------------------------------------------------------------------------------- /examples/hello_plus.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : examples/hello_plus.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver robust 'Hello, world!' example file %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 28 Jan 2013 %%% 10 | %%% Changed : 05 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run this sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run this hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%%-------------------------------------------------------------------------%%% 68 | %%% %%% 69 | %%% For a barebones 'hello world' see examples/hello.erl. %%% 70 | %%% %%% 71 | %%%-------------------------------------------------------------------------%%% 72 | %%% %%% 73 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 74 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 75 | %%% %%% 76 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 77 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 78 | %%% %%% 79 | %%%-------------------------------------------------------------------------%%% 80 | 81 | -module(hello_plus). 82 | -export([run/0]). 83 | 84 | -include("erlvolt.hrl"). 85 | 86 | run() -> 87 | 88 | %%% 89 | %%% Start driver 90 | %%% 91 | 92 | crypto:start(), 93 | application:start(erlvolt), 94 | 95 | %%% 96 | %%% Connection Pool Parameter 97 | %%% 98 | 99 | Hosts = [{"localhost", 21212}], 100 | 101 | try 102 | 103 | %%% 104 | %%% Connect to the database 105 | %%% 106 | 107 | erlvolt:add_pool(hello_pool, Hosts, [blocking]), 108 | 109 | %%% 110 | %%% Load sample data into the database 111 | %%% 112 | 113 | % Find out if we are Volt pre-3.0 or not (changed order in hello sample) 114 | erlvolt:call_procedure(hello_pool, "@AdHoc", ["DELETE FROM helloworld"]), 115 | timer:sleep(200), 116 | erlvolt:call_procedure(hello_pool, "Insert", ["1", "2", "3"]), 117 | timer:sleep(200), 118 | VoltVersion = case erlvolt:call_procedure(hello_pool, "Select", ["1"]) of 119 | ?VOLT_EMPTY_RESPONSE -> 120 | 'pre-3'; 121 | _ -> 122 | '3+' 123 | end, 124 | 125 | % insert for Volt 3+ or earlier, respectively 126 | % this is not due to a Volt change, but only a change of the example 127 | R = case VoltVersion of 128 | 'pre-3' -> 129 | erlvolt:call_procedure(hello_pool, "Insert", ["Hello", "World", "English"]); 130 | '3+' -> 131 | erlvolt:call_procedure(hello_pool, "Insert", ["English", "Hello", "World"]) 132 | end, 133 | 134 | case erlvolt:get_status(R) of 135 | ?VOLT_SUCCESS -> ok; 136 | ?VOLT_GRACEFUL_FAILURE -> ok; % UNIQUE violation = database not restarted 137 | _ -> io:format("### Insert failed: ~p~n", [R]) 138 | end, 139 | 140 | % insert for Volt 3+ or earlier, respectively 141 | % this is not due to a Volt change, but only a change of the example 142 | R1 = case VoltVersion of 143 | 'pre-3' -> 144 | erlvolt:call_procedure(hello_pool, "Insert", ["Hej", "världen", "Swedish"]); 145 | '3+' -> 146 | erlvolt:call_procedure(hello_pool, "Insert", ["Swedish", "Hej", "världen"]) 147 | end, 148 | 149 | case erlvolt:get_status(R1) of 150 | ?VOLT_SUCCESS -> ok; 151 | ?VOLT_GRACEFUL_FAILURE -> ok; % UNIQUE violation = database not restarted 152 | _ -> io:format("### Insert failed: ~p~n", [R1]) 153 | end, 154 | 155 | %%% 156 | %%% Synchronous Query 157 | %%% 158 | 159 | Result = erlvolt:call_procedure(hello_pool, "Select", ["Swedish"]), 160 | 161 | %%% 162 | %%% Result 163 | %%% 164 | 165 | case Result of 166 | 167 | %% Expected result e.g.: 168 | %% {result, 169 | %% {voltresponse, 170 | %% {0, <<"<0.45.0>">>, 1, <<>>, 128, <<>>, <<>>, 1}, 171 | %% [{volttable, 172 | %% [<<"HELLO">>, <<"WORLD">>], 173 | %% "\t\t", 174 | %% [{voltrow, 175 | %% [<<"Hej">>, <<"världen">>]}]}]}} 176 | %% 177 | %% @type voltresponse() = 178 | %% 179 | %% { voltresponse, 180 | %% { Protocol, 181 | %% ClientData, 182 | %% Status, 183 | %% StatusString, 184 | %% AppStatus, 185 | %% AppStatusString, 186 | %% SerializedException, 187 | %% RoundTripTime }, 188 | %% [ volttable() ] 189 | %% }. 190 | %% @end 191 | 192 | ?VOLT_EMPTY_RESPONSE -> 193 | 194 | io:format("~nI can't say Hello in this language!~n"); 195 | 196 | ?VOLT_ERROR_MESSAGE("Procedure Select was not found") -> 197 | 198 | io:format("~nRunning the right database? (cd voltdb/doc/tutorials/hello && ./run.sh)~n~n"); 199 | 200 | {result, _ } -> 201 | 202 | %%% 203 | %%% Result 204 | %%% 205 | 206 | Table = erlvolt:get_table(Result, 1), 207 | Row = erlvolt:get_row(Table, 1), 208 | Hello = erlvolt:get_string(Row, Table, "HELLO"), 209 | World = erlvolt:get_string(Row, Table, "WORLD"), 210 | 211 | io:format("~n~s ~s!~n~n", [Hello, World]); 212 | 213 | %% unexpected 214 | Other -> 215 | io:format("Unexpected result ~p.", [Other]), 216 | exit(hello_bad_result) 217 | end, 218 | 219 | %%% 220 | %%% Close database connection 221 | %%% 222 | 223 | erlvolt:close_pool(hello_pool) 224 | 225 | catch 226 | 227 | %%% 228 | %%% Exceptions 229 | %%% 230 | 231 | throw:{ connection_failed, _}=_Why -> 232 | io:format("~n------------------------------------------------------------------------------------~n"), 233 | io:format("Failed to open server connection.~nIs the VoltDB server running and accessible?"), 234 | io:format("~n------------------------------------------------------------------------------------~n"); 235 | 236 | What:Why -> 237 | io:format("~n ~w ~w ~n ~p", [What, Why, erlang:get_stacktrace()]), 238 | exit({What, Why}) 239 | end. 240 | -------------------------------------------------------------------------------- /examples/hello_pre3.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : examples/hello.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver minimal 'Hello, world!' example file %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 28 Apr 2012 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run this sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run this hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello-barebones-pre3 # note the 'barebones' %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_pre3.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_pre3 run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% For a slightly more comples example see examples/hello_plus.erl. %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | -module(hello_pre3). 80 | -export([run/0]). 81 | 82 | -include("erlvolt.hrl"). 83 | 84 | -author("H. Diedrich "). 85 | 86 | run() -> 87 | 88 | %%% 89 | %%% Start driver 90 | %%% 91 | 92 | crypto:start(), 93 | application:start(erlvolt), 94 | 95 | %%% 96 | %%% Connect 97 | %%% 98 | 99 | erlvolt:add_pool(hello_pool, [{"localhost", 21212}]), 100 | 101 | %%% 102 | %%% Load sample data into the database 103 | %%% 104 | 105 | erlvolt:call_procedure(hello_pool, "Insert", ["Hej", "världen", "Swedish"]), 106 | 107 | %%% 108 | %%% Query 109 | %%% 110 | 111 | Result = erlvolt:call_procedure(hello_pool, "Select", ["Swedish"]), 112 | %% note: the stored procedure is called 'Select'. 113 | 114 | %%% 115 | %%% Result 116 | %%% 117 | 118 | Table = erlvolt:get_table(Result, 1), 119 | Row = erlvolt:get_row(Table, 1), 120 | Hello = erlvolt:get_string(Row, Table, "HELLO"), 121 | World = erlvolt:get_string(Row, Table, "WORLD"), 122 | 123 | io:format("~n~s ~s!~n~n", [Hello, World]), 124 | 125 | %%% 126 | %%% Close 127 | %%% 128 | 129 | erlvolt:close_pool(hello_pool). 130 | 131 | -------------------------------------------------------------------------------- /examples/parallel.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : examples/parallel.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver parallel 'Hello, world!' example %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 28 Jan 2013 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run this sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run this hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make parallel %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info parallel.erl %%% 61 | %%% $ erl -pa ../ebin -s parallel run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in a couple of languages: %%% 64 | %%% %%% 65 | %%% Hello Sample %%% 66 | %%% ---------------------------------------------------------------- %%% 67 | %%% I. start %%% 68 | %%% III. insert samples %%% 69 | %%% IV. select %%% 70 | %%% V. receive %%% 71 | %%% ---------------------------------------------------------------- %%% 72 | %%% .... Hello World! %%% 73 | %%% .... Hej världen! %%% 74 | %%% .... Hola mundo! %%% 75 | %%% .... Hallo Welt! %%% 76 | %%% .... Hello wereld! %%% 77 | %%% .... Salut tout le monde! %%% 78 | %%% .... Ciao mondo! %%% 79 | %%% .... Go' vIvan! %%% 80 | %%% .... Aiya arda! %%% 81 | %%% .... :-) (+)! %%% 82 | %%% ---------------------------------------------------------------- %%% 83 | %%% VI. close pool %%% 84 | %%% %%% 85 | %%%-------------------------------------------------------------------------%%% 86 | %%% %%% 87 | %%% For a barebones 'hello world' see examples/hello.erl. %%% 88 | %%% %%% 89 | %%%-------------------------------------------------------------------------%%% 90 | %%% %%% 91 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 92 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 93 | %%% %%% 94 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 95 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 96 | %%% %%% 97 | %%%-------------------------------------------------------------------------%%% 98 | 99 | -module(parallel). 100 | -export([run/0]). 101 | 102 | -include("erlvolt.hrl"). 103 | 104 | run() -> 105 | 106 | %%% 107 | %%% Start driver 108 | %%% 109 | 110 | io:format("~n~nParallel Sample~n"), 111 | io:format("-----------------------------------------------------------------------~n"), 112 | 113 | io:format("I. start~n"), 114 | crypto:start(), 115 | application:start(erlvolt), 116 | 117 | %%% 118 | %%% Connect to the database 119 | %%% 120 | 121 | erlvolt:add_pool(hello_pool, [{"localhost", 21212}], []), 122 | 123 | %%% 124 | %%% Load sample data into the database 125 | %%% 126 | 127 | io:format("III. insert samples~n"), 128 | erlvolt:call_procedure(hello_pool, "Insert", ["English", "Hello", "World"]), 129 | erlvolt:call_procedure(hello_pool, "Insert", ["Swedish", "Hej", "v‰rlden"]), 130 | erlvolt:call_procedure(hello_pool, "Insert", ["Spanish", "Hola", "mundo"]), 131 | erlvolt:call_procedure(hello_pool, "Insert", ["German", "Hallo", "Welt"]), 132 | erlvolt:call_procedure(hello_pool, "Insert", ["Dutch", "Hello", "wereld"]), 133 | erlvolt:call_procedure(hello_pool, "Insert", ["French", "Salut", "tout le monde"]), 134 | erlvolt:call_procedure(hello_pool, "Insert", ["Italian", "Ciao", "mondo"]), 135 | erlvolt:call_procedure(hello_pool, "Insert", ["Klingon", "Go'", "vIvan"]), 136 | erlvolt:call_procedure(hello_pool, "Insert", ["Quenya", "Aiya", "arda"]), 137 | erlvolt:call_procedure(hello_pool, "Insert", ["Smiley", ":-)", "(+)"]), 138 | 139 | %%% 140 | %%% Asynchronous Query 141 | %%% 142 | 143 | Languages = ["English","Swedish","Spanish","German","Dutch","French","Italian","Klingon","Quenya","Smiley"], 144 | 145 | io:format("IV. select~n"), 146 | 147 | [ ok = erlvolt:call_procedure(hello_pool, "Select", [Language], [asynchronous]) 148 | || Language <- Languages ], 149 | 150 | 151 | %%% 152 | %%% Results 153 | %%% 154 | 155 | io:format("V. receive~n"), 156 | io:format("-----------------------------------------------------------------------~n"), 157 | 158 | [ receive 159 | ?VOLT_ERROR_MESSAGE("Procedure Select was not found") -> 160 | io:format("~nRunning the right database? (cd voltdb/doc/tutorials/hello && ./run.sh)~n~n"); 161 | 162 | Result -> 163 | Table = erlvolt:get_table(Result, 1), 164 | Row = erlvolt:get_row(Table, 1), 165 | Hello = erlvolt:get_string(Row, Table, "HELLO"), 166 | World = erlvolt:get_string(Row, Table, "WORLD"), 167 | io:format(".... ~s ~s!~n", [Hello, World]) 168 | end 169 | || _ <- Languages ], 170 | io:format("-----------------------------------------------------------------------~n"), 171 | 172 | %%% 173 | %%% Close database connection 174 | %%% 175 | 176 | io:format("VI. close pool~n"), 177 | erlvolt:close_pool(hello_pool). 178 | -------------------------------------------------------------------------------- /examples/parallel_pre3.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : examples/parallel.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver parallel 'Hello, world!' example %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 28 Jan 2013 %%% 10 | %%% Changed : 06 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run this sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run this hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make parallel-pre3 %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info parallel_pre3.erl %%% 61 | %%% $ erl -pa ../ebin -s parallel_pre3 run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in a couple of languages: %%% 64 | %%% %%% 65 | %%% Hello Sample %%% 66 | %%% ---------------------------------------------------------------- %%% 67 | %%% I. start %%% 68 | %%% III. insert samples %%% 69 | %%% IV. select %%% 70 | %%% V. receive %%% 71 | %%% ---------------------------------------------------------------- %%% 72 | %%% .... Hello World! %%% 73 | %%% .... Hej världen! %%% 74 | %%% .... Hola mundo! %%% 75 | %%% .... Hallo Welt! %%% 76 | %%% .... Hello wereld! %%% 77 | %%% .... Salut tout le monde! %%% 78 | %%% .... Ciao mondo! %%% 79 | %%% .... Go' vIvan! %%% 80 | %%% .... Aiya arda! %%% 81 | %%% .... :-) (+)! %%% 82 | %%% ---------------------------------------------------------------- %%% 83 | %%% VI. close pool %%% 84 | %%% %%% 85 | %%%-------------------------------------------------------------------------%%% 86 | %%% %%% 87 | %%% For a barebones 'hello world' see examples/hello.erl. %%% 88 | %%% %%% 89 | %%%-------------------------------------------------------------------------%%% 90 | %%% %%% 91 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 92 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 93 | %%% %%% 94 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 95 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 96 | %%% %%% 97 | %%%-------------------------------------------------------------------------%%% 98 | 99 | -module(parallel_pre3). 100 | -export([run/0]). 101 | 102 | -include("erlvolt.hrl"). 103 | 104 | run() -> 105 | 106 | %%% 107 | %%% Start driver 108 | %%% 109 | 110 | io:format("~n~nParallel Sample pre VoltDB 3.0 (Different Hello World Sample Table)~n"), 111 | io:format("-----------------------------------------------------------------------~n"), 112 | 113 | io:format("I. start~n"), 114 | crypto:start(), 115 | application:start(erlvolt), 116 | 117 | %%% 118 | %%% Connect to the database 119 | %%% 120 | 121 | erlvolt:add_pool(hello_pool, [{"localhost", 21212}], []), 122 | 123 | %%% 124 | %%% Load sample data into the database 125 | %%% 126 | 127 | io:format("III. insert samples~n"), 128 | erlvolt:call_procedure(hello_pool, "Insert", ["Hello", "World", "English"]), 129 | erlvolt:call_procedure(hello_pool, "Insert", ["Hej", "världen", "Swedish"]), 130 | erlvolt:call_procedure(hello_pool, "Insert", ["Hola", "mundo", "Spanish"]), 131 | erlvolt:call_procedure(hello_pool, "Insert", ["Hallo", "Welt", "German"]), 132 | erlvolt:call_procedure(hello_pool, "Insert", ["Hello", "wereld", "Dutch"]), 133 | erlvolt:call_procedure(hello_pool, "Insert", ["Salut", "tout le monde", "French"]), 134 | erlvolt:call_procedure(hello_pool, "Insert", ["Ciao", "mondo", "Italian"]), 135 | erlvolt:call_procedure(hello_pool, "Insert", ["Go'", "vIvan", "Klingon"]), 136 | erlvolt:call_procedure(hello_pool, "Insert", ["Aiya", "arda", "Quenya"]), 137 | erlvolt:call_procedure(hello_pool, "Insert", [":-)", "(+)", "Smiley"]), 138 | 139 | %%% 140 | %%% Asynchronous Query 141 | %%% 142 | 143 | Languages = ["English","Swedish","Spanish","German","Dutch","French","Italian","Klingon","Quenya","Smiley"], 144 | 145 | io:format("IV. select~n"), 146 | 147 | [ ok = erlvolt:call_procedure(hello_pool, "Select", [Language], [asynchronous]) 148 | || Language <- Languages ], 149 | 150 | 151 | %%% 152 | %%% Results 153 | %%% 154 | 155 | io:format("V. receive~n"), 156 | io:format("-----------------------------------------------------------------------~n"), 157 | 158 | [ receive 159 | ?VOLT_ERROR_MESSAGE("Procedure Select was not found") -> 160 | io:format("~nRunning the right database? (cd voltdb/doc/tutorials/hello && ./run.sh)~n~n"); 161 | 162 | Result -> 163 | Table = erlvolt:get_table(Result, 1), 164 | Row = erlvolt:get_row(Table, 1), 165 | Hello = erlvolt:get_string(Row, Table, "HELLO"), 166 | World = erlvolt:get_string(Row, Table, "WORLD"), 167 | io:format(".... ~s ~s!~n", [Hello, World]) 168 | end 169 | || _ <- Languages ], 170 | io:format("-----------------------------------------------------------------------~n"), 171 | 172 | %%% 173 | %%% Close database connection 174 | %%% 175 | 176 | io:format("VI. close pool~n"), 177 | erlvolt:close_pool(hello_pool). 178 | -------------------------------------------------------------------------------- /include/erlvolt.hrl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt.hrl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver data structures and macros %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 13 Apr 2012 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | %%%---------------------------------------------------------------------------- 80 | %%% Response Patterns: Macros 81 | %%%---------------------------------------------------------------------------- 82 | 83 | -define(VOLT_OK, {result, {voltresponse, {0, _, 1, <<>>, 128, <<>>, <<>>, _}, []}}). 84 | -define(VOLT_ERROR_MESSAGE(T), {result,{voltresponse,{_,_,_,<>,_,_,_,_},[]}}). 85 | -define(VOLT_EMPTY_RESPONSE, {result, {voltresponse, {0, _, 1, <<>>, 128, <<>>, <<>>, _}, [{volttable,_,_,[]}]}}). 86 | 87 | %%%---------------------------------------------------------------------------- 88 | %%% Procedure Call Status Code 89 | %%%---------------------------------------------------------------------------- 90 | 91 | % A Byte value specifying the success or failure of a remote stored procedure call. 92 | % * SUCCESS = 1 93 | % * USER_ABORT = -1 94 | % * GRACEFUL_FAILURE = -2 95 | % * UNEXPECTED_FAILURE = -3 96 | % * CONNECTION_LOST = -4 97 | 98 | %%%---------------------------------------------------------------------------- 99 | 100 | -define(VOLT_SUCCESS, 1). 101 | -define(VOLT_USER_ABORT, -1). 102 | -define(VOLT_GRACEFUL_FAILURE, -2). 103 | -define(VOLT_UNEXPECTED_FAILURE, -3). 104 | -define(VOLT_CONNECTION_LOST, -4). 105 | 106 | %%%---------------------------------------------------------------------------- 107 | %%% Optional Verbose Debug Traces: Macros 108 | %%%---------------------------------------------------------------------------- 109 | 110 | -define(TRACE(S), void). 111 | -define(TRACE(F,S), void). 112 | %-define(TRACE(S), erlvolt:trace(S)). 113 | %-define(TRACE(F,S), erlvolt:trace(F,S)). 114 | 115 | %%%---------------------------------------------------------------------------- 116 | %%% Optional Profiler: Macros 117 | %%%---------------------------------------------------------------------------- 118 | 119 | -ifdef(profile). 120 | 121 | -define(ERLVOLT_PROFILER_COUNT_PENDING(), erlvolt_profiler:count_pending()). 122 | -define(ERLVOLT_PROFILER_COUNT_SUCCESS(), erlvolt_profiler:count_success()). 123 | -define(ERLVOLT_PROFILER_COUNT_SUCCESS(T), erlvolt_profiler:count_success(T)). 124 | -define(ERLVOLT_PROFILER_COUNT_FAILURE(), erlvolt_profiler:count_failure()). 125 | -define(ERLVOLT_PROFILER_COUNT_FAILURE(T), erlvolt_profiler:count_failure(T)). 126 | -define(ERLVOLT_PROFILER_COUNT_QUEUED(), erlvolt_profiler:count_queued()). 127 | -define(ERLVOLT_PROFILER_COUNT_UNQUEUED(), erlvolt_profiler:count_unqueued()). 128 | -define(ERLVOLT_PROFILER_COUNT_UNQUEUED(T), erlvolt_profiler:count_unqueued(T)). 129 | -define(ERLVOLT_PROFILER_DUMP(ClientID), erlvolt_profiler:dump(ClientID)). 130 | -define(ERLVOLT_PROFILER_DUMP_FUNCTION, dump). 131 | -define(ERLVOLT_PROFILER_PENDING(), erlvolt_profiler:pending()). 132 | -define(ERLVOLT_PROFILER_QUEUED(), erlvolt_profiler:queued()). 133 | -define(ERLVOLT_PROFILER_WAITQUEUED(N), erlvolt_profiler:waitqueued(N)). 134 | -define(ERLVOLT_PROFILER_WAITPENDING(N), erlvolt_profiler:waitpending(N)). 135 | -define(ERLVOLT_PROFILER_CR, "~n"). 136 | -define(ERLVOLT_PROFILER_NCR, ""). 137 | 138 | -else. 139 | 140 | -define(ERLVOLT_PROFILER_COUNT_PENDING(), void). 141 | -define(ERLVOLT_PROFILER_COUNT_SUCCESS(), void). 142 | -define(ERLVOLT_PROFILER_COUNT_SUCCESS(T), void). 143 | -define(ERLVOLT_PROFILER_COUNT_FAILURE(), void). 144 | -define(ERLVOLT_PROFILER_COUNT_FAILURE(T), void). 145 | -define(ERLVOLT_PROFILER_COUNT_QUEUED(), void). 146 | -define(ERLVOLT_PROFILER_COUNT_UNQUEUED(), void). 147 | -define(ERLVOLT_PROFILER_COUNT_UNQUEUED(T), void). 148 | -define(ERLVOLT_PROFILER_DUMP(ClientID), void). 149 | -define(ERLVOLT_PROFILER_DUMP_FUNCTION, dummy). 150 | -define(ERLVOLT_PROFILER_PENDING(), void). 151 | -define(ERLVOLT_PROFILER_QUEUED(), void). 152 | -define(ERLVOLT_PROFILER_WAITQUEUED(N), void). 153 | -define(ERLVOLT_PROFILER_WAITPENDING(N), void). 154 | -define(ERLVOLT_PROFILER_CR, ""). 155 | -define(ERLVOLT_PROFILER_NCR, "~n"). 156 | 157 | -endif. 158 | 159 | -------------------------------------------------------------------------------- /include/erlvolt_wire.hrl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt_wire.hrl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver wire protocol constants %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 25 Apr 2010 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | 80 | %*****************************************************************************% 81 | % Message Headers % 82 | %*****************************************************************************% 83 | 84 | -define(VOLT_HEADER_TYPE, 8/integer). % Note: _TYPE means Erlang binary type. 85 | % Change this type if (***) is ever changed to be non-implicit. 86 | 87 | -define(VOLT_PROTOCOL_VERSION, 0). 88 | -define(VOLT_PROTOCOL_VERSION_TYPE, 8/integer-big). 89 | -define(VOLT_PROTOCOL_VERSION_BINARY, <>). 90 | 91 | 92 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 93 | %%% %%% 94 | %%% BASIC TYPES %%% 95 | %%% %%% 96 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 97 | 98 | 99 | %*****************************************************************************% 100 | % Strings % 101 | %*****************************************************************************% 102 | % % 103 | % Strings begin with a 4-byte integer storing the number of bytes of char- % 104 | % acter data, followed by the character data. % 105 | % % 106 | % --- Pg. 2, VoltDB Client Wire Protocol Version 0, 05/05/10 --- % 107 | % % 108 | % Erlang default is big endian. Erlang default <<>> scan type is integer. % 109 | % % 110 | %****************************************************************************** 111 | 112 | -define(VOLT_STRING_SIZE_BINARY_TYPE, 32/big-signed). 113 | -define(VOLT_STRING_BINARY(B), Size:?VOLT_STRING_SIZE_BINARY_TYPE, B:Size/binary). 114 | -define(VOLT_STRING_BINARY_W_SIZE(B,Size), Size:?VOLT_STRING_SIZE_BINARY_TYPE, B:Size). 115 | 116 | -define(VOLT_STRING_NULL, -1:?VOLT_STRING_SIZE_BINARY_TYPE). 117 | -define(VOLT_STRING_EMPTY, 0:?VOLT_STRING_SIZE_BINARY_TYPE). 118 | 119 | -define(VOLT_MAX_STRING_SIZE, 1000000). 120 | 121 | %%%---------------------------------------------------------------------------- 122 | %%% VoltDB (Java) Float NaN Bit Patterns 123 | %%%---------------------------------------------------------------------------- 124 | 125 | % IEEE 754 does not define 'the' bit pattern for, e.g. NaN. But Java does. 126 | % There are many bit patterns that are NaN, meaning, they don't have a 127 | % meaningful value as float numbers. But again, Java defines one as 'the' NaN. 128 | 129 | % Home ª Open-JDK-6.b17-src ª java ª lang ª source 130 | % ... 131 | % 48 * @since JDK1.0 132 | % 49 */ 133 | % 50 public final class Float extends Number implements Comparable { 134 | % 51 /** 135 | % 52 * A constant holding the positive infinity of type 136 | % 53 * {@code float}. It is equal to the value returned by 137 | % 54 * {@code Float.intBitsToFloat(0x7f800000)}. 138 | % 55 */ 139 | % 56 public static final float POSITIVE_INFINITY = 1.0f / 0.0f; 140 | % 57 141 | % 58 /** 142 | % 59 * A constant holding the negative infinity of type 143 | % 60 * {@code float}. It is equal to the value returned by 144 | % 61 * {@code Float.intBitsToFloat(0xff800000)}. 145 | % 62 */ 146 | % 63 public static final float NEGATIVE_INFINITY = -1.0f / 0.0f; 147 | % 64 148 | % 65 /** 149 | % 66 * A constant holding a Not-a-Number (NaN) value of type 150 | % 67 * {@code float}. It is equivalent to the value returned by 151 | % 68 * {@code Float.intBitsToFloat(0x7fc00000)}. 152 | % 69 */ 153 | % 70 public static final float NaN = 0.0f / 0.0f; 154 | % ... 155 | % - http://www.docjar.com/html/api/java/lang/Float.java.html 156 | 157 | %%%---------------------------------------------------------------------------- 158 | 159 | -define(VOLT_NAN, <<16#7fc00000:32>>). 160 | -define(VOLT_POSITIVE_INFINITY, <<16#7f800000:32>>). 161 | -define(VOLT_NEGATIVE_INFINITY, <<16#ff800000:32>>). 162 | 163 | 164 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 165 | 166 | 167 | %%%---------------------------------------------------------------------------- 168 | %%% VoltDB Integer Limits 169 | %%%---------------------------------------------------------------------------- 170 | 171 | % http://en.wikipedia.org/wiki/Integer_%28computer_science%29 172 | % Erlang has not limits for integers at all. 173 | 174 | -define(VOLT_BYTE_MIN, -128). 175 | -define(VOLT_BYTE_MAX, 127). 176 | -define(VOLT_SHORT_MIN, -32768). 177 | -define(VOLT_SHORT_MAX, 32767). 178 | -define(VOLT_INTEGER_MIN, -2147483648). 179 | -define(VOLT_INTEGER_MAX, 2147483647). 180 | -define(VOLT_LONG_MIN, -9223372036854775808). 181 | -define(VOLT_LONG_MAX, 9223372036854775807). 182 | 183 | 184 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 185 | 186 | 187 | %%%---------------------------------------------------------------------------- 188 | %%% VoltDB Decimal Null and Limits 189 | %%%---------------------------------------------------------------------------- 190 | 191 | % VoltDB: "Null is serialized as the smallest representable value which is 192 | % -170141183460469231731687303715884105728. Serializing values (Null excluded) 193 | % that are greater than 99999999999999999999999999999999999999 or less than 194 | % -99999999999999999999999999999999999999 will result in an error response. 195 | 196 | -define(VOLT_DECIMAL_BINARY_TYPE(E), <>). 197 | 198 | -define(VOLT_DECIMAL_MAX, 99999999999999999999999999999999999999). 199 | -define(VOLT_DECIMAL_MIN, -99999999999999999999999999999999999999). 200 | -define(VOLT_DECIMAL_NULL, -170141183460469231731687303715884105728). 201 | 202 | 203 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 204 | 205 | 206 | %%%---------------------------------------------------------------------------- 207 | %%% Application Specific Data Types 208 | %%%---------------------------------------------------------------------------- 209 | 210 | % A Byte value specifying the type of a serialized value on the wire. 211 | % * ARRAY = -99 212 | % * NULL = 1 213 | % * TINYINT = 3 214 | % * SMALLINT = 4 215 | % * INTEGER = 5 216 | % * BIGINT = 6 217 | % * FLOAT = 8 218 | % * STRING = 9 219 | % * TIMESTAMP = 11 220 | % * DECIMAL = 22 221 | 222 | %%%---------------------------------------------------------------------------- 223 | 224 | -define(VOLT_ARRAY, -99). 225 | -define(VOLT_NULL, 1). 226 | -define(VOLT_TINYINT, 3). 227 | -define(VOLT_SMALLINT, 4). 228 | -define(VOLT_SHORTINT, 4). 229 | -define(VOLT_INTEGER, 5). 230 | -define(VOLT_INTINT, 5). 231 | -define(VOLT_BIGINT, 6). 232 | -define(VOLT_FLOAT, 8). 233 | -define(VOLT_STRING, 9). 234 | -define(VOLT_TIMESTAMP, 11). 235 | -define(VOLT_DECIMAL, 22). 236 | 237 | %%%---------------------------------------------------------------------------- 238 | 239 | -define(VOLT_TINYINT_TYPE, 8/big-signed). 240 | -define(VOLT_SMALLINT_TYPE, 16/big-signed). 241 | -define(VOLT_SHORTINT_TYPE, 16/big-signed). 242 | -define(VOLT_INTEGER_TYPE, 32/big-signed). 243 | -define(VOLT_INTINT_TYPE, 32/big-signed). 244 | -define(VOLT_BIGINT_TYPE, 64/big-signed). 245 | -define(VOLT_FLOAT_TYPE, 32/float-big-signed). 246 | -define(VOLT_TIMESTAMP_TYPE, 64/big-signed). 247 | -define(VOLT_DECIMAL_TYPE, 128/big-signed). 248 | 249 | %%%---------------------------------------------------------------------------- 250 | 251 | -define(VOLT_TINYINT_WIRE_BYTES, 1). 252 | -define(VOLT_SMALLINT_WIRE_BYTES, 2). 253 | -define(VOLT_SHORTINT_WIRE_BYTES, 2). % 254 | -define(VOLT_INTEGER_WIRE_BYTES, 4). 255 | -define(VOLT_INTINT_WIRE_BYTES, 4). % 256 | -define(VOLT_BIGINT_WIRE_BYTES, 8). 257 | -define(VOLT_FLOAT_WIRE_BYTES, 4). 258 | -define(VOLT_TIMESTAMP_WIRE_BYTES, 8). 259 | -define(VOLT_DECIMAL_WIRE_BYTES, 16). 260 | 261 | %%%---------------------------------------------------------------------------- 262 | 263 | -define(VOLT_FLOAT_BINARY, 4/binary). 264 | -define(VOLT_TIMESTAMP_BINARY, 8/binary). 265 | -define(VOLT_DECIMAL_BINARY, 16/binary). 266 | 267 | %%%------------------------------------%------------------------------------%%% 268 | -------------------------------------------------------------------------------- /priv/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VoltDB/voltdb-client-erlang/606ee807248f9fb7beaca982ae159d1becdf25d2/priv/empty -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | include ../etc/include.mk 2 | 3 | all: $(EBIN_FILES) 4 | @: 5 | 6 | fast: $(EBIN_FILES) 7 | 8 | clean: 9 | @rm -rf $(EBIN_FILES) 10 | 11 | -------------------------------------------------------------------------------- /src/erlvolt.app.src: -------------------------------------------------------------------------------- 1 | %% Erlang Application (.app) file-template 2 | %% This template is filled in by a sed call in ./Makefile 3 | %% and then copied over to ebin/erlvolt.app. 4 | 5 | {application, erlvolt, [ 6 | {description, "Erlvolt - Erlang VoltDB driver"}, 7 | {vsn, "0.3.3"}, 8 | {modules, []}, 9 | {mod, {erlvolt_app, ["%MAKETIME%"]}}, 10 | {registered, []}, 11 | {applications, [kernel, stdlib, crypto]}, 12 | {env, []} 13 | ]}. 14 | -------------------------------------------------------------------------------- /src/erlvolt_app.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt_app.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver application module %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 13 Apr 2012 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | -module(erlvolt_app). 80 | -behaviour(application). 81 | 82 | -vsn("0.3/beta"). 83 | -author("H. Diedrich "). 84 | -license("MIT - http://www.opensource.org/licenses/mit-license.php"). 85 | -copyright("(c) 2010-12 VoltDB, LLC - http://www.voltdb.com"). 86 | 87 | -define(VERSION, "0.3/beta"). 88 | -define(LIBRARY, "Erlvolt"). 89 | -define(EXPLAIN, "Erlang VoltDB driver"). 90 | 91 | -export([start/2, stop/1, modules/0]). 92 | 93 | -include("erlvolt.hrl"). 94 | -include("erlvolt_internal.hrl"). 95 | 96 | %% @spec start(any(),any()) -> 'ignore' | {'error',any()} | {'ok',pid()} 97 | start(_Type, _StartArgs) -> 98 | % start the supervisors (3 in erlvolt_sup) 99 | erlvolt:trace("#1 erlvolt_app:start/2"), 100 | erlvolt_sup:start_link(). 101 | 102 | %% @spec stop(any()) -> 'ok' 103 | stop(_State) -> 104 | erlvolt:trace("#100 erlvolt_app:stop/1"), 105 | erlvolt_conn_mgr:close_pools(). 106 | 107 | %% @spec modules() -> any() 108 | modules() -> 109 | {ok, Modules} = application_controller:get_key(erlvolt, modules), Modules. 110 | -------------------------------------------------------------------------------- /src/erlvolt_internal.hrl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt_internal.hrl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver internal records header %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 05 Feb 2013 %%% 10 | %%% Changed : 05 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | 80 | %%%---------------------------------------------------------------------------- 81 | %%% Records 82 | %%%---------------------------------------------------------------------------- 83 | 84 | 85 | -record(pool, { 86 | pool_id, 87 | size, 88 | user, 89 | password, 90 | hosts, 91 | service, 92 | timeout, 93 | queue_size, 94 | slots, 95 | nagle, 96 | send_buffer, 97 | receive_buffer, 98 | send_timeout, 99 | available = queue:new(), 100 | waiting = queue:new() 101 | }). 102 | 103 | -record(erlvolt_connection, { 104 | id, 105 | pid, 106 | pool_id, 107 | slots, 108 | nagle, 109 | send_buffer, 110 | receive_buffer, 111 | send_timeout, 112 | pending = 0, 113 | alive = true 114 | }). 115 | 116 | -record(erlvolt_slot, { 117 | id, 118 | connection_id, 119 | connection_pid, 120 | pool_id, 121 | granted = erlang:now(), 122 | left = undefined, 123 | sent = false, 124 | pending = false, 125 | done = false 126 | }). 127 | 128 | -record(erlvolt_profile, { 129 | p = 0, 130 | t0 = 0, 131 | n = 0, 132 | c = 0, 133 | s = 0, 134 | e = 0, 135 | x = 0, 136 | al = 0, 137 | xl = 0, 138 | q = 0, 139 | ql = 0 140 | }). 141 | -------------------------------------------------------------------------------- /src/erlvolt_profiler.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt_profiler.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver query profiler %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 13 Jan 2013 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | -module(erlvolt_profiler). 80 | -behaviour(gen_server). 81 | 82 | -vsn("0.3/beta"). 83 | -author("H. Diedrich "). 84 | -license("MIT - http://www.opensource.org/licenses/mit-license.php"). 85 | -copyright("(c) 2010-12 VoltDB, LLC - http://www.voltdb.com"). 86 | 87 | -define(VERSION, "0.3/beta"). 88 | -define(LIBRARY, "Erlvolt"). 89 | -define(EXPLAIN, "Erlang VoltDB driver"). 90 | 91 | -export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2]). 92 | -export([terminate/2, code_change/3]). 93 | -export([reset/0,test/0,ts/1,abri/1,dummy/0,dummy/1]). 94 | -ifdef(profile). 95 | -export([pending/0, queued/0, 96 | count_pending/0, count_success/0, count_success/1, count_failure/0, count_failure/1, 97 | count_queued/0, count_unqueued/0, count_unqueued/1, 98 | dump/1, waitpending/1, waitqueued/1]). 99 | -endif. 100 | 101 | -include("erlvolt.hrl"). 102 | -include("erlvolt_internal.hrl"). 103 | 104 | % -record(state, {now,lap}). 105 | 106 | %%==================================================================== 107 | %% API 108 | %%==================================================================== 109 | %%-------------------------------------------------------------------- 110 | %% Function: start_link() -> {ok,Pid} | ignore | {error,Error} 111 | %% Description: Starts the server 112 | %%-------------------------------------------------------------------- 113 | %% @spec start_link() -> 'ignore' | {'error',any()} | {'ok',pid()} 114 | start_link() -> 115 | ?TRACE("#3 erlvolt_profiler:start_link/0"), 116 | gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 117 | 118 | %% @spec test() -> any() 119 | test() -> 120 | gen_server:call(?MODULE, test, infinity), 121 | call(test). 122 | 123 | -ifdef(profile). 124 | 125 | %% @spec reset() -> ok 126 | reset() -> 127 | cast(reset). 128 | 129 | %% @spec count_pending() -> ok 130 | count_pending() -> 131 | cast({count_pending}). 132 | 133 | %% @spec count_success() -> ok 134 | count_success() -> 135 | cast({count_success}). 136 | 137 | %% @spec count_success(T::time()) -> ok 138 | count_success(T) -> 139 | cast({count_success,T}). 140 | 141 | %% @spec count_failure() -> ok 142 | count_failure() -> 143 | cast({count_failure}). 144 | 145 | %% @spec count_failure(T::time()) -> ok 146 | count_failure(T) -> 147 | cast({count_failure,T}). 148 | 149 | %% @spec count_queued() -> ok 150 | count_queued() -> 151 | cast({count_queued}). 152 | 153 | %% @spec count_unqueued() -> ok 154 | count_unqueued() -> 155 | cast({count_unqueued}). 156 | 157 | %% @spec count_unqueued(T::time()) -> ok 158 | count_unqueued(T) -> 159 | cast({count_unqueued,T}). 160 | 161 | %% @spec dump(any()) -> ok 162 | dump(ClientID) -> 163 | cast({dump, ClientID}). 164 | 165 | %% @spec pending() -> integer() 166 | pending() -> 167 | call({pending}). 168 | 169 | %% @spec queued() -> integer() 170 | queued() -> 171 | call({queued}). 172 | 173 | -else. 174 | 175 | %% @doc reset function dummy when profiler is not compiled in 176 | %% @spec reset() -> ok 177 | reset() -> 178 | ok. 179 | 180 | -endif. 181 | 182 | %% @spec dummy() -> ok 183 | dummy() -> 184 | io:format("."), 185 | ok. 186 | 187 | %% @spec dummy(any()) -> ok 188 | dummy(_) -> 189 | io:format("."), 190 | ok. 191 | 192 | %% the stateful loop functions of the gen_server never 193 | %% want to call exit/1 because it would crash the gen_server. 194 | %% instead we want to return error tuples and then throw 195 | %% the error once outside of the gen_server process 196 | %% @spec call(Msg::tuple()) -> ok | integer() 197 | call(Msg) -> 198 | case gen_server:call(?MODULE, Msg, infinity) of 199 | {error, Reason} -> 200 | exit(Reason); 201 | Result -> 202 | Result 203 | end. 204 | 205 | -ifdef(profile). 206 | %% @spec cast(Msg::tuple()) -> ok | integer() 207 | cast(Msg) -> 208 | gen_server:cast(?MODULE, Msg). 209 | -endif. 210 | 211 | %%==================================================================== 212 | %% gen_server callbacks 213 | %%==================================================================== 214 | 215 | %%-------------------------------------------------------------------- 216 | %% Function: init(Args) -> {ok, State} | 217 | %% {ok, State, Timeout} | 218 | %% ignore | 219 | %% {stop, Reason} 220 | %% Description: Initiates the server 221 | %%-------------------------------------------------------------------- 222 | %% @spec init([]) -> {'ok',#state{}} 223 | init([]) -> 224 | ?TRACE("#3a erlvolt_profiler:init/1"), 225 | {ok, new_state()}. 226 | 227 | new_state() -> 228 | {#erlvolt_profile{t0=now()}, #erlvolt_profile{t0=now()}}. 229 | 230 | %%-------------------------------------------------------------------- 231 | %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | 232 | %% {reply, Reply, State, Timeout} | 233 | %% {noreply, State} | 234 | %% {noreply, State, Timeout} | 235 | %% {stop, Reason, Reply, State} | 236 | %% {stop, Reason, State} 237 | %% Description: Handling call messages 238 | %%-------------------------------------------------------------------- 239 | %% @spec handle_call(any(),any(),any()) -> {'reply',any(),any()} 240 | handle_call(test, _, State) -> 241 | {reply, ok, State}; 242 | 243 | handle_call({pending}, _From, {L0,_}=State) -> 244 | {reply, L0#erlvolt_profile.x, State}; 245 | 246 | handle_call({queued}, _From, {L0,_}=State) -> 247 | {reply, L0#erlvolt_profile.q, State}; 248 | 249 | handle_call(Msg, From, State) -> 250 | io:format("Unhandled call from ~p to profiler: ~p~n", [From, Msg]), 251 | {reply, {error, invalid_call}, State}. 252 | 253 | %%-------------------------------------------------------------------- 254 | %% Function: handle_cast(Msg, State) -> {noreply, State} | 255 | %% {noreply, State, Timeout} | 256 | %% {stop, Reason, State} 257 | %% Description: Handling cast messages 258 | %%-------------------------------------------------------------------- 259 | %% @spec handle_cast(any(),{#profile{},#profile{}}) -> {'noreply',{#profile{},#profile{}}} 260 | handle_cast({dump, ClientID}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},{erlvolt_profile,_,T1,_,C1,_,_,_,_,_,_,_}}) -> 261 | 262 | Tn = now(), 263 | TD = trunc(timer:now_diff(Tn,T0) / 1000), 264 | TDs = TD / 1000, 265 | A = trunc(C/TD*1000), 266 | TD1 = timer:now_diff(Tn,T1), % µs 267 | A1 = if TD1 > 0 -> trunc((C-C1)/TD1*1000000); true -> 0 end, 268 | ALc = if AL == nil -> "n/a"; S > 0 -> try io_lib:format("~6.3fms", [AL / S]) catch _:_ -> "n/A" end; true -> "N/a" end, 269 | QLm = trunc(QL / 1000), 270 | if (QLm > 0); (Q > 0) -> 271 | io:format("Client ~5s: at ~6.3fsec: lap ~8s T/sec, total ~8s T/sec, success: ~7s, fails: ~s, pending: ~7s, avglat: ~s, maxlat: ~4Bms, queued: ~5s, maxwait: ~5sms~n", 272 | [ClientID, TDs, ts(A1), ts(A), ts(S), ts(E), ts(X), ALc, XL, ts(Q), ts(QLm)]); 273 | true -> 274 | io:format("Client ~5s: at ~6.3fsec: lap ~8s T/sec, total ~8s T/sec, success: ~7s, fails: ~s, pending: ~7s, avglat: ~s, maxlat: ~4Bms~n", 275 | [ClientID, TDs, ts(A1), ts(A), ts(S), ts(E), ts(X), ALc, XL]) 276 | end, 277 | 278 | {noreply, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,0,Q,0},{erlvolt_profile,P,Tn,N,C,S,E,X,0,0,Q,0}}}; 279 | 280 | handle_cast(reset, _) -> 281 | {noreply, new_state()}; 282 | 283 | handle_cast({count_pending}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 284 | {noreply, {{erlvolt_profile,P,T0,N,C,S,E,X+1,AL,XL,Q,QL},L1}}; 285 | 286 | handle_cast({count_success}, {{erlvolt_profile,P,T0,N,C,S,E,X,_AL,XL,Q,QL},L1}) -> 287 | {noreply, {{erlvolt_profile,P,T0,N,C+1,S+1,E,X-1,nil,XL,Q,QL},L1}}; 288 | 289 | handle_cast({count_success, Waited}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 290 | {noreply, {{erlvolt_profile,P,T0,N,C+1,S+1,E,X-1,if is_number(AL) -> AL+Waited; true -> nil end,max(XL,Waited),Q,QL},L1}}; 291 | 292 | handle_cast({count_failure}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 293 | {noreply, {{erlvolt_profile,P,T0,N,C+1,S,E+1,X-1,AL,XL,Q,QL},L1}}; 294 | 295 | handle_cast({count_queued}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 296 | {noreply, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q+1,QL},L1}}; 297 | 298 | handle_cast({count_unqueued}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 299 | {noreply, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q-1,QL},L1}}; 300 | 301 | handle_cast({count_unqueued, Waited}, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q,QL},L1}) -> 302 | {noreply, {{erlvolt_profile,P,T0,N,C,S,E,X,AL,XL,Q-1,max(QL,Waited)},L1}}; 303 | 304 | handle_cast(Msg, State) -> 305 | io:format("Unhandled cast to profiler: ~p~n", [Msg]), 306 | {noreply, State}. 307 | 308 | %%-------------------------------------------------------------------- 309 | %% Function: handle_info(Info, State) -> {noreply, State} | 310 | %% {noreply, State, Timeout} | 311 | %% {stop, Reason, State} 312 | %% Description: Handling all non call/cast messages 313 | %%-------------------------------------------------------------------- 314 | %% @spec handle_info(any(),any()) -> {'noreply',any()} 315 | handle_info(_Info, State) -> 316 | {noreply, State}. 317 | 318 | %%-------------------------------------------------------------------- 319 | %% Function: terminate(Reason, State) -> void() 320 | %% Description: This function is called by a gen_server when it is about to 321 | %% terminate. It should be the opposite of Module:init/1 and do any necessary 322 | %% cleaning up. When it returns, the gen_server terminates with Reason. 323 | %% The return value is ignored. 324 | %%-------------------------------------------------------------------- 325 | %% @spec terminate(any(),any()) -> 'ok' 326 | terminate(_Reason, _State) -> 327 | ok. 328 | 329 | %%-------------------------------------------------------------------- 330 | %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} 331 | %% Description: Convert process state when code is changed 332 | %%-------------------------------------------------------------------- 333 | %% @spec code_change(any(),any(),any()) -> {'ok',any()} 334 | code_change(_OldVsn, State, _Extra) -> 335 | {ok, State}. 336 | 337 | %%-------------------------------------------------------------------- 338 | %%% Helper functions 339 | %%-------------------------------------------------------------------- 340 | 341 | -ifdef(profile). 342 | 343 | %% Wait until less than Target calls are queued up for sending to the server 344 | %% @spec waitqueued(pid(),100) -> 'ok'. 345 | waitqueued(Target) -> 346 | % io:format("queued: ~p~n", [erlvolt_profiler:queued()]), 347 | case erlvolt_profiler:queued() > Target of 348 | true -> 349 | timer:sleep(1), 350 | waitqueued(Target); 351 | false -> 352 | ok 353 | end. 354 | 355 | %% Wait until less than Target responses are pending at the server 356 | %% @spec waitpending(pid(),100) -> 'ok'. 357 | waitpending(Target) -> 358 | % io:format("pending: ~p~n", [erlvolt_profiler:pending()]), 359 | case erlvolt_profiler:pending() > Target of 360 | true -> 361 | timer:sleep(1), 362 | waitpending(Target); 363 | false -> 364 | ok 365 | end. 366 | 367 | -endif. 368 | 369 | %% @private thousands separator 370 | ts(N) when is_integer(N) -> 371 | L = integer_to_list(N), 372 | [ [D|case (I-2) rem 3 of 2 -> ","; _ -> "" end] || {I,D} <- lists:zip(lists:seq(length(L),1,-1), L)]; 373 | 374 | ts(X) -> 375 | X. 376 | 377 | 378 | %% @private suppress trailing ".0" 379 | abri(N) -> 380 | if N == trunc(N) -> 381 | integer_to_list(trunc(N)); 382 | true -> 383 | float_to_list(N) 384 | end. 385 | -------------------------------------------------------------------------------- /src/erlvolt_sup.erl: -------------------------------------------------------------------------------- 1 | %%%-------------------------------------------------------------------------%%% 2 | %%% File : erlvolt_conn.erl %%% 3 | %%% Version : 0.3/beta %%% 4 | %%% Description : Erlang VoltDB driver joint supervisor module %%% 5 | %%% Copyright : VoltDB, LLC - http://www.voltdb.com %%% 6 | %%% Production : Eonblast Corporation - http://www.eonblast.com %%% 7 | %%% Author : H. Diedrich %%% 8 | %%% License : MIT %%% 9 | %%% Created : 13 Apr 2012 %%% 10 | %%% Changed : 02 Feb 2013 %%% 11 | %%%-------------------------------------------------------------------------%%% 12 | %%% %%% 13 | %%% This driver is being contributed to VoltDB by Eonblast Corporation. %%% 14 | %%% %%% 15 | %%%-------------------------------------------------------------------------%%% 16 | %%% %%% 17 | %%% Erlvolt 0.3/beta - Erlang VoltDB client API. %%% 18 | %%% %%% 19 | %%% This file is part of VoltDB. %%% 20 | %%% Copyright (C) 2008-2018 VoltDB Inc. http://www.voltdb.com %%% 21 | %%% Author H. Diedrich http://www.eonblast.com %%% 22 | %%% %%% 23 | %%% Permission is hereby granted, free of charge, to any person obtaining %%% 24 | %%% a copy of this software and associated documentation files (the %%% 25 | %%% "Software"), to deal in the Software without restriction, including %%% 26 | %%% without limitation the rights to use, copy, modify, merge, publish, %%% 27 | %%% distribute, sublicense, and/or sell copies of the Software, and to %%% 28 | %%% permit persons to whom the Software is furnished to do so, subject to %%% 29 | %%% the following conditions: %%% 30 | %%% %%% 31 | %%% The above copyright notice and this permission notice shall be %%% 32 | %%% included in all copies or substantial portions of the Software. %%% 33 | %%% %%% 34 | %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, %%% 35 | %%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF %%% 36 | %%% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. %%% 37 | %%% IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR %%% 38 | %%% OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, %%% 39 | %%% ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR %%% 40 | %%% OTHER DEALINGS IN THE SOFTWARE. %%% 41 | %%% %%% 42 | %%%-------------------------------------------------------------------------%%% 43 | %%% %%% 44 | %%% USAGE %%% 45 | %%% %%% 46 | %%% You can run a sample using the 'Hello' tutorial-server discussed %%% 47 | %%% in the VoltDB manual and present in every VoltDB distribution. %%% 48 | %%% %%% 49 | %%% Start that server from your voltdb installation with: %%% 50 | %%% %%% 51 | %%% $ cd voltdb/doc/tutorial/helloworld %%% 52 | %%% $ ./run.sh %%% 53 | %%% %%% 54 | %%% Then run the hello world example, using make from the driver root: %%% 55 | %%% %%% 56 | %%% $ make hello %%% 57 | %%% or %%% 58 | %%% $ make %%% 59 | %%% $ cd examples %%% 60 | %%% $ erlc -I ../include -o ../ebin +debug_info hello_plus.erl %%% 61 | %%% $ erl -pa ../ebin -s hello_plus run -s init stop -noshell %%% 62 | %%% %%% 63 | %%% You will see this response, 'Hello, world!' in Swedish: %%% 64 | %%% %%% 65 | %%% Hej världen! %%% 66 | %%% %%% 67 | %%% The hello world source is found in examples/hello_plus.erl %%% 68 | %%% %%% 69 | %%%-------------------------------------------------------------------------%%% 70 | %%% %%% 71 | %%% See README.md or .html for instructions, examples/ for more examples. %%% 72 | %%% See doc/BENCHMARKS.md or .html for a description of driver benchmarks. %%% 73 | %%% %%% 74 | %%% For getting started with VoltDB,see: voltdb/doc/GettingStarted.pdf or %%% 75 | %%% online: http://voltdb.com/downloads/documentation/GettingStarted.pdf. %%% 76 | %%% %%% 77 | %%%-------------------------------------------------------------------------%%% 78 | 79 | -module(erlvolt_sup). 80 | -behaviour(supervisor). 81 | 82 | -vsn("0.3/beta"). 83 | -author("H. Diedrich "). 84 | -license("MIT - http://www.opensource.org/licenses/mit-license.php"). 85 | -copyright("(c) 2010-12 VoltDB, LLC - http://www.voltdb.com"). 86 | 87 | -define(VERSION, "0.3/beta"). 88 | -define(LIBRARY, "Erlvolt"). 89 | -define(EXPLAIN, "Erlang VoltDB driver"). 90 | 91 | -export([start_link/0, init/1]). 92 | 93 | %%% @spec start_link() -> ignore | {error,any()} | {ok,pid()} 94 | start_link() -> % called by erlvolt_app:start/2 95 | erlvolt:trace("#2 erlvolt_sup:start_link/0"), 96 | supervisor:start_link({local, erlvolt_sup_profiler}, ?MODULE, erlvolt_sup_profiler), 97 | erlvolt_profiler:test(), 98 | supervisor:start_link({local, erlvolt_sup_conn_mgr}, ?MODULE, erlvolt_sup_conn_mgr), 99 | erlvolt_conn_mgr:test(), 100 | supervisor:start_link({local, erlvolt_sup_conn}, ?MODULE, erlvolt_sup_conn). 101 | 102 | 103 | %:% init must return the supervisor spec and nested into it, the child spec(s). 104 | %%% Supervisor of the global connection manager 105 | %%% @spec init('erlvolt_sup_conn' | 'erlvolt_sup_conn_mgr') -> {'ok',{{'one_for_one',integer(),integer()} | {'simple_one_for_one',integer(),integer()},[any(),...]}} 106 | init(erlvolt_sup_conn_mgr) -> 107 | erlvolt:trace("#2a erlvolt_sup:init(erlvolt_conn_mgr)"), 108 | {ok, {{one_for_one, 10, 10}, [ 109 | % Spec of the /one/ Connection Slot Manager 110 | { erlvolt_conn_mgr, 111 | {erlvolt_conn_mgr, start_link, []}, 112 | permanent, 113 | 5000, 114 | worker, 115 | [erlvolt_conn_mgr]} 116 | ]}}; 117 | 118 | %%% Supervisor of the individual connection send/receive workers 119 | init(erlvolt_sup_conn) -> 120 | erlvolt:trace("#2b erlvolt_sup:init(erlvolt_sup_conn)"), 121 | {ok, {{simple_one_for_one, 10, 10}, [ 122 | % Spec of the /many, dynamic/ socket controlling Connection main loops 123 | { erlvolt_conn, 124 | {erlvolt_conn, start_link, []}, 125 | transient, 126 | 5000, 127 | worker, 128 | [erlvolt_conn]} 129 | ]}}; 130 | 131 | %:% init must return the supervisor spec and nested into it, the child spec(s). 132 | %%% Supervisor of the global connection manager 133 | %%% @spec init('erlvolt_sup_conn' | 'erlvolt_sup_conn_mgr') -> {'ok',{{'one_for_one',integer(),integer()} | {'simple_one_for_one',integer(),integer()},[any(),...]}} 134 | init(erlvolt_sup_profiler) -> 135 | erlvolt:trace("#2c erlvolt_sup:init(erlvolt_profiler)"), 136 | {ok, {{one_for_one, 10, 10}, [ 137 | % Spec of the /one/ Profiler 138 | { erlvolt_profiler, 139 | {erlvolt_profiler, start_link, []}, 140 | permanent, 141 | 5000, 142 | worker, 143 | [erlvolt_profiler]} 144 | ]}}. 145 | 146 | 147 | %:% Child Spec: 148 | %:% {Id, StartFunc, Restart, Shutdown, Type, Modules} 149 | %:% Id = term() 150 | %:% StartFunc = {M, F, A} 151 | %:% M = F = atom() 152 | %:% A = [term()] 153 | %:% Restart = permanent | transient | temporary 154 | %:% Shutdown = brutal_kill | integer()>0 | infinity 155 | %:% Type = worker | supervisor 156 | %:% Modules = [Module] | dynamic 157 | %:% Module = atom() 158 | --------------------------------------------------------------------------------