Skip to content

Instantly share code, notes, and snippets.

@jobs-git
Last active May 30, 2019 21:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jobs-git/2b37d600dcab227fb2c36533fc8c2108 to your computer and use it in GitHub Desktop.
Save jobs-git/2b37d600dcab227fb2c36533fc8c2108 to your computer and use it in GitHub Desktop.
Tarantool-c slow
//plain http server based on rosseta
//expected clients are http browser
//tested with wrk resulted to 30,000 rps
//wrk http://127.0.0.1:8080 -c 15 -t 3 -d 5
//compile with
//gcc server.c -o server
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
#include <string.h>
int main()
{
const char *msg = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 13\r\nConnection: close\r\n\r\nHello, world!";
int ret = strlen(msg);
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 8080;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
//printf("got connection\n");
if (client_fd == -1) {
perror("Can't accept");
continue;
}
send(client_fd, msg, ret,MSG_NOSIGNAL); /*-1:'\0'*/
//write(client_fd, msg, ret);
close(client_fd);
}
}
//http server connected to tarantool expecting a reply
//expected clients are http browser
//tested with wrk resulted to 900 rps
//wrk http://127.0.0.1:8080 -c 15 -t 3 -d 5
//compile with
//$tarantool-c is the tarantool-c root
//gcc server_tar.c -I$tarantool-c/include -L$tarantool-c/lib -ltarantool -o server_tar
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <err.h>
#include <string.h>
#include <tarantool/tarantool.h>
#include <tarantool/tnt_net.h>
#include <tarantool/tnt_opt.h>
struct tnt_stream *tnt;
struct tnt_stream *tuple;
struct tnt_reply reply;
int main()
{
const char *msg = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: 13\r\nConnection: close\r\n\r\nHello, world!";
int ret = strlen(msg);
int one = 1, client_fd;
struct sockaddr_in svr_addr, cli_addr;
socklen_t sin_len = sizeof(cli_addr);
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
err(1, "can't open socket");
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int));
int port = 8080;
svr_addr.sin_family = AF_INET;
svr_addr.sin_addr.s_addr = INADDR_ANY;
svr_addr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &svr_addr, sizeof(svr_addr)) == -1) {
close(sock);
err(1, "Can't bind");
}
listen(sock, 5);
//initialize tarantool
const char * uri = "127.0.0.101:3301";
tnt = tnt_net(NULL); // Allocating stream
tnt_set(tnt, TNT_OPT_URI, uri); // Setting URI
tnt_connect(tnt);
tuple = tnt_object(NULL);
tnt_reply_init(&reply);
//server event loop
while (1) {
client_fd = accept(sock, (struct sockaddr *) &cli_addr, &sin_len);
//printf("got connection\n");
if (client_fd == -1) {
perror("Can't accept");
continue;
}
//tarantool details
tnt_object_add_array(tuple, 1); //might be the number of rows involved
tnt_object_add_int(tuple, 8); //which row it belongs to
tnt_select(tnt, 10, 0, UINT32_MAX, 0, 0, tuple); //10 is the space id
tnt_flush(tnt);
tnt_object_reset(tuple);
int r = tnt->read_reply(tnt, &reply);
while(1){
if (r == 1)
{
// This means that we're reading responses way to fast and there is nothing in the socket
// Let's just wait a little bit
// It is better to wait 1 ms one in a while than to use mutex every time in terms of CPU usage
usleep(1000);
}
else if (r == -1)
{
printf("Read reply failed %s\n", reply.error);
}else{
//reply suceeds, do something
break;
}
}
tnt_reply_free(&reply);
send(client_fd, msg, ret,MSG_NOSIGNAL);
close(client_fd);
}
//close tnt connection if the server terminates nicely
tnt_close(tnt); tnt_stream_free(tnt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment