From 9686dabd044666f32cbc30f7551caf81a05124e2 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 26 May 2015 14:26:47 -0700 Subject: Initial refactoring and context API changes --- src/core/census/README.md | 76 ++++++++++++++++++++++++++++++++ src/core/census/context.c | 59 +++++++++++++++++++++++++ src/core/census/context.h | 49 ++++++++++++++++++++ src/core/census/grpc_context.c | 41 +++++++++++++++++ src/core/census/grpc_context.h | 42 ++++++++++++++++++ src/core/census/initialize.c | 38 ++++++++++++++++ src/core/surface/call.c | 35 ++++++++------- src/core/surface/channel_create.c | 3 +- src/core/surface/init.c | 4 +- src/core/surface/secure_channel_create.c | 3 +- src/core/surface/server.c | 15 +++++-- 11 files changed, 341 insertions(+), 24 deletions(-) create mode 100644 src/core/census/README.md create mode 100644 src/core/census/context.c create mode 100644 src/core/census/context.h create mode 100644 src/core/census/grpc_context.c create mode 100644 src/core/census/grpc_context.h create mode 100644 src/core/census/initialize.c (limited to 'src/core') diff --git a/src/core/census/README.md b/src/core/census/README.md new file mode 100644 index 0000000000..fb615a2194 --- /dev/null +++ b/src/core/census/README.md @@ -0,0 +1,76 @@ + + +# Census - a resource measurement and tracing system + +This directory contains code for Census, which will ultimately provide the +following features for any gRPC-using system: +* A [dapper](http://research.google.com/pubs/pub36356.html)-like tracing + system, enabling tracing across a distributed infrastructure. +* RPC statistics and measurements for key metrics, such as latency, bytes + transferred, number of errors etc. +* Resource measurement framework which can be used for measuring custom + metrics. Through the use of [tags](#Tags), these can be broken down across + the entire distributed stack. +* Easy integration of the above with + [Google Cloud Trace](https://cloud.google.com/tools/cloud-trace) and + [Google Cloud Monitoring](https://cloud.google.com/monitoring/). + +## Concepts + +### Context + +### Operations + +### Tags + +### Metrics + +## API + +### Internal/RPC API + +### External/Client API + +### RPC API + +## Files in this directory + +Note that files and functions in this directory can be split into two +categories: +* Files that define core census library functions. Functions etc. in these + files are named census\_\*, and constitute the core census library + functionality. At some time in the future, these will become a standalone + library. +* Files that define functions etc. that provide a convenient interface between + grpc and the core census functionality. These files are all named + grpc\_\*.{c,h}, and define function names beginning with grpc\_census\_\*. + diff --git a/src/core/census/context.c b/src/core/census/context.c new file mode 100644 index 0000000000..a940e96ec0 --- /dev/null +++ b/src/core/census/context.c @@ -0,0 +1,59 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "context.h" + +#include +#include +#include + +/* Placeholder implementation only. */ + +size_t census_context_serialize(const census_context *context, char *buffer, + size_t buf_size) { + /* TODO(aveitch): implement serialization */ + return 0; +} + +census_context *census_context_deserialize(char *buffer) { + census_context *ret; + if (buffer != NULL) { + /* TODO(aveitch): implement deserialization */ + return NULL; + } + ret = gpr_malloc(sizeof(census_context)); + memset(ret, 0, sizeof(census_context)); + return ret; +} + +void census_context_destroy(census_context *context) { gpr_free(context); } diff --git a/src/core/census/context.h b/src/core/census/context.h new file mode 100644 index 0000000000..d43a69f7e5 --- /dev/null +++ b/src/core/census/context.h @@ -0,0 +1,49 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H +#define GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H + +#include + +/* census_context is the in-memory representation of information needed to + * maintain tracing, RPC statistics and resource usage information. */ +struct census_context { + gpr_uint64 op_id; /* Operation identifier - unique per-context */ + gpr_uint64 trace_id; /* Globally unique trace identifier */ + /* TODO(aveitch) Add census tags: + const census_tag_set *tags; + */ +}; + +#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */ diff --git a/src/core/census/grpc_context.c b/src/core/census/grpc_context.c new file mode 100644 index 0000000000..4b1ba49e70 --- /dev/null +++ b/src/core/census/grpc_context.c @@ -0,0 +1,41 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include "src/core/census/grpc_context.h" + +void *grpc_census_context_create() { return census_context_deserialize(NULL); } + +void grpc_census_context_destroy(void *context) { + census_context_destroy((census_context *)context); +} diff --git a/src/core/census/grpc_context.h b/src/core/census/grpc_context.h new file mode 100644 index 0000000000..f610f6ce21 --- /dev/null +++ b/src/core/census/grpc_context.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* GRPC <--> CENSUS context interface */ + +#ifndef CENSUS_GRPC_CONTEXT_H +#define CENSUS_GRPC_CONTEXT_H + +void *grpc_census_context_create(); +void grpc_census_context_destroy(void *context); + +#endif /* CENSUS_GRPC_CONTEXT_H */ diff --git a/src/core/census/initialize.c b/src/core/census/initialize.c new file mode 100644 index 0000000000..d72c08b91c --- /dev/null +++ b/src/core/census/initialize.c @@ -0,0 +1,38 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +int census_initialize(int functions) { return 0; } + +void census_shutdown() {} diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 50df36cae9..b0b922b642 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -31,6 +31,7 @@ * */ +#include "src/core/census/grpc_context.h" #include "src/core/surface/call.h" #include "src/core/channel/channel_stack.h" #include "src/core/iomgr/alarm.h" @@ -242,9 +243,9 @@ static int fill_send_ops(grpc_call *call, grpc_transport_op *op); static void execute_op(grpc_call *call, grpc_transport_op *op); static void recv_metadata(grpc_call *call, grpc_metadata_batch *metadata); static void finish_read_ops(grpc_call *call); -static grpc_call_error cancel_with_status( - grpc_call *c, grpc_status_code status, const char *description, - gpr_uint8 locked); +static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status, + const char *description, + gpr_uint8 locked); grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq, const void *server_transport_data, @@ -268,6 +269,8 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq, if (call->is_client) { call->request_set[GRPC_IOREQ_SEND_TRAILING_METADATA] = REQSET_DONE; call->request_set[GRPC_IOREQ_SEND_STATUS] = REQSET_DONE; + call->context[GRPC_CONTEXT_TRACING] = grpc_census_context_create(); + call->destroy_context[GRPC_CONTEXT_TRACING] = grpc_census_context_destroy; } GPR_ASSERT(add_initial_metadata_count < MAX_SEND_INITIAL_METADATA_COUNT); for (i = 0; i < add_initial_metadata_count; i++) { @@ -402,7 +405,8 @@ static void lock(grpc_call *call) { gpr_mu_lock(&call->mu); } static int need_more_data(grpc_call *call) { return is_op_live(call, GRPC_IOREQ_RECV_INITIAL_METADATA) || - (is_op_live(call, GRPC_IOREQ_RECV_MESSAGE) && grpc_bbq_empty(&call->incoming_queue)) || + (is_op_live(call, GRPC_IOREQ_RECV_MESSAGE) && + grpc_bbq_empty(&call->incoming_queue)) || is_op_live(call, GRPC_IOREQ_RECV_TRAILING_METADATA) || is_op_live(call, GRPC_IOREQ_RECV_STATUS) || is_op_live(call, GRPC_IOREQ_RECV_STATUS_DETAILS) || @@ -557,13 +561,13 @@ static void finish_live_ioreq_op(grpc_call *call, grpc_ioreq_op op, break; case GRPC_IOREQ_RECV_INITIAL_METADATA: GPR_SWAP(grpc_metadata_array, call->buffered_metadata[0], - *call->request_data[GRPC_IOREQ_RECV_INITIAL_METADATA] - .recv_metadata); + *call->request_data[GRPC_IOREQ_RECV_INITIAL_METADATA] + .recv_metadata); break; case GRPC_IOREQ_RECV_TRAILING_METADATA: GPR_SWAP(grpc_metadata_array, call->buffered_metadata[1], - *call->request_data[GRPC_IOREQ_RECV_TRAILING_METADATA] - .recv_metadata); + *call->request_data[GRPC_IOREQ_RECV_TRAILING_METADATA] + .recv_metadata); break; case GRPC_IOREQ_OP_COUNT: abort(); @@ -653,9 +657,8 @@ static int add_slice_to_message(grpc_call *call, gpr_slice slice) { } /* we have to be reading a message to know what to do here */ if (!call->reading_message) { - cancel_with_status( - call, GRPC_STATUS_INVALID_ARGUMENT, - "Received payload data while not reading a message", 1); + cancel_with_status(call, GRPC_STATUS_INVALID_ARGUMENT, + "Received payload data while not reading a message", 1); return 0; } /* append the slice to the incoming buffer */ @@ -1021,9 +1024,9 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c, return cancel_with_status(c, status, description, 0); } -static grpc_call_error cancel_with_status( - grpc_call *c, grpc_status_code status, const char *description, - gpr_uint8 locked) { +static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status, + const char *description, + gpr_uint8 locked) { grpc_transport_op op; grpc_mdstr *details = description ? grpc_mdstr_from_string(c->metadata_context, description) @@ -1287,8 +1290,8 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, tag); } -void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value, - void (*destroy)(void *value)) { +void grpc_call_context_set(grpc_call *call, grpc_context_index elem, + void *value, void (*destroy)(void *value)) { if (call->destroy_context[elem]) { call->destroy_context[elem](value); } diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index daa8d3a7c6..9fa6696bf6 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -195,9 +195,10 @@ grpc_channel *grpc_channel_create(const char *target, const grpc_channel_filter *filters[MAX_FILTERS]; int n = 0; filters[n++] = &grpc_client_surface_filter; + /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; - } + } */ filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1); diff --git a/src/core/surface/init.c b/src/core/surface/init.c index d6eb9b2c24..5cd5d9197f 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -31,11 +31,11 @@ * */ +#include #include #include "src/core/channel/channel_stack.h" #include "src/core/debug/trace.h" #include "src/core/iomgr/iomgr.h" -#include "src/core/statistics/census_interface.h" #include "src/core/profiling/timers.h" #include "src/core/surface/call.h" #include "src/core/surface/init.h" @@ -64,7 +64,7 @@ void grpc_init(void) { grpc_security_pre_init(); grpc_iomgr_init(); grpc_tracer_init("GRPC_TRACE"); - census_init(); + census_initialize(CENSUS_NONE); grpc_timers_global_init(); } gpr_mu_unlock(&g_init_mu); diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 3e331293b5..23156c981e 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -234,9 +234,10 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, new_args_from_connector != NULL ? new_args_from_connector : args, &connector_arg); filters[n++] = &grpc_client_surface_filter; + /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { filters[n++] = &grpc_client_census_filter; - } + } */ filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1); diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 351ed5b758..b8ac410687 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -592,9 +592,15 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } static const grpc_channel_filter server_surface_filter = { - server_start_transport_op, channel_op, sizeof(call_data), init_call_elem, - destroy_call_elem, sizeof(channel_data), init_channel_elem, - destroy_channel_elem, "server", + server_start_transport_op, + channel_op, + sizeof(call_data), + init_call_elem, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + "server", }; void grpc_server_register_completion_queue(grpc_server *server, @@ -640,9 +646,10 @@ grpc_server *grpc_server_create_from_filters(grpc_channel_filter **filters, server->channel_filters = gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *)); server->channel_filters[0] = &server_surface_filter; + /* TODO(census) if (census_enabled) { server->channel_filters[1] = &grpc_server_census_filter; - } + } */ for (i = 0; i < filter_count; i++) { server->channel_filters[i + 1 + census_enabled] = filters[i]; } -- cgit v1.2.3