Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable TCP keepalives for render_list connections to renderd #271

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions includes/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ extern "C" {
#define RENDER_PORT 7654
#define XMLCONFIG_MAX 41

/* TCP keepalive configuration */
struct keepalive_settings {
int enabled;
int time;
int interval;
int probes;
};

extern struct keepalive_settings keepalives;

enum protoCmd { cmdIgnore, cmdRender, cmdDirty, cmdDone, cmdNotDone, cmdRenderPrio, cmdRenderBulk, cmdRenderLow };

struct protocol {
Expand Down
4 changes: 4 additions & 0 deletions src/render_expired.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ int main(int argc, char **argv)
}
#else

struct keepalive_settings keepalives;

// tile marking arrays
unsigned int **tile_requested;

Expand Down Expand Up @@ -109,6 +111,8 @@ int main(int argc, char **argv)
struct storage_backend * store;
char name[PATH_MAX];

memset(&keepalives, 0, sizeof(struct keepalive_settings));

// excess_zoomlevels is how many zoom levels at the large end
// we can ignore because their tiles will share one meta tile.
// with the default METATILE==8 this is 3.
Expand Down
58 changes: 57 additions & 1 deletion src/render_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ int main(int argc, char **argv)
}
#else

struct keepalive_settings keepalives;

static int minZoom = 0;
static int maxZoom = MAX_ZOOM;
static int verbose = 0;
Expand Down Expand Up @@ -92,6 +94,8 @@ int main(int argc, char **argv)
struct storage_backend * store;
struct stat_info s;

memset(&keepalives, 0, sizeof(struct keepalive_settings));

