From 497373d9765c32fde5082dddbb25fa07a64de748 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Wed, 27 Mar 2019 13:41:46 -0700 Subject: [PATCH] ws redis command improvements + test script --- DOCKER_VERSION | 1 + Dockerfile | 32 +----------------------------- Dockerfile.dev | 31 +++++++++++++++++++++++++++++ Dockerfile.prod | 30 ++++++++++++++++++++++++++++ docker-compose.yml | 21 ++++++++++++++++++++ makefile | 14 ++++++++++++- ws/test_ws_redis.sh | 25 ++++++++++++++++++++++++ ws/ws.cpp | 6 +++++- ws/ws.h | 3 ++- ws/ws_redis_publish.cpp | 16 +++++++++------ ws/ws_redis_subscribe.cpp | 41 +++++++++++++++++++++------------------ 11 files changed, 161 insertions(+), 59 deletions(-) create mode 100644 DOCKER_VERSION mode change 100644 => 120000 Dockerfile create mode 100644 Dockerfile.dev create mode 100644 Dockerfile.prod create mode 100644 docker-compose.yml create mode 100644 ws/test_ws_redis.sh diff --git a/DOCKER_VERSION b/DOCKER_VERSION new file mode 100644 index 00000000..1892b926 --- /dev/null +++ b/DOCKER_VERSION @@ -0,0 +1 @@ +1.3.2 diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 05937cd1..00000000 --- a/Dockerfile +++ /dev/null @@ -1,31 +0,0 @@ -FROM debian:stretch - -ENV DEBIAN_FRONTEND noninteractive -RUN apt-get update -RUN apt-get -y install g++ -RUN apt-get -y install libssl-dev -RUN apt-get -y install gdb -RUN apt-get -y install screen -RUN apt-get -y install procps -RUN apt-get -y install lsof -RUN apt-get -y install libz-dev -RUN apt-get -y install vim -RUN apt-get -y install make -RUN apt-get -y install cmake -RUN apt-get -y install curl -RUN apt-get -y install python -RUN apt-get -y install netcat - -# debian strech cmake is too old for building with Docker -COPY makefile . -RUN ["make", "install_cmake_for_linux"] - -COPY . . - -ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-rc4-Linux-x86_64/bin -ENV PATH="${CMAKE_BIN_PATH}:${PATH}" - -# RUN ["make"] - -EXPOSE 8765 -CMD ["/ws/ws", "transfer", "--port", "8765", "--host", "0.0.0.0"] diff --git a/Dockerfile b/Dockerfile new file mode 120000 index 00000000..91fb519b --- /dev/null +++ b/Dockerfile @@ -0,0 +1 @@ +Dockerfile.dev \ No newline at end of file diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 00000000..05937cd1 --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,31 @@ +FROM debian:stretch + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update +RUN apt-get -y install g++ +RUN apt-get -y install libssl-dev +RUN apt-get -y install gdb +RUN apt-get -y install screen +RUN apt-get -y install procps +RUN apt-get -y install lsof +RUN apt-get -y install libz-dev +RUN apt-get -y install vim +RUN apt-get -y install make +RUN apt-get -y install cmake +RUN apt-get -y install curl +RUN apt-get -y install python +RUN apt-get -y install netcat + +# debian strech cmake is too old for building with Docker +COPY makefile . +RUN ["make", "install_cmake_for_linux"] + +COPY . . + +ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-rc4-Linux-x86_64/bin +ENV PATH="${CMAKE_BIN_PATH}:${PATH}" + +# RUN ["make"] + +EXPOSE 8765 +CMD ["/ws/ws", "transfer", "--port", "8765", "--host", "0.0.0.0"] diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 00000000..8081776b --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,30 @@ +FROM debian:buster + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update + +RUN apt-get -y install g++ +RUN apt-get -y install libssl-dev +RUN apt-get -y install libz-dev +RUN apt-get -y install make + +RUN apt-get -y install wget +RUN mkdir -p /tmp/cmake +WORKDIR /tmp/cmake +RUN wget https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz +RUN tar zxf cmake-3.14.0-Linux-x86_64.tar.gz + +RUN adduser app + +COPY . . + +ARG CMAKE_BIN_PATH=/tmp/cmake/cmake-3.14.0-Linux-x86_64/bin +ENV PATH="${CMAKE_BIN_PATH}:${PATH}" + +RUN ["make"] + +# Now run in usermode +USER app + +EXPOSE 8765 +CMD ["bash"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..c84f68f5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: "3" +services: + ws: + stdin_open: true + tty: true + image: bsergean/ws:build + ports: + - "8765:8765" + entrypoint: bash + networks: + - ws-net + depends_on: + - redis1 + + redis1: + image: redis:alpine + networks: + - ws-net + +networks: + ws-net: diff --git a/makefile b/makefile index b6906259..1098117d 100644 --- a/makefile +++ b/makefile @@ -9,8 +9,20 @@ brew: mkdir -p build && (cd build ; cmake .. ; make -j install) .PHONY: docker + +NAME := bsergean/ws +TAG := $(shell cat DOCKER_VERSION) +IMG := ${NAME}:${TAG} +LATEST := ${NAME}:latest +BUILD := ${NAME}:build + docker: - docker build -t ws:latest . + docker build -t ${IMG} . + docker tag ${IMG} ${BUILD} + +docker_push: + docker tag ${IMG} ${LATEST} + docker push ${LATEST} run: docker run --cap-add sys_ptrace -it ws:latest diff --git a/ws/test_ws_redis.sh b/ws/test_ws_redis.sh new file mode 100644 index 00000000..ac720fab --- /dev/null +++ b/ws/test_ws_redis.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +# Handle Ctrl-C by killing all sub-processing AND exiting +trap cleanup INT + +function cleanup { + kill `cat /tmp/pidfile.subscribe` + exit 1 +} + +REDIS_HOST=${REDIS_HOST:=localhost} + +ws redis_subscribe --pidfile /tmp/pidfile.subscribe --host $REDIS_HOST foo & + +# Wait for the subscriber to be ready +sleep 0.5 + +# Now publish messages +ws redis_publish -c 100000 --host ${REDIS_HOST} foo bar + +# Wait a little for all messages to be received +sleep 0.5 + +# Cleanup +cleanup diff --git a/ws/ws.cpp b/ws/ws.cpp index 1c1e7c53..321898a5 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -49,6 +49,7 @@ int main(int argc, char** argv) int transferTimeout = 1800; int maxRedirects = 5; int delayMs = -1; + int count = 1; CLI::App* sendApp = app.add_subcommand("send", "Send a file"); sendApp->add_option("url", url, "Connection url")->required(); @@ -106,6 +107,7 @@ int main(int argc, char** argv) redisPublishApp->add_option("--password", password, "Password"); redisPublishApp->add_option("channel", channel, "Channel")->required(); redisPublishApp->add_option("message", message, "Message")->required(); + redisPublishApp->add_option("-c", count, "Count"); CLI::App* redisSubscribeApp = app.add_subcommand("redis_subscribe", "Redis subscriber"); redisSubscribeApp->add_option("--port", redisPort, "Port"); @@ -113,6 +115,7 @@ int main(int argc, char** argv) redisSubscribeApp->add_option("--password", password, "Password"); redisSubscribeApp->add_option("channel", channel, "Channel")->required(); redisSubscribeApp->add_flag("-v", verbose, "Verbose"); + redisSubscribeApp->add_option("--pidfile", pidfile, "Pid file"); CLI11_PARSE(app, argc, argv); @@ -169,7 +172,8 @@ int main(int argc, char** argv) } else if (app.got_subcommand("redis_publish")) { - return ix::ws_redis_publish_main(hostname, redisPort, password, channel, message); + return ix::ws_redis_publish_main(hostname, redisPort, password, + channel, message, count); } else if (app.got_subcommand("redis_subscribe")) { diff --git a/ws/ws.h b/ws/ws.h index 95ae880f..d944b741 100644 --- a/ws/ws.h +++ b/ws/ws.h @@ -44,7 +44,8 @@ namespace ix int port, const std::string& password, const std::string& channel, - const std::string& message); + const std::string& message, + int count); int ws_redis_subscribe_main(const std::string& hostname, int port, diff --git a/ws/ws_redis_publish.cpp b/ws/ws_redis_publish.cpp index 31a1ec86..298eb657 100644 --- a/ws/ws_redis_publish.cpp +++ b/ws/ws_redis_publish.cpp @@ -14,7 +14,8 @@ namespace ix int port, const std::string& password, const std::string& channel, - const std::string& message) + const std::string& message, + int count) { RedisClient redisClient; if (!redisClient.connect(hostname, port)) @@ -35,12 +36,15 @@ namespace ix std::cout << "Auth response: " << authResponse << ":" << port << std::endl; } - std::cerr << "Publishing message " << message - << " to " << channel << "..." << std::endl; - if (!redisClient.publish(channel, message)) + for (int i = 0; i < count; i++) { - std::cerr << "Error publishing to channel " << channel << std::endl; - return 1; + //std::cerr << "Publishing message " << message + // << " to " << channel << "..." << std::endl; + if (!redisClient.publish(channel, message)) + { + std::cerr << "Error publishing to channel " << channel << std::endl; + return 1; + } } return 0; diff --git a/ws/ws_redis_subscribe.cpp b/ws/ws_redis_subscribe.cpp index bc861d39..aa422bac 100644 --- a/ws/ws_redis_subscribe.cpp +++ b/ws/ws_redis_subscribe.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "IXRedisClient.h" namespace ix @@ -36,11 +38,10 @@ namespace ix std::cout << "Auth response: " << authResponse << ":" << port << std::endl; } - std::chrono::time_point lastTimePoint; - int msgPerSeconds = 0; - int msgCount = 0; + std::atomic msgPerSeconds(0); + std::atomic msgCount(0); - auto callback = [&lastTimePoint, &msgPerSeconds, &msgCount, verbose] + auto callback = [&msgPerSeconds, &msgCount, verbose] (const std::string& message) { if (verbose) @@ -49,21 +50,7 @@ namespace ix } msgPerSeconds++; - - auto now = std::chrono::steady_clock::now(); - if (now - lastTimePoint > std::chrono::seconds(1)) - { - lastTimePoint = std::chrono::steady_clock::now(); - - msgCount += msgPerSeconds; - - // #messages 901 msg/s 150 - std::cout << "#messages " << msgCount << " " - << "msg/s " << msgPerSeconds - << std::endl; - - msgPerSeconds = 0; - } + msgCount++; }; auto responseCallback = [](const std::string& redisResponse) @@ -71,6 +58,22 @@ namespace ix std::cout << "Redis subscribe response: " << redisResponse << std::endl; }; + auto timer = [&msgPerSeconds, &msgCount] + { + while (true) + { + std::cout << "#messages " << msgCount << " " + << "msg/s " << msgPerSeconds + << std::endl; + + msgPerSeconds = 0; + auto duration = std::chrono::seconds(1); + std::this_thread::sleep_for(duration); + } + }; + + std::thread t(timer); + std::cerr << "Subscribing to " << channel << "..." << std::endl; if (!redisClient.subscribe(channel, responseCallback, callback)) {