diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9da58b9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,32 @@ +language: c + +sudo: required + +services: + - docker + +env: + global: + - LUAROCKS=2.4.1 + matrix: + - LUA=lua5.1 + - LUA=lua5.2 + - LUA=lua5.3 + - LUA=luajit + - LUA=luajit2.0 + +before_install: + - docker-compose up -d nats + - source .travis/setenv_lua.sh + - luarocks install telescope + +install: + - luarocks make rockspec/nats-0.0.3-1.rockspec + +script: + - make test + +notifications: + email: + on_success: change + on_failure: always \ No newline at end of file diff --git a/.travis/platform.sh b/.travis/platform.sh new file mode 100755 index 0000000..0ade201 --- /dev/null +++ b/.travis/platform.sh @@ -0,0 +1,15 @@ +if [ -z "${PLATFORM:-}" ]; then + PLATFORM=$TRAVIS_OS_NAME; +fi + +if [ "$PLATFORM" == "osx" ]; then + PLATFORM="macosx"; +fi + +if [ -z "$PLATFORM" ]; then + if [ "$(uname)" == "Linux" ]; then + PLATFORM="linux"; + else + PLATFORM="macosx"; + fi; +fi \ No newline at end of file diff --git a/.travis/setenv_lua.sh b/.travis/setenv_lua.sh new file mode 100755 index 0000000..a01b2f7 --- /dev/null +++ b/.travis/setenv_lua.sh @@ -0,0 +1,3 @@ +export PATH=${PATH}:$HOME/.lua:$HOME/.local/bin:${TRAVIS_BUILD_DIR}/install/luarocks/bin +bash .travis/setup_lua.sh +eval "$($HOME/.lua/luarocks path)" \ No newline at end of file diff --git a/.travis/setup_lua.sh b/.travis/setup_lua.sh new file mode 100755 index 0000000..257d8fb --- /dev/null +++ b/.travis/setup_lua.sh @@ -0,0 +1,125 @@ +#! /bin/bash + +# A script for setting up environment for travis-ci testing. +# Sets up Lua and Luarocks. +# LUA must be "lua5.1", "lua5.2" or "luajit". +# luajit2.0 - master v2.0 +# luajit2.1 - master v2.1 + +set -eufo pipefail + +LUAJIT_VERSION="2.0.5" +if [ "$LUA" == "luajit2.1" ]; then + LUAJIT_VERSION="2.1.0-beta3" +fi +LUAJIT_BASE="LuaJIT-$LUAJIT_VERSION" + +source .travis/platform.sh + +LUA_HOME_DIR=$TRAVIS_BUILD_DIR/install/lua + +LR_HOME_DIR=$TRAVIS_BUILD_DIR/install/luarocks + +mkdir $HOME/.lua + +LUAJIT="no" + +if [ "$PLATFORM" == "macosx" ]; then + if [ "$LUA" == "luajit" ]; then + LUAJIT="yes"; + fi + if [ "$LUA" == "luajit2.0" ]; then + LUAJIT="yes"; + fi + if [ "$LUA" == "luajit2.1" ]; then + LUAJIT="yes"; + fi; +elif [ "$(expr substr $LUA 1 6)" == "luajit" ]; then + LUAJIT="yes"; +fi + +mkdir -p "$LUA_HOME_DIR" + +if [ "$LUAJIT" == "yes" ]; then + + if [ "$LUA" == "luajit" ]; then + curl --location https://github.com/LuaJIT/LuaJIT/archive/v$LUAJIT_VERSION.tar.gz | tar xz; + else + git clone https://github.com/LuaJIT/LuaJIT.git $LUAJIT_BASE; + fi + + cd $LUAJIT_BASE + + if [ "$LUA" == "luajit2.1" ]; then + git checkout v2.1; + # force the INSTALL_TNAME to be luajit + perl -i -pe 's/INSTALL_TNAME=.+/INSTALL_TNAME= luajit/' Makefile + fi + + make && make install PREFIX="$LUA_HOME_DIR" + + ln -s "$LUA_HOME_DIR/bin/luajit" $HOME/.lua/luajit + ln -s "$LUA_HOME_DIR/bin/luajit" $HOME/.lua/lua; + +else + + if [ "$LUA" == "lua5.1" ]; then + curl http://www.lua.org/ftp/lua-5.1.5.tar.gz | tar xz + cd lua-5.1.5; + elif [ "$LUA" == "lua5.2" ]; then + curl http://www.lua.org/ftp/lua-5.2.4.tar.gz | tar xz + cd lua-5.2.4; + elif [ "$LUA" == "lua5.3" ]; then + curl http://www.lua.org/ftp/lua-5.3.2.tar.gz | tar xz + cd lua-5.3.2; + fi + + # Build Lua without backwards compatibility for testing + perl -i -pe 's/-DLUA_COMPAT_(ALL|5_2)//' src/Makefile + make $PLATFORM + make INSTALL_TOP="$LUA_HOME_DIR" install; + + ln -s $LUA_HOME_DIR/bin/lua $HOME/.lua/lua + ln -s $LUA_HOME_DIR/bin/luac $HOME/.lua/luac; + +fi + +cd $TRAVIS_BUILD_DIR + +lua -v + +LUAROCKS_BASE=luarocks-$LUAROCKS + +curl --location http://luarocks.org/releases/$LUAROCKS_BASE.tar.gz | tar xz + +cd $LUAROCKS_BASE + +if [ "$LUA" == "luajit" ]; then + ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR"; +elif [ "$LUA" == "luajit2.0" ]; then + ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.0" --prefix="$LR_HOME_DIR"; +elif [ "$LUA" == "luajit2.1" ]; then + ./configure --lua-suffix=jit --with-lua-include="$LUA_HOME_DIR/include/luajit-2.1" --prefix="$LR_HOME_DIR"; +else + ./configure --with-lua="$LUA_HOME_DIR" --prefix="$LR_HOME_DIR" +fi + +make build && make install + +ln -s $LR_HOME_DIR/bin/luarocks $HOME/.lua/luarocks + +cd $TRAVIS_BUILD_DIR + +luarocks --version + +rm -rf $LUAROCKS_BASE + +if [ "$LUAJIT" == "yes" ]; then + rm -rf $LUAJIT_BASE; +elif [ "$LUA" == "lua5.1" ]; then + rm -rf lua-5.1.5; +elif [ "$LUA" == "lua5.2" ]; then + rm -rf lua-5.2.4; +elif [ "$LUA" == "lua5.3" ]; then + rm -rf lua-5.3.2; +fi \ No newline at end of file diff --git a/README.md b/README.md index 7596be9..e3e9820 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ NATS Lua library ================ +![travis status](https://travis-ci.org/OystParis/lua-nats.svg?branch=master) + LUA client for NATS messaging system. https://nats.io > Note: lua-nats is under heavy development. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..09935e8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,7 @@ +version: "2" +services: + + nats: + image: nats + ports: + - "4222:4222" \ No newline at end of file diff --git a/rockspec/lua-nats-0.0.2-1.rockspec b/rockspec/nats-0.0.3-1.rockspec similarity index 93% rename from rockspec/lua-nats-0.0.2-1.rockspec rename to rockspec/nats-0.0.3-1.rockspec index 8c70f24..be97415 100644 --- a/rockspec/lua-nats-0.0.2-1.rockspec +++ b/rockspec/nats-0.0.3-1.rockspec @@ -1,9 +1,9 @@ package = "nats" -version = "0.0.2-1" +version = "0.0.3-1" source = { url = "git://github.com/DawnAngel/lua-nats.git", - tag = "0.0.2" + tag = "0.0.3" } description = { diff --git a/src/nats.lua b/src/nats.lua index b9495b1..fe9236e 100644 --- a/src/nats.lua +++ b/src/nats.lua @@ -36,6 +36,11 @@ local defaults = { path = nil, } +-- ### Create a properly formatted inbox subject. + +local function create_inbox() + return '_INBOX.' .. uuid() +end -- ### Local methods ### @@ -87,7 +92,7 @@ local function create_client(client_proto, client_socket, commands) client.requests = { multibulk = request.raw, } - + uuid.seed() return client end @@ -137,13 +142,16 @@ function response.read(client) -- MSG elseif slices[1] == 'MSG' then - local length = slices[4] - data.action = 'MSG' data.subject = slices[2] data.unique_id = slices[3] -- ask for line ending chars and remove them - data.content = client.network.read(client, length+2):sub(1, -3) + if #slices == 4 then + data.content = client.network.read(client, slices[4]+2):sub(1, -3) + else + data.reply = slices[4] + data.content = client.network.read(client, slices[5]+2):sub(1, -3) + end -- INFO elseif slices[1] == 'INFO' then @@ -337,9 +345,18 @@ function command.pong(client) request.raw(client, 'PONG\r\n') end +function command.request(client, subject, payload, callback) + local inbox = create_inbox() + unique_id = client:subscribe(inbox, function(message, reply) + client:unsubscribe(unique_id) + callback(message, reply) + end) + client:publish(subject, payload, inbox) + return unique_id, inbox +end + function command.subscribe(client, subject, callback) - uuid.seed() - unique_id = uuid() + local unique_id = uuid() request.raw(client, 'SUB '..subject..' '..unique_id..'\r\n') client.subscriptions[unique_id] = callback @@ -351,9 +368,14 @@ function command.unsubscribe(client, unique_id) client.subscriptions[unique_id] = nil end -function command.publish(client, subject, payload) +function command.publish(client, subject, payload, reply) + if reply ~= nil then + reply = ' '..reply + else + reply = '' + end request.raw(client, { - 'PUB '..subject..' '..#payload..'\r\n', + 'PUB '..subject..reply..' '..#payload..'\r\n', payload..'\r\n', }) end @@ -370,7 +392,7 @@ function command.wait(client, quantity) elseif data.action == 'MSG' then count = count + 1 - client.subscriptions[data.unique_id](data.content) + client.subscriptions[data.unique_id](data.content, data.reply) end until quantity > 0 and count >= quantity end @@ -382,6 +404,7 @@ nats.commands = { connect = command.connect, ping = command.ping, pong = command.pong, + request = command.request, subscribe = command.subscribe, unsubscribe = command.unsubscribe, publish = command.publish, diff --git a/tests/test_client.lua b/tests/test_client.lua index 0f6311d..f4af511 100644 --- a/tests/test_client.lua +++ b/tests/test_client.lua @@ -109,4 +109,24 @@ context('NATS commands', function() assert_equal(client.network.lwrite:sub(1,3), 'PUB') end) + + test('* client:request', function() + local init_message = 'init message' + local reply_message = 'reply message' + local equal_init_message, equal_reply_message + + client:subscribe('foo', function(message, reply) + equal_init_message = message == init_message + client:publish(reply, reply_message) + end) + + client:request('foo', init_message, function(message) + equal_reply_message = message == reply_message + end) + + client:wait(2) + + assert_true(equal_init_message) + assert_true(equal_reply_message) + end) end)