while (1) {
int option_index = 0;
static struct option long_options[] = {
Expand All @@ -102,6 +106,8 @@ int main(int argc, char **argv)
{"min-y", required_argument, 0, 'y'},
{"max-y", required_argument, 0, 'Y'},
{"socket", required_argument, 0, 's'},
{"keepalives", no_argument, 0, 'k'},
{"keepalive-config", required_argument, 0, 'K'},
{"num-threads", required_argument, 0, 'n'},
{"max-load", required_argument, 0, 'l'},
{"tile-dir", required_argument, 0, 't'},
Expand All @@ -113,7 +119,7 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};

c = getopt_long(argc, argv, "hvaz:Z:x:X:y:Y:s:m:t:n:l:f", long_options, &option_index);
c = getopt_long(argc, argv, "hvaz:Z:x:X:y:Y:s:kK:m:t:n:l:f", long_options, &option_index);

if (c == -1) {
break;
Expand All @@ -129,6 +135,54 @@ int main(int argc, char **argv)
spath = strdup(optarg);
break;

case 'k': /* -k, --keepalives */
keepalives.enabled = 1;
break;

case 'K': { /* --keepalive-config=<t>:<intvl>:<count> */
char * confstr = strdup(optarg);
if (!strlen(confstr)) {
fprintf(stderr, "No parameters provided for the TCP keepalive config\n");
return 1;
}

int val_count = 0;
const int val_count_expected = 3;
char * val[val_count_expected];
char * p = strtok(confstr, ":");
while (p != NULL) {
val[ val_count++ ] = p;
p = strtok(NULL, ":");
}

if (val_count != val_count_expected) {
fprintf(stderr, "Must provide exactly %d instead of %d arguments to --kepalive-config. See help for details.\n", val_count_expected, val_count);
return 1;
}

keepalives.enabled = 1;
char * error_char = NULL;
keepalives.time = strtol(val[0], &error_char, 10);
if (*error_char != '\0') {
fprintf(stderr, "TCP keepalive time contains invalid character\n");
return 1;
}

keepalives.interval = strtol(val[1], &error_char, 10);
if (*error_char != '\0') {
fprintf(stderr, "TCP keepalive interval contains invalid character\n");
return 1;
}

keepalives.probes = strtol(val[2], &error_char, 10);
if (*error_char != '\0') {
fprintf(stderr, "TCP keepalive probe count contains invalid character\n");
return 1;
}

break;
}

case 't': /* -t, --tile-dir */
tile_dir = strdup(optarg);
break;
Expand Down Expand Up @@ -202,6 +256,8 @@ int main(int argc, char **argv)
fprintf(stderr, " -m, --map=MAP render tiles in this map (defaults to '" XMLCONFIG_DEFAULT "')\n");
fprintf(stderr, " -l, --max-load=LOAD sleep if load is this high (defaults to %d)\n", MAX_LOAD_OLD);
fprintf(stderr, " -s, --socket=SOCKET|HOSTNAME:PORT unix domain socket name or hostname and port for contacting renderd\n");
fprintf(stderr, " -k, --keepalives enable TCP keepalives\n");
fprintf(stderr, " -K, --keepalive-config=<t>:<intvl>:<count> TCP keepalive configuration. Send keepalives after t seconds of inactivity, every intvl seconds. Consider connection broken after count probes. Implicitly enables TCP keepalives.\n");
fprintf(stderr, " -n, --num-threads=N the number of parallel request threads (default 1)\n");
fprintf(stderr, " -t, --tile-dir tile cache directory (defaults to '" HASH_PATH "')\n");
fprintf(stderr, " -z, --min-zoom=ZOOM filter input to only render tiles greater or equal to this zoom level (default is 0)\n");
Expand Down
4 changes: 3 additions & 1 deletion src/render_old.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static struct timeval start, end;

int foreground = 1;


struct keepalive_settings keepalives;

void display_rate(struct timeval start, struct timeval end, int num)
{
Expand Down Expand Up @@ -199,6 +199,8 @@ int main(int argc, char **argv)
int dd, mm, yy;
struct tm tm;

memset(&keepalives, 0, sizeof(struct keepalive_settings));

while (1) {
int option_index = 0;
static struct option long_options[] = {
Expand Down
43 changes: 43 additions & 0 deletions src/render_submit_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
Expand Down Expand Up @@ -306,10 +307,52 @@ int make_connection(const char *spath)
continue;
}

if (keepalives.enabled) {
fprintf(stderr, "Enabling TCP keepalives\n");
if (keepalives.time > 0) {
fprintf(stderr, "TCP keepalives configuration: time=%d, interval=%d, probes=%d\n",
keepalives.time,
keepalives.interval,
keepalives.probes
);
}
int optval = 0;
socklen_t optlen = sizeof(optval);

optval = 1;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
perror("setsockopt()");
close(fd);
exit(2);
}

#ifdef LINUX
if (keepalives.time > 0 && setsockopt(fd, SOL_SOCKET, TCP_KEEPIDLE, &keepalives.time, sizeof(keepalives.time)) < 0) {
perror("setsockopt()");
close(fd);
exit(2);
}

if (keepalives.interval > 0 && setsockopt(fd, SOL_SOCKET, TCP_KEEPINTVL, &keepalives.interval, sizeof(keepalives.interval)) < 0) {
perror("setsockopt()");
close(fd);
exit(2);
}

if (keepalives.probes > 0 && setsockopt(fd, SOL_SOCKET, TCP_KEEPCNT, &keepalives.probes, sizeof(keepalives.probes)) < 0) {
perror("setsockopt()");
close(fd);
exit(2);
}
#endif

}

char resolved_addr[NI_MAXHOST];
char resolved_port[NI_MAXSERV];
int name_info = getnameinfo(rp->ai_addr, rp->ai_addrlen, resolved_addr, sizeof(resolved_addr), resolved_port, sizeof(resolved_port), NI_NUMERICHOST | NI_NUMERICSERV);
if (name_info != 0) {
close(fd);
fprintf(stderr, "cannot retrieve name info: %d\n", name_info);
exit(2);
}
Expand Down
4 changes: 4 additions & 0 deletions src/speedtest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ int main(int argc, char **argv)
}
#else

struct keepalive_settings keepalives;

static const int minZoom = 0;
static const int maxZoom = 18;

Expand Down Expand Up @@ -208,6 +210,8 @@ int main(int argc, char **argv)
int verbose = 0;
int numThreads = 1;

memset(&keepalives, 0, sizeof(struct keepalive_settings));

while (1) {
int option_index = 0;
static struct option long_options[] = {
Expand Down