From: Sebastian Harl Date: Sun, 14 Sep 2014 10:14:48 +0000 (+0200) Subject: frontend, proto: Include the response data type in query replies. X-Git-Tag: sysdb-0.5.0~37 X-Git-Url: https://git.tokkee.org/?p=sysdb.git;a=commitdiff_plain;h=ee8df3b190c2eb49e460dcf03f81288a5d825c39;hp=210fe5d90e273805bdf764adc6167cdbf17c82b5 frontend, proto: Include the response data type in query replies. For that purpose, use the newly added CONNECTION_DATA status instead of CONNECTION_OK for query replies and include the data type as the first field in the message body. The type is the same as the respective command type. --- diff --git a/src/frontend/query.c b/src/frontend/query.c index bbf9853..52d27ec 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -205,6 +205,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, { sdb_strbuf_t *buf; sdb_store_obj_t *host; + uint32_t type = htonl(CONNECTION_FETCH); host = sdb_store_get_host(name); if (! host) { @@ -228,6 +229,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, return -1; } + sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); if (sdb_store_host_tojson(host, buf, filter, /* flags = */ 0)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "host '%s' to JSON", name); @@ -237,7 +239,7 @@ sdb_fe_exec_fetch(sdb_conn_t *conn, const char *name, return -1; } - sdb_connection_send(conn, CONNECTION_OK, + sdb_connection_send(conn, CONNECTION_DATA, (uint32_t)sdb_strbuf_len(buf), sdb_strbuf_string(buf)); sdb_strbuf_destroy(buf); sdb_object_deref(SDB_OBJ(host)); @@ -248,6 +250,7 @@ int sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter) { sdb_strbuf_t *buf; + uint32_t type = htonl(CONNECTION_LIST); buf = sdb_strbuf_create(1024); if (! buf) { @@ -261,6 +264,7 @@ sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter) return -1; } + sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); if (sdb_store_tojson(buf, filter, /* flags = */ SDB_SKIP_ALL)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to serialize " "store to JSON"); @@ -269,7 +273,7 @@ sdb_fe_exec_list(sdb_conn_t *conn, sdb_store_matcher_t *filter) return -1; } - sdb_connection_send(conn, CONNECTION_OK, + sdb_connection_send(conn, CONNECTION_DATA, (uint32_t)sdb_strbuf_len(buf), sdb_strbuf_string(buf)); sdb_strbuf_destroy(buf); return 0; @@ -280,6 +284,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m, sdb_store_matcher_t *filter) { tojson_data_t data = { NULL, filter, 0 }; + uint32_t type = htonl(CONNECTION_LOOKUP); data.buf = sdb_strbuf_create(1024); if (! data.buf) { @@ -293,6 +298,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m, return -1; } + sdb_strbuf_memcpy(data.buf, &type, sizeof(uint32_t)); sdb_strbuf_append(data.buf, "["); /* Let the JSON serializer handle the filter instead of the scanner. Else, @@ -308,7 +314,7 @@ sdb_fe_exec_lookup(sdb_conn_t *conn, sdb_store_matcher_t *m, sdb_strbuf_append(data.buf, "]"); - sdb_connection_send(conn, CONNECTION_OK, + sdb_connection_send(conn, CONNECTION_DATA, (uint32_t)sdb_strbuf_len(data.buf), sdb_strbuf_string(data.buf)); sdb_strbuf_destroy(data.buf); return 0; @@ -320,6 +326,7 @@ sdb_fe_exec_timeseries(sdb_conn_t *conn, sdb_timeseries_opts_t *opts) { sdb_strbuf_t *buf; + uint32_t type = htonl(CONNECTION_TIMESERIES); buf = sdb_strbuf_create(1024); if (! buf) { @@ -332,6 +339,7 @@ sdb_fe_exec_timeseries(sdb_conn_t *conn, return -1; } + sdb_strbuf_memcpy(buf, &type, sizeof(uint32_t)); if (sdb_store_fetch_timeseries(hostname, metric, opts, buf)) { sdb_log(SDB_LOG_ERR, "frontend: Failed to fetch time-series"); sdb_strbuf_sprintf(conn->errbuf, "Failed to fetch time-series"); @@ -339,7 +347,7 @@ sdb_fe_exec_timeseries(sdb_conn_t *conn, return -1; } - sdb_connection_send(conn, CONNECTION_OK, + sdb_connection_send(conn, CONNECTION_DATA, (uint32_t)sdb_strbuf_len(buf), sdb_strbuf_string(buf)); sdb_strbuf_destroy(buf); return 0; diff --git a/src/include/frontend/proto.h b/src/include/frontend/proto.h index 9e02400..c006c49 100644 --- a/src/include/frontend/proto.h +++ b/src/include/frontend/proto.h @@ -53,15 +53,46 @@ extern "C" { typedef enum { /* * CONNECTION_OK: - * Indicates that a command was successful. The message body will contain - * the result of the command (if any) encoded as a JSON string. + * Indicates that a command was successful. The message body will usually + * be empty but may contain a string providing unformatted information + * providing more details. + * + * 0 32 64 + * +---------------+---------------+ + * | message type | length | + * +---------------+---------------+ + * | optional status message ... | */ CONNECTION_OK = 0, + /* + * CONNECTION_DATA: + * Indicates that a data query was successful. The message body will + * contain the type of the data and the result encoded as a JSON string. + * The type is the same as the command code of the respective command (see + * below) and is stored as an unsigned 32bit integer in network + * byte-order. The result may be empty (but the type is still included). + * + * 0 32 64 + * +---------------+---------------+ + * | message type | length | + * +---------------+---------------+ + * | result type | result ... | + * +---------------+ | + * | ... | + */ + CONNECTION_DATA, + /* * CONNECTION_ERROR: * Indicates that a command has failed. The message body will contain a * string describing the error. + * + * 0 32 64 + * +---------------+---------------+ + * | message type | length | + * +---------------+---------------+ + * | error message ... | */ CONNECTION_ERROR, @@ -70,6 +101,12 @@ typedef enum { * Indicates an asynchronous log message. The message body will contain * the message string providing informational or warning logs. Log * messages may be sent to the client any time. + * + * 0 32 64 + * +---------------+---------------+ + * | message type | length | + * +---------------+---------------+ + * | log message ... | */ CONNECTION_LOG, } sdb_conn_status_t; @@ -103,7 +140,12 @@ typedef enum { CONNECTION_STARTUP, /* - * Querying the server. + * Querying the server. On success, the server replies with + * CONNECTION_DATA. + * + * The command codes listed here are used, both, for sending a query to + * the server and to indicate the response type from a query in a DATA + * message. */ /* diff --git a/src/tools/sysdb/command.c b/src/tools/sysdb/command.c index 9dfb619..718309b 100644 --- a/src/tools/sysdb/command.c +++ b/src/tools/sysdb/command.c @@ -75,6 +75,10 @@ sdb_command_print_reply(sdb_client_t *client) status = (int)rcode; result = sdb_strbuf_string(recv_buf); + /* At the moment, we don't care about the result type. We simply print the + * result without further parsing it. */ + if (status == CONNECTION_DATA) + result += sizeof(uint32_t); if (result && *result) printf("%s\n", result); else if (rcode == UINT32_MAX) { diff --git a/src/tools/sysdb/main.c b/src/tools/sysdb/main.c index fc226f9..331cfa2 100644 --- a/src/tools/sysdb/main.c +++ b/src/tools/sysdb/main.c @@ -194,7 +194,7 @@ execute_commands(sdb_client_t *client, sdb_llist_t *commands) } /* Wait for server replies. We might get any number of log messages - * but eventually see the reply to the query, which is either OK or + * but eventually see the reply to the query, which is either DATA or * ERROR. */ while (42) { status = sdb_command_print_reply(client); @@ -203,12 +203,19 @@ execute_commands(sdb_client_t *client, sdb_llist_t *commands) break; } - if ((status == CONNECTION_OK) || (status == CONNECTION_ERROR)) + if ((status == CONNECTION_DATA) || (status == CONNECTION_ERROR)) break; + if (status == CONNECTION_OK) { + /* pre 0.4 versions used OK instead of DATA */ + sdb_log(SDB_LOG_WARNING, "Received unexpected OK status from " + "server in response to a QUERY (expected DATA); " + "assuming we're talking to an old server"); + break; + } } - if (status) - break; + if ((status != CONNECTION_OK) && (status != CONNECTION_DATA)) + break; /* error */ } sdb_llist_iter_destroy(iter); @@ -302,7 +309,9 @@ main(int argc, char **argv) int status = execute_commands(input.client, commands); sdb_llist_destroy(commands); sdb_client_destroy(input.client); - exit(status); + if ((status != CONNECTION_OK) && (status != CONNECTION_DATA)) + exit(1); + exit(0); } sdb_log(SDB_LOG_INFO, "SysDB client "SDB_CLIENT_VERSION_STRING