mirror of https://github.com/grpc/grpc.git
commit
194b23856a
1381 changed files with 86849 additions and 28891 deletions
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@ |
||||
There are times when we make changes that include a temporary shim for |
||||
backward-compatibility (e.g., a macro or some other function to preserve |
||||
the original API) to avoid having to bump the major version number in |
||||
the next release. However, when we do eventually want to release a |
||||
feature that does change the API in a non-backward-compatible way, we |
||||
will wind up bumping the major version number anyway, at which point we |
||||
can take the opportunity to clean up any pending backward-compatibility |
||||
shims. |
||||
|
||||
This file lists all pending backward-compatibility changes that should |
||||
be cleaned up the next time we are going to bump the major version |
||||
number: |
||||
|
||||
- remove `GRPC_ARG_MAX_MESSAGE_LENGTH` channel arg from |
||||
`include/grpc/impl/codegen/grpc_types.h` (commit `af00d8b`) |
||||
- remove `ServerBuilder::SetMaxMessageSize()` method from |
||||
`include/grpc++/server_builder.h` (commit `6980362`) |
||||
- remove `GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY` macro from |
||||
`include/grpc/impl/codegen/grpc_types.h` (commit `59c9f90`) |
@ -0,0 +1,15 @@ |
||||
There are times when we make changes that include a temporary shim for |
||||
backward-compatibility (e.g., a macro or some other function to preserve |
||||
the original API) to avoid having to bump the major version number in |
||||
the next release. However, when we do eventually want to release a |
||||
feature that does change the API in a non-backward-compatible way, we |
||||
will wind up bumping the major version number anyway, at which point we |
||||
can take the opportunity to clean up any pending backward-compatibility |
||||
shims. |
||||
|
||||
This file lists all pending backward-compatibility changes that should |
||||
be cleaned up the next time we are going to bump the major version |
||||
number: |
||||
|
||||
- remove `ClientContext::set_fail_fast()` method from |
||||
`include/grpc++/impl/codegen/client_context.h` (commit `9477724`) |
@ -0,0 +1,67 @@ |
||||
gRPC environment variables |
||||
-------------------------- |
||||
|
||||
gRPC C core based implementations (those contained in this repository) expose |
||||
some configuration as environment variables that can be set. |
||||
|
||||
* GRPC_ABORT_ON_LEAKS |
||||
A debugging aid to cause a call to abort() when gRPC objects are leaked past |
||||
grpc_shutdown(). Set to 1 to cause the abort, if unset or 0 it does not |
||||
abort the process. |
||||
|
||||
* GOOGLE_APPLICATION_CREDENTIALS |
||||
The path to find the credentials to use when Google credentials are created |
||||
|
||||
* GRPC_SSL_CIPHER_SUITES |
||||
A colon separated list of cipher suites to use with OpenSSL |
||||
Defaults to: |
||||
ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384 |
||||
|
||||
* GRPC_DEFAULT_SSL_ROOTS_FILE_PATH |
||||
PEM file to load SSL roots from |
||||
|
||||
* GRPC_POLL_STRATEGY [posix-style environments only] |
||||
Declares which polling engines to try when starting gRPC. |
||||
This is a comma-separated list of engines, which are tried in priority order |
||||
first -> last. |
||||
Available polling engines include: |
||||
- epoll (linux-only) - a polling engine based around the epoll family of |
||||
system calls |
||||
- poll - a portable polling engine based around poll(), intended to be a |
||||
fallback engine when nothing better exists |
||||
- legacy - the (deprecated) original polling engine for gRPC |
||||
|
||||
* GRPC_TRACE |
||||
A comma separated list of tracers that provide additional insight into how |
||||
gRPC C core is processing requests via debug logs. Available tracers include: |
||||
- api - traces api calls to the C core |
||||
- channel - traces operations on the C core channel stack |
||||
- combiner - traces combiner lock state |
||||
- compression - traces compression operations |
||||
- connectivity_state - traces connectivity state changes to channels |
||||
- channel_stack_builder - traces information about channel stacks being built |
||||
- http - traces state in the http2 transport engine |
||||
- http1 - traces HTTP/1.x operations performed by gRPC |
||||
- flowctl - traces http2 flow control |
||||
- op_failure - traces error information when failure is pushed onto a |
||||
completion queue |
||||
- pending_tags - [debug builds only] traces still-in-progress tags on |
||||
completion queues |
||||
- round_robin - traces the round_robin load balancing policy |
||||
- glb - traces the grpclb load balancer |
||||
- queue_pluck |
||||
- queue_timeout |
||||
- server_channel - lightweight trace of significant server channel events |
||||
- secure_endpoint - traces bytes flowing through encrypted channels |
||||
- transport_security - traces metadata about secure channel establishment |
||||
- tcp - traces bytes in and out of a channel |
||||
'all' can additionally be used to turn all traces on. |
||||
Individual traces can be disabled by prefixing them with '-'. |
||||
Example: |
||||
export GRPC_TRACE=all,-pending_tags |
||||
|
||||
* GRPC_VERBOSITY |
||||
Default gRPC logging verbosity - one of: |
||||
- DEBUG - log all gRPC messages |
||||
- INFO - log INFO and ERROR message |
||||
- ERROR - log only errors |
@ -0,0 +1,121 @@ |
||||
# `epoll`-based pollset implementation in gRPC |
||||
|
||||
Sree Kuchibhotla (sreek@) [May - 2016] |
||||
(Design input from Craig Tiller and David Klempner) |
||||
|
||||
> Status: As of June 2016, this change is implemented and merged. |
||||
|
||||
> * The bulk of the functionality is in: [ev_poll_linux.c](https://github.com/grpc/grpc/blob/master/src/core/lib/iomgr/ev_epoll_linux.c) |
||||
> * Pull request: https://github.com/grpc/grpc/pull/6803 |
||||
|
||||
## 1. Introduction |
||||
The document talks about the proposed changes to `epoll`-based implementation of pollsets in gRPC. Section-2 gives an overview of the current implementation, Section-3 talks about the problems in the current implementation and finally Section-4 talks about the proposed changes. |
||||
|
||||
## 2. Current `epoll`-based implementation in gRPC |
||||
|
||||
![image](images/old_epoll_impl.png) |
||||
|
||||
**Figure 1: Current implementation** |
||||
|
||||
A gRPC client or a server can have more than one completion queue. Each completion queue creates a pollset. |
||||
|
||||
The gRPC core library does not create any threads[^1] on its own and relies on the application using the gRPC core library to provide the threads. A thread starts to poll for events by calling the gRPC core surface APIs `grpc_completion_queue_next()` or `grpc_completion_queue_pluck()`. More than one thread can call `grpc_completion_queue_next()`on the same completion queue[^2]. |
||||
|
||||
A file descriptor can be in more than one completion queue. There are examples in the next section that show how this can happen. |
||||
|
||||
When an event of interest happens in a pollset, multiple threads are woken up and there are no guarantees on which thread actually ends up performing the work i.e executing the callbacks associated with that event. The thread that performs the work finally queues a completion event `grpc_cq_completion` on the appropriate completion queue and "kicks" (i.e wakes ups) the thread that is actually interested in that event (which can be itself - in which case there is no thread hop) |
||||
|
||||
For example, in **Figure 1**, if `fd1` becomes readable, any one of the threads i.e *Threads 1* to *Threads K* or *Thread P*, might be woken up. Let's say *Thread P* was calling a `grpc_completion_queue_pluck()` and was actually interested in the event on `fd1` but *Thread 1* woke up. In this case, *Thread 1* executes the callbacks and finally kicks *Thread P* by signalling `event_fd_P`. *Thread P* wakes up, realizes that there is a new completion event for it and returns from `grpc_completion_queue_pluck()` to its caller. |
||||
|
||||
## 3. Issues in the current architecture |
||||
|
||||
### _Thundering Herds_ |
||||
|
||||
If multiple threads concurrently call `epoll_wait()`, we are guaranteed that only one thread is woken up if one of the `fds` in the set becomes readable/writable. However, in our current implementation, the threads do not directly call a blocking `epoll_wait()`[^3]. Instead, they call `poll()` on the set containing `[event_fd`[^4]`, epoll_fd]`. **(see Figure 1)** |
||||
|
||||
Considering the fact that an `fd` can be in multiple `pollsets` and that each `pollset` might have multiple poller threads, it means that whenever an `fd` becomes readable/writable, all the threads in all the `pollsets` (in which that `fd` is present) are woken up. |
||||
|
||||
The performance impact of this would be more conspicuous on the server side. Here are a two examples of thundering herds on the server side. |
||||
|
||||
Example 1: Listening fds on server |
||||
|
||||
* A gRPC server can have multiple server completion queues (i.e completion queues which are used to listen for incoming channels). |
||||
* A gRPC server can also listen on more than one TCP-port. |
||||
* A listening socket is created for each port the gRPC server would be listening on. |
||||
* Every listening socket's fd is added to all the server completion queues' pollsets. (Currently we do not do any sharding of the listening fds across these pollsets). |
||||
|
||||
This means that for every incoming new channel, all the threads waiting on all the pollsets are woken up. |
||||
|
||||
Example 2: New Incoming-channel fds on server |
||||
|
||||
* Currently, every new incoming channel's `fd` (i.e the socket `fd` that is returned by doing an `accept()` on the new incoming channel) is added to all the server completion queues' pollsets [^5]). |
||||
* Clearly, this would also cause all thundering herd problem for every read onthat fd |
||||
|
||||
There are other scenarios especially on the client side where an fd can end up being on multiple pollsets which would cause thundering herds on the clients. |
||||
|
||||
|
||||
## 4. Proposed changes to the current `epoll`-based polling implementation: |
||||
|
||||
The main idea in this proposal is to group 'related' `fds` into a single epoll-based set. This would ensure that only one thread wakes up in case of an event on one of the `fds` in the epoll set. |
||||
|
||||
To accomplish this, we introduce a new abstraction called `polling_island` which will have an epoll set underneath (See **Figure 2** below). A `polling_island` contains the following: |
||||
|
||||
* `epoll_fd`: The file descriptor of the underlying epoll set |
||||
* `fd_set`: The set of 'fds' in the pollset island i.e in the epoll set (The pollset island merging operation described later requires the list of fds in the pollset island and currently there is no API available to enumerate all the fds in an epoll set) |
||||
* `event_fd`: A level triggered _event fd_ that is used to wake up all the threads waiting on this epoll set (Note: This `event_fd` is added to the underlying epoll set during pollset island creation. This is useful in the pollset island merging operation described later) |
||||
* `merged_to`: The polling island into which this one merged. See section 4.2 (case 2) for more details on this. Also note that if `merged_to` is set, all the other fields in this polling island are not used anymore |
||||
|
||||
In this new model, only one thread wakes up whenever an event of interest happens in an epoll set. |
||||
|
||||
![drawing](images/new_epoll_impl.png) |
||||
|
||||
**Figure 2: Proposed changes** |
||||
|
||||
### 4.1 Relation between `fd`, `pollset` and `polling_island:` |
||||
|
||||
* An `fd` may belong to multiple `pollsets` but belongs to exactly one `polling_island` |
||||
* A `pollset` belongs to exactly one `polling_island` |
||||
* An `fd` and the `pollset(s`) it belongs to, have same `polling_island` |
||||
|
||||
### 4.2 Algorithm to add an `fd` to a `pollset` |
||||
|
||||
There are two cases to check here: |
||||
|
||||
* **Case 1:** Both `fd` and `pollset` already belong to the same `polling_island` |
||||
* This is straightforward and nothing really needs to be done here |
||||
* **Case 2:** The `fd `and `pollset` point to different `polling_islands`: In this case we _merge_ both the polling islands i.e: |
||||
* Add all the `fds` from the smaller `polling_island `to the larger `polling_island` and update the `merged_to` pointer on the smaller island to point to the larger island. |
||||
* Wake up all the threads waiting on the smaller `polling_island`'s `epoll_fd` (by signalling the `event_fd` on that island) and make them now wait on the larger `polling_island`'s `epoll_fd` |
||||
* Update `fd` and `pollset` to now point to the larger `polling_island` |
||||
|
||||
### 4.3 Directed wakeups: |
||||
|
||||
The new implementation, just like the current implementation, does not provide us any guarantees that the thread that is woken up is the thread that is actually interested in the event. So the thread that woke up executes the callbacks and finally has to 'kick' the appropriate polling thread interested in the event. |
||||
|
||||
In the current implementation, every polling thread also had a `event_fd` on which it was listening to and hence waking it up was as simple as signalling that `event_fd`. However, using an `event_fd` also meant that every thread has to use a `poll()` (on `event_fd` and `epoll_fd`) instead of doing an `epoll_wait()` and this resulted in the thundering herd problems described above. |
||||
|
||||
The proposal here is to use signals and kicking a thread would just be sending a signal to that thread. Unfortunately there are only a few signals available on posix systems and most of them have pre-determined behavior leaving only a few signals `SIGUSR1`, `SIGUSR2` and `SIGRTx (SIGRTMIN to SIGRTMAX)` for custom use. |
||||
|
||||
The calling application might have registered other signal handlers for these signals. `We will provide a new API where the applications can "give a signal number" to gRPC library to use for this purpose. |
||||
|
||||
``` |
||||
void grpc_use_signal(int signal_num) |
||||
``` |
||||
|
||||
If the calling application does not provide a signal number, then the gRPC library will relegate to using a model similar to the current implementation (where every thread does a blocking `poll()` on its `wakeup_fd` and the `epoll_fd`). The function` psi_wait() `in figure 2 implements this logic. |
||||
|
||||
**>> **(**NOTE**: Or alternatively, we can implement a turnstile polling (i.e having only one thread calling `epoll_wait()` on the epoll set at any time - which all other threads call poll on their `wakeup_fds`) |
||||
in case of not getting a signal number from the applications. |
||||
|
||||
|
||||
## Notes |
||||
|
||||
[^1]: Only exception is in case of name-resolution |
||||
|
||||
[^2]: However, a `grpc_completion_queue_next()` and `grpc_completion_queue_pluck()` must not be called in parallel on the same completion queue |
||||
|
||||
[^3]: The threads first do a blocking` poll()` with `[wakeup_fd, epoll_fd]`. If the `poll()` returns due to an event of interest in the epoll set, they then call a non-blocking i.e a zero-timeout `epoll_wait()` on the `epoll_fd` |
||||
|
||||
[^4]: `event_fd` is the linux platform specific implementation of `grpc_wakeup_fd`. A `wakeup_fd` is used to wake up polling threads typically when the event for which the polling thread is waiting is already completed by some other thread. It is also used to wake up the polling threads in case of shutdowns or to re-evaluate the poller's interest in the fds to poll (the last scenario is only in case of `poll`-based (not `epoll`-based) implementation of `pollsets`). |
||||
|
||||
[^5]: See more details about the issue here https://github.com/grpc/grpc/issues/5470 and for a proposed fix here: https://github.com/grpc/grpc/pull/6149 |
@ -0,0 +1,30 @@ |
||||
# HTTP to gRPC Status Code Mapping |
||||
|
||||
Since intermediaries are a common part of HTTP infrastructure some responses to |
||||
gRPC requests may be received that do not include the grpc-status header. In |
||||
some cases mapping error codes from an intermediary allows the gRPC client to |
||||
behave more appropriately to the error situation without overloading the |
||||
semantics of either error code. |
||||
|
||||
This table is to be used _only_ for clients that received a response that did |
||||
not include grpc-status. If grpc-status was provided, it _must_ be used. Servers |
||||
_must not_ use this table to determine an HTTP status code to use; the mappings |
||||
are neither symmetric nor 1-to-1. |
||||
|
||||
| HTTP Status Code | gRPC Status Code | |
||||
|----------------------------|--------------------| |
||||
| 400 Bad Request | INTERNAL | |
||||
| 401 Unauthorized | UNAUTHENTICATED | |
||||
| 403 Forbidden | PERMISSION\_DENIED | |
||||
| 404 Not Found | UNIMPLEMENTED | |
||||
| 429 Too Many Requests | UNAVAILABLE | |
||||
| 502 Bad Gateway | UNAVAILABLE | |
||||
| 503 Service Unavailable | UNAVAILABLE | |
||||
| 504 Gateway Timeout | UNAVAILABLE | |
||||
| _All other codes_ | UNKNOWN | |
||||
|
||||
Technically, 1xx should have the entire header skipped and a subsequent header |
||||
be read. See RFC 7540 §8.1. |
||||
|
||||
200 is UNKNOWN because there should be a grpc-status in case of truly OK |
||||
response. |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 62 KiB |
@ -0,0 +1,192 @@ |
||||
# gRPC Server Reflection Tutorial |
||||
|
||||
gRPC Server Reflection provides information about publicly-accessible gRPC |
||||
services on a server, and assists clients at runtime to construct RPC |
||||
requests and responses without precompiled service information. It is used by |
||||
gRPC CLI, which can be used to introspect server protos and send/receive test |
||||
RPCs. |
||||
|
||||
## Enable Server Reflection |
||||
|
||||
### Enable server reflection in C++ servers |
||||
|
||||
C++ Server Reflection is an add-on library, `libgrpc++_reflction`. To enable C++ |
||||
server reflection, you can link this library to your server binary. |
||||
|
||||
Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly |
||||
contain symbols used by the application. On these platforms, LD flag |
||||
`--no-as-needed` is needed for for dynamic linking and `--whole-archive` is |
||||
needed for for static linking. |
||||
|
||||
This [Makefile](../examples/cpp/helloworld/Makefile#L37#L45) demonstrates |
||||
enabling c++ server reflection on Linux and MacOS. |
||||
|
||||
## Test services using Server Reflection |
||||
|
||||
After enabling Server Reflection in a server application, you can use gRPC CLI |
||||
to test its services. |
||||
|
||||
Instructions on how to use gRPC CLI can be found at |
||||
[command_line_tool.md](command_line_tool.md), or using `grpc_cli help` command. |
||||
|
||||
Here we use `examples/cpp/helloworld` as an example to show the use of gRPC |
||||
Server Reflection and gRPC CLI. First, we need to build gRPC CLI and setup an |
||||
example server with Server Reflection enabled. |
||||
|
||||
- Setup an example server |
||||
|
||||
Server Reflection has already been enabled in the |
||||
[Makefile](../examples/cpp/helloworld/Makefile) of the helloworld example. We |
||||
can simply make it and run the greeter_server. |
||||
|
||||
```sh |
||||
$ make -C examples/cpp/helloworld |
||||
$ examples/cpp/helloworld/greeter_server & |
||||
``` |
||||
|
||||
- Build gRPC CLI |
||||
|
||||
```sh |
||||
make grpc_cli |
||||
cd bins/opt |
||||
``` |
||||
|
||||
gRPC CLI binary `grpc_cli` can be found at `bins/opt/` folder. This tool is |
||||
still new and does not have a `make install` target yet. |
||||
|
||||
### List services |
||||
|
||||
`grpc_cli ls` command lists services and methods exposed at a given port |
||||
|
||||
- List all the services exposed at a given port |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
helloworld.Greeter |
||||
grpc.reflection.v1alpha.ServerReflection |
||||
``` |
||||
|
||||
- List one service with details |
||||
|
||||
`grpc_cli ls` command inspects a service given its full name (in the format of |
||||
\<package\>.\<service\>). It can print information with a long listing format |
||||
when `-l` flag is set. This flag can be used to get more details about a |
||||
service. |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 helloworld.Greeter -l |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
filename: helloworld.proto |
||||
package: helloworld; |
||||
service Greeter { |
||||
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
||||
} |
||||
|
||||
``` |
||||
|
||||
### List methods |
||||
|
||||
- List one method with details |
||||
|
||||
`grpc_cli ls` command also inspects a method given its full name (in the |
||||
format of \<package\>.\<service\>.\<method\>). |
||||
|
||||
```sh |
||||
$ grpc_cli ls localhost:50051 helloworld.Greeter.SayHello -l |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
rpc SayHello(helloworld.HelloRequest) returns (helloworld.HelloReply) {} |
||||
``` |
||||
|
||||
### Inspect message types |
||||
|
||||
We can use`grpc_cli type` command to inspect request/response types given the |
||||
full name of the type (in the format of \<package\>.\<type\>). |
||||
|
||||
- Get information about the request type |
||||
|
||||
```sh |
||||
$ grpc_cli type localhost:50051 helloworld.HelloRequest |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
message HelloRequest { |
||||
optional string name = 1; |
||||
} |
||||
``` |
||||
|
||||
### Call a remote method |
||||
|
||||
We can send RPCs to a server and get responses using `grpc_cli call` command. |
||||
|
||||
- Call a unary method |
||||
|
||||
```sh |
||||
$ grpc_cli call localhost:50051 SayHello "name: 'gRPC CLI'" |
||||
``` |
||||
|
||||
output: |
||||
```sh |
||||
message: "Hello gRPC CLI" |
||||
``` |
||||
|
||||
## Use Server Reflection in a C++ client |
||||
|
||||
Server Reflection can be used by clients to get information about gRPC services |
||||
at runtime. We've provided a descriptor database called |
||||
[grpc::ProtoReflectionDescriptorDatabase](../test/cpp/util/proto_reflection_descriptor_database.h) |
||||
which implements the |
||||
[google::protobuf::DescriptorDatabase](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor_database#DescriptorDatabase) |
||||
interface. It manages the communication between clients and reflection services |
||||
and the storage of received information. Clients can use it as using a local |
||||
descriptor database. |
||||
|
||||
- To use Server Reflection with grpc::ProtoReflectionDescriptorDatabase, first |
||||
initialize an instance with a grpc::Channel. |
||||
|
||||
```c++ |
||||
std::shared_ptr<grpc::Channel> channel = |
||||
grpc::CreateChannel(server_address, server_cred); |
||||
grpc::ProtoReflectionDescriptorDatabase reflection_db(channel); |
||||
``` |
||||
|
||||
- Then use this instance to feed a |
||||
[google::protobuf::DescriptorPool](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool). |
||||
|
||||
```c++ |
||||
google::protobuf::DescriptorPool desc_pool(&reflection_db); |
||||
``` |
||||
|
||||
- Example usage of this descriptor pool |
||||
|
||||
* Get Service/method descriptors. |
||||
|
||||
```c++ |
||||
const google::protobuf::ServiceDescriptor* service_desc = |
||||
desc_pool->FindServiceByName("helloworld.Greeter"); |
||||
const google::protobuf::MethodDescriptor* method_desc = |
||||
desc_pool->FindMethodByName("helloworld.Greeter.SayHello"); |
||||
``` |
||||
|
||||
* Get message type descriptors. |
||||
|
||||
```c++ |
||||
const google::protobuf::Descriptor* request_desc = |
||||
desc_pool->FindMessageTypeByName("helloworld.HelloRequest"); |
||||
``` |
||||
|
||||
* Feed [google::protobuf::DynamicMessageFactory](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.dynamic_message#DynamicMessageFactory). |
||||
|
||||
```c++ |
||||
google::protobuf::DynamicMessageFactory(&desc_pool); |
||||
``` |
@ -0,0 +1,92 @@ |
||||
# Stress Test framework for gRPC |
||||
|
||||
(Sree Kuchibhotla - sreek@) |
||||
|
||||
> Status: This is implemented. More details at [README.md](https://github.com/grpc/grpc/blob/master/tools/run_tests/stress_test/README.md) |
||||
|
||||
|
||||
**I. GOALS** |
||||
|
||||
1) Build a stress test suite for gRPC: |
||||
|
||||
* Build a stress test suite that can Identify bugs by testing the system (gRPC server/client) under extreme conditions: |
||||
* High load |
||||
* High concurrency |
||||
* Limited resources |
||||
* Intermittent failures |
||||
* Should be integrated with Jenkins CI |
||||
|
||||
2) Make it generic enough (i.e build a generic test framework) that can be used for: |
||||
|
||||
* Executing M instances of a client against N instances of a server with an arbitrarily defined connection matrix |
||||
* Execute heterogenous test configurations - for example: Java stress test clients against C++ servers or Node clients against Python servers or TSAN C++ clients vs ASAN C++ Servers etc. |
||||
* Easy and Flexible enough that Devs can use it to recreate complex test scenarios |
||||
|
||||
The implementation effort is divided into two parts: |
||||
|
||||
* Building a "Stress Test Framework" to run the stress test suites- More details in **Section II** (The idea is that the Stress Test framework is generic enough that it would be easier to modify it to run other suites like interop-tests or custom test scenarios) |
||||
* Building a 'Stress test suite' - More details in **section III** |
||||
|
||||
**Terminology:** |
||||
|
||||
GCE - Google compute engine |
||||
GKE - Google Container engine |
||||
Kubernetes - Google's open source service scheduler / orchestrator. |
||||
|
||||
**Note:** The terms GKE and Kubernetes are used interchangeably in this document |
||||
|
||||
# II. STRESS TEST FRAMEWORK |
||||
|
||||
(The details of each step are explained below)) |
||||
![image](images/stress_test_framework.png) |
||||
**Figure 1** |
||||
|
||||
### Step 1 Read the test config, generate base docker images |
||||
|
||||
**_Test Config:_** The test configuration contains the following information: |
||||
|
||||
* _GKE info:_ GKE project and cluster info |
||||
* _Docker images:_ Instructions to build docker images |
||||
* _Client templates:_ One or more client templates each containing the following information: |
||||
* Which docker image to use |
||||
* Path to the client program to launch (within the docker image) |
||||
* Parameters to the client program |
||||
* _Server templates:_ Similar to Client templates - except that these are for servers |
||||
* Test matrix containing the following: |
||||
* _Server groups:_ One or more groups of servers containing the following info for each group |
||||
* Which server template to use |
||||
* How many instances to launch |
||||
* _Client groups:_ One or more groups of clients containing the following (for each group): |
||||
* Which client template to use |
||||
* How many instances to launch |
||||
* Which server group to talk to (all clients in this group will talk to all servers in the server group) |
||||
|
||||
The first step is to read the test config and build the docker images |
||||
|
||||
**_Stress server docker image:_** The following are the main files in the server docker images |
||||
|
||||
* _Interop_server:_ The server program |
||||
* `run_server.py`: This is a python script which is the entry point of the docker image (i.e this is the script that is called when the docker image is run in GKE). This script launches the interop server and also updates the status in BigQuery. If the interop_server fails for whatever reason, the script launch_server.py logs that status in BigQuery |
||||
|
||||
**_Stress client docker image:_** |
||||
|
||||
* Stress client: The stress test client. In addition to talking to the interop_server, the stress client also exports metrics (which can be queried by the metrics_client described below) |
||||
* Metrics client: Metrics client connects to the stress_client to get the current qps metrics. |
||||
* `run_client.py`: This is a python script which is the entry point of the docker image (i.e this is the script that is called when the docker image is run in GKE). This script launches the stress client and also updates the status in BigQuery. The script then periodically launches metrics client to query the qps from the stress client and then uploads the qps to BigQuery. |
||||
|
||||
### Step 2) Upload the docker images to GKE |
||||
The docker images are uploaded to the GKE registry |
||||
|
||||
### Step 3) Launch the tests in GKE |
||||
The test driver reads the test matrix (described in step 1) and creates the necessary server and client pods in GKE. |
||||
|
||||
### Step 4) Tests are run in GKE |
||||
GKE starts running the tests by calling the entry points in *each* docker image (i.e `run_server.py` or `run_client.py` depending on whcih docker image it is) |
||||
|
||||
### Step 5) Upload the status to GKE and Monitor the status in GKE |
||||
* 5.1 The tests periodically update their status in BigQuery |
||||
* 5.2 The test driver periodically checks the status in Bigquery to see if any tests failed. If any tests failed, the driver immediately stops the tests. If not, the driver continues to run the tests for a configurable amount of time. |
||||
|
||||
### Step 6) Create a summary report |
||||
The test driver creates a final summary report containing details about any test failures and information about how to connect the failed pods in GKE for debugging. |
||||
|
@ -0,0 +1,4 @@ |
||||
The roots.pem file is periodically generated from: |
||||
https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt |
||||
using |
||||
https://github.com/agl/extract-nss-root-certs |
@ -1,186 +0,0 @@ |
||||
/*
|
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
// Generated by the gRPC protobuf plugin.
|
||||
// If you make any local change, they will be lost.
|
||||
// source: reflection.proto
|
||||
// Original file comments:
|
||||
// Copyright 2016, 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.
|
||||
//
|
||||
// Service exported by server reflection
|
||||
//
|
||||
#ifndef GRPC_reflection_2eproto__INCLUDED |
||||
#define GRPC_reflection_2eproto__INCLUDED |
||||
|
||||
#include <grpc++/ext/reflection.pb.h> |
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h> |
||||
#include <grpc++/impl/codegen/async_unary_call.h> |
||||
#include <grpc++/impl/codegen/method_handler_impl.h> |
||||
#include <grpc++/impl/codegen/proto_utils.h> |
||||
#include <grpc++/impl/codegen/rpc_method.h> |
||||
#include <grpc++/impl/codegen/service_type.h> |
||||
#include <grpc++/impl/codegen/status.h> |
||||
#include <grpc++/impl/codegen/stub_options.h> |
||||
#include <grpc++/impl/codegen/sync_stream.h> |
||||
|
||||
namespace grpc { |
||||
class CompletionQueue; |
||||
class Channel; |
||||
class RpcService; |
||||
class ServerCompletionQueue; |
||||
class ServerContext; |
||||
} // namespace grpc
|
||||
|
||||
namespace grpc { |
||||
namespace reflection { |
||||
namespace v1alpha { |
||||
|
||||
class ServerReflection GRPC_FINAL { |
||||
public: |
||||
class StubInterface { |
||||
public: |
||||
virtual ~StubInterface() {} |
||||
// The reflection service is structured as a bidirectional stream, ensuring
|
||||
// all related requests go to a single server.
|
||||
std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> ServerReflectionInfo(::grpc::ClientContext* context) { |
||||
return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(ServerReflectionInfoRaw(context)); |
||||
} |
||||
std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> AsyncServerReflectionInfo(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { |
||||
return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(AsyncServerReflectionInfoRaw(context, cq, tag)); |
||||
} |
||||
private: |
||||
virtual ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflectionInfoRaw(::grpc::ClientContext* context) = 0; |
||||
virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* AsyncServerReflectionInfoRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0; |
||||
}; |
||||
class Stub GRPC_FINAL : public StubInterface { |
||||
public: |
||||
Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel); |
||||
std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> ServerReflectionInfo(::grpc::ClientContext* context) { |
||||
return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(ServerReflectionInfoRaw(context)); |
||||
} |
||||
std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> AsyncServerReflectionInfo(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) { |
||||
return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(AsyncServerReflectionInfoRaw(context, cq, tag)); |
||||
} |
||||
|
||||
private: |
||||
std::shared_ptr< ::grpc::ChannelInterface> channel_; |
||||
::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflectionInfoRaw(::grpc::ClientContext* context) GRPC_OVERRIDE; |
||||
::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* AsyncServerReflectionInfoRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE; |
||||
const ::grpc::RpcMethod rpcmethod_ServerReflectionInfo_; |
||||
}; |
||||
static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions()); |
||||
|
||||
class Service : public ::grpc::Service { |
||||
public: |
||||
Service(); |
||||
virtual ~Service(); |
||||
// The reflection service is structured as a bidirectional stream, ensuring
|
||||
// all related requests go to a single server.
|
||||
virtual ::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream); |
||||
}; |
||||
template <class BaseClass> |
||||
class WithAsyncMethod_ServerReflectionInfo : public BaseClass { |
||||
private: |
||||
void BaseClassMustBeDerivedFromService(const Service *service) {} |
||||
public: |
||||
WithAsyncMethod_ServerReflectionInfo() { |
||||
::grpc::Service::MarkMethodAsync(0); |
||||
} |
||||
~WithAsyncMethod_ServerReflectionInfo() GRPC_OVERRIDE { |
||||
BaseClassMustBeDerivedFromService(this); |
||||
} |
||||
// disable synchronous version of this method
|
||||
::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream) GRPC_FINAL GRPC_OVERRIDE { |
||||
abort(); |
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); |
||||
} |
||||
void RequestServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { |
||||
::grpc::Service::RequestAsyncBidiStreaming(0, context, stream, new_call_cq, notification_cq, tag); |
||||
} |
||||
}; |
||||
typedef WithAsyncMethod_ServerReflectionInfo<Service > AsyncService; |
||||
template <class BaseClass> |
||||
class WithGenericMethod_ServerReflectionInfo : public BaseClass { |
||||
private: |
||||
void BaseClassMustBeDerivedFromService(const Service *service) {} |
||||
public: |
||||
WithGenericMethod_ServerReflectionInfo() { |
||||
::grpc::Service::MarkMethodGeneric(0); |
||||
} |
||||
~WithGenericMethod_ServerReflectionInfo() GRPC_OVERRIDE { |
||||
BaseClassMustBeDerivedFromService(this); |
||||
} |
||||
// disable synchronous version of this method
|
||||
::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream) GRPC_FINAL GRPC_OVERRIDE { |
||||
abort(); |
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); |
||||
} |
||||
}; |
||||
typedef Service StreamedUnaryService; |
||||
}; |
||||
|
||||
} // namespace v1alpha
|
||||
} // namespace reflection
|
||||
} // namespace grpc
|
||||
|
||||
|
||||
#endif // GRPC_reflection_2eproto__INCLUDED
|
File diff suppressed because it is too large
Load Diff
@ -1,105 +0,0 @@ |
||||
/*
|
||||
* |
||||
* 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 GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H |
||||
#define GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H |
||||
|
||||
#include <grpc/impl/codegen/sync.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
template <class mutex> |
||||
class lock_guard; |
||||
class condition_variable; |
||||
|
||||
class mutex { |
||||
public: |
||||
mutex() { gpr_mu_init(&mu_); } |
||||
~mutex() { gpr_mu_destroy(&mu_); } |
||||
|
||||
private: |
||||
::gpr_mu mu_; |
||||
template <class mutex> |
||||
friend class lock_guard; |
||||
friend class condition_variable; |
||||
}; |
||||
|
||||
template <class mutex> |
||||
class lock_guard { |
||||
public: |
||||
lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); } |
||||
~lock_guard() { unlock_internal(); } |
||||
|
||||
protected: |
||||
void lock_internal() { |
||||
if (!locked) gpr_mu_lock(&mu_.mu_); |
||||
locked = true; |
||||
} |
||||
void unlock_internal() { |
||||
if (locked) gpr_mu_unlock(&mu_.mu_); |
||||
locked = false; |
||||
} |
||||
|
||||
private: |
||||
mutex &mu_; |
||||
bool locked; |
||||
friend class condition_variable; |
||||
}; |
||||
|
||||
template <class mutex> |
||||
class unique_lock : public lock_guard<mutex> { |
||||
public: |
||||
unique_lock(mutex &mu) : lock_guard<mutex>(mu) {} |
||||
void lock() { this->lock_internal(); } |
||||
void unlock() { this->unlock_internal(); } |
||||
}; |
||||
|
||||
class condition_variable { |
||||
public: |
||||
condition_variable() { gpr_cv_init(&cv_); } |
||||
~condition_variable() { gpr_cv_destroy(&cv_); } |
||||
void wait(lock_guard<mutex> &mu) { |
||||
mu.locked = false; |
||||
gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future(GPR_CLOCK_REALTIME)); |
||||
mu.locked = true; |
||||
} |
||||
void notify_one() { gpr_cv_signal(&cv_); } |
||||
void notify_all() { gpr_cv_broadcast(&cv_); } |
||||
|
||||
private: |
||||
gpr_cv cv_; |
||||
}; |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H
|
@ -1,117 +0,0 @@ |
||||
/*
|
||||
* |
||||
* 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 GRPCXX_IMPL_THD_NO_CXX11_H |
||||
#define GRPCXX_IMPL_THD_NO_CXX11_H |
||||
|
||||
#include <grpc/support/thd.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
class thread { |
||||
public: |
||||
template <class T> |
||||
thread(void (T::*fptr)(), T *obj) { |
||||
func_ = new thread_function<T>(fptr, obj); |
||||
joined_ = false; |
||||
start(); |
||||
} |
||||
template <class T, class U> |
||||
thread(void (T::*fptr)(U arg), T *obj, U arg) { |
||||
func_ = new thread_function_arg<T, U>(fptr, obj, arg); |
||||
joined_ = false; |
||||
start(); |
||||
} |
||||
~thread() { |
||||
if (!joined_) std::terminate(); |
||||
delete func_; |
||||
} |
||||
thread(thread &&other) |
||||
: func_(other.func_), thd_(other.thd_), joined_(other.joined_) { |
||||
other.joined_ = true; |
||||
other.func_ = NULL; |
||||
} |
||||
void join() { |
||||
gpr_thd_join(thd_); |
||||
joined_ = true; |
||||
} |
||||
|
||||
private: |
||||
void start() { |
||||
gpr_thd_options options = gpr_thd_options_default(); |
||||
gpr_thd_options_set_joinable(&options); |
||||
gpr_thd_new(&thd_, thread_func, (void *)func_, &options); |
||||
} |
||||
static void thread_func(void *arg) { |
||||
thread_function_base *func = (thread_function_base *)arg; |
||||
func->call(); |
||||
} |
||||
class thread_function_base { |
||||
public: |
||||
virtual ~thread_function_base() {} |
||||
virtual void call() = 0; |
||||
}; |
||||
template <class T> |
||||
class thread_function : public thread_function_base { |
||||
public: |
||||
thread_function(void (T::*fptr)(), T *obj) : fptr_(fptr), obj_(obj) {} |
||||
virtual void call() { (obj_->*fptr_)(); } |
||||
|
||||
private: |
||||
void (T::*fptr_)(); |
||||
T *obj_; |
||||
}; |
||||
template <class T, class U> |
||||
class thread_function_arg : public thread_function_base { |
||||
public: |
||||
thread_function_arg(void (T::*fptr)(U arg), T *obj, U arg) |
||||
: fptr_(fptr), obj_(obj), arg_(arg) {} |
||||
virtual void call() { (obj_->*fptr_)(arg_); } |
||||
|
||||
private: |
||||
void (T::*fptr_)(U arg); |
||||
T *obj_; |
||||
U arg_; |
||||
}; |
||||
thread_function_base *func_; |
||||
gpr_thd_id thd_; |
||||
bool joined_; |
||||
|
||||
// Disallow copy and assign.
|
||||
thread(const thread &); |
||||
void operator=(const thread &); |
||||
}; |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_IMPL_THD_NO_CXX11_H
|
@ -0,0 +1,70 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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 GRPCXX_RESOURCE_QUOTA_H |
||||
#define GRPCXX_RESOURCE_QUOTA_H |
||||
|
||||
struct grpc_resource_quota; |
||||
|
||||
#include <grpc++/impl/codegen/config.h> |
||||
|
||||
namespace grpc { |
||||
|
||||
/// ResourceQuota represents a bound on memory usage by the gRPC library.
|
||||
/// A ResourceQuota can be attached to a server (via ServerBuilder), or a client
|
||||
/// channel (via ChannelArguments). gRPC will attempt to keep memory used by
|
||||
/// all attached entities below the ResourceQuota bound.
|
||||
class ResourceQuota final { |
||||
public: |
||||
explicit ResourceQuota(const grpc::string& name); |
||||
ResourceQuota(); |
||||
~ResourceQuota(); |
||||
|
||||
/// Resize this ResourceQuota to a new size. If new_size is smaller than the
|
||||
/// current size of the pool, memory usage will be monotonically decreased
|
||||
/// until it falls under new_size. No time bound is given for this to occur
|
||||
/// however.
|
||||
ResourceQuota& Resize(size_t new_size); |
||||
|
||||
grpc_resource_quota* c_resource_quota() const { return impl_; } |
||||
|
||||
private: |
||||
ResourceQuota(const ResourceQuota& rhs); |
||||
ResourceQuota& operator=(const ResourceQuota& rhs); |
||||
|
||||
grpc_resource_quota* const impl_; |
||||
}; |
||||
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_RESOURCE_QUOTA_H
|
@ -0,0 +1,67 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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 GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H |
||||
#define GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H |
||||
|
||||
#include <map> |
||||
|
||||
#include <grpc++/server_context.h> |
||||
|
||||
namespace grpc { |
||||
namespace testing { |
||||
|
||||
// A test-only class to access private members and methods of ServerContext.
|
||||
class ServerContextTestSpouse { |
||||
public: |
||||
explicit ServerContextTestSpouse(ServerContext* ctx) : ctx_(ctx) {} |
||||
|
||||
// Inject client metadata to the ServerContext for the test. The test spouse
|
||||
// must be alive when ServerContext::client_metadata is called.
|
||||
void AddClientMetadata(const grpc::string& key, const grpc::string& value); |
||||
std::multimap<grpc::string, grpc::string> GetInitialMetadata() const { |
||||
return ctx_->initial_metadata_; |
||||
} |
||||
std::multimap<grpc::string, grpc::string> GetTrailingMetadata() const { |
||||
return ctx_->trailing_metadata_; |
||||
} |
||||
|
||||
private: |
||||
ServerContext* ctx_; // not owned
|
||||
std::multimap<grpc::string, grpc::string> client_metadata_storage_; |
||||
}; |
||||
|
||||
} // namespace testing
|
||||
} // namespace grpc
|
||||
|
||||
#endif // GRPCXX_TEST_SERVER_CONTEXT_TEST_SPOUSE_H
|
@ -1,122 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015-2016, 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_IMPL_CODEGEN_BYTE_BUFFER_H |
||||
#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H |
||||
|
||||
#include <grpc/impl/codegen/compression_types.h> |
||||
#include <grpc/impl/codegen/slice_buffer.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
typedef enum { |
||||
GRPC_BB_RAW |
||||
/* Future types may include GRPC_BB_PROTOBUF, etc. */ |
||||
} grpc_byte_buffer_type; |
||||
|
||||
struct grpc_byte_buffer { |
||||
void *reserved; |
||||
grpc_byte_buffer_type type; |
||||
union { |
||||
struct { |
||||
void *reserved[8]; |
||||
} reserved; |
||||
struct { |
||||
grpc_compression_algorithm compression; |
||||
gpr_slice_buffer slice_buffer; |
||||
} raw; |
||||
} data; |
||||
}; |
||||
typedef struct grpc_byte_buffer grpc_byte_buffer; |
||||
|
||||
/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
|
||||
* |
||||
* Increases the reference count for all \a slices processed. The user is |
||||
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, |
||||
size_t nslices); |
||||
|
||||
/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
|
||||
* \a nslices). The \a compression argument defines the compression algorithm |
||||
* used to generate the data in \a slices. |
||||
* |
||||
* Increases the reference count for all \a slices processed. The user is |
||||
* responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create( |
||||
gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression); |
||||
|
||||
/** Copies input byte buffer \a bb.
|
||||
* |
||||
* Increases the reference count of all the source slices. The user is |
||||
* responsible for calling grpc_byte_buffer_destroy over the returned copy. */ |
||||
GRPCAPI grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb); |
||||
|
||||
/** Returns the size of the given byte buffer, in bytes. */ |
||||
GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer *bb); |
||||
|
||||
/** Destroys \a byte_buffer deallocating all its memory. */ |
||||
GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer); |
||||
|
||||
/** Reader for byte buffers. Iterates over slices in the byte buffer */ |
||||
struct grpc_byte_buffer_reader; |
||||
typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader; |
||||
|
||||
/** Initialize \a reader to read over \a buffer.
|
||||
* Returns 1 upon success, 0 otherwise. */ |
||||
GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, |
||||
grpc_byte_buffer *buffer); |
||||
|
||||
/** Cleanup and destroy \a reader */ |
||||
GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader); |
||||
|
||||
/** Updates \a slice with the next piece of data from from \a reader and returns
|
||||
* 1. Returns 0 at the end of the stream. Caller is responsible for calling |
||||
* gpr_slice_unref on the result. */ |
||||
GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, |
||||
gpr_slice *slice); |
||||
|
||||
/** Merge all data from \a reader into single slice */ |
||||
GRPCAPI gpr_slice |
||||
grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader); |
||||
|
||||
/** Returns a RAW byte buffer instance from the output of \a reader. */ |
||||
GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_from_reader( |
||||
grpc_byte_buffer_reader *reader); |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_H */ |
@ -0,0 +1,140 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016, 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_IMPL_CODEGEN_GPR_TYPES_H |
||||
#define GRPC_IMPL_CODEGEN_GPR_TYPES_H |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#include <stddef.h> |
||||
#include <stdint.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* The clocks we support. */ |
||||
typedef enum { |
||||
/* Monotonic clock. Epoch undefined. Always moves forwards. */ |
||||
GPR_CLOCK_MONOTONIC = 0, |
||||
/* Realtime clock. May jump forwards or backwards. Settable by
|
||||
the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */ |
||||
GPR_CLOCK_REALTIME, |
||||
/* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
|
||||
undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */ |
||||
GPR_CLOCK_PRECISE, |
||||
/* Unmeasurable clock type: no base, created by taking the difference
|
||||
between two times */ |
||||
GPR_TIMESPAN |
||||
} gpr_clock_type; |
||||
|
||||
/* Analogous to struct timespec. On some machines, absolute times may be in
|
||||
* local time. */ |
||||
typedef struct gpr_timespec { |
||||
int64_t tv_sec; |
||||
int32_t tv_nsec; |
||||
/** Against which clock was this time measured? (or GPR_TIMESPAN if
|
||||
this is a relative time meaure) */ |
||||
gpr_clock_type clock_type; |
||||
} gpr_timespec; |
||||
|
||||
/* Slice API
|
||||
|
||||
A slice represents a contiguous reference counted array of bytes. |
||||
It is cheap to take references to a slice, and it is cheap to create a |
||||
slice pointing to a subset of another slice. |
||||
|
||||
The data-structure for slices is exposed here to allow non-gpr code to |
||||
build slices from whatever data they have available. |
||||
|
||||
When defining interfaces that handle slices, care should be taken to define |
||||
reference ownership semantics (who should call unref?) and mutability |
||||
constraints (is the callee allowed to modify the slice?) */ |
||||
|
||||
/* Reference count container for gpr_slice. Contains function pointers to
|
||||
increment and decrement reference counts. Implementations should cleanup |
||||
when the reference count drops to zero. |
||||
Typically client code should not touch this, and use gpr_slice_malloc, |
||||
gpr_slice_new, or gpr_slice_new_with_len instead. */ |
||||
typedef struct gpr_slice_refcount { |
||||
void (*ref)(void *); |
||||
void (*unref)(void *); |
||||
} gpr_slice_refcount; |
||||
|
||||
#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1) |
||||
|
||||
/* A gpr_slice s, if initialized, represents the byte range
|
||||
s.bytes[0..s.length-1]. |
||||
|
||||
It can have an associated ref count which has a destruction routine to be run |
||||
when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()). |
||||
Multiple gpr_slice values may share a ref count. |
||||
|
||||
If the slice does not have a refcount, it represents an inlined small piece |
||||
of data that is copied by value. */ |
||||
typedef struct gpr_slice { |
||||
struct gpr_slice_refcount *refcount; |
||||
union { |
||||
struct { |
||||
uint8_t *bytes; |
||||
size_t length; |
||||
} refcounted; |
||||
struct { |
||||
uint8_t length; |
||||
uint8_t bytes[GPR_SLICE_INLINED_SIZE]; |
||||
} inlined; |
||||
} data; |
||||
} gpr_slice; |
||||
|
||||
#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8 |
||||
|
||||
/* Represents an expandable array of slices, to be interpreted as a
|
||||
single item. */ |
||||
typedef struct { |
||||
/* slices in the array */ |
||||
gpr_slice *slices; |
||||
/* the number of slices in the array */ |
||||
size_t count; |
||||
/* the number of slices allocated in the array */ |
||||
size_t capacity; |
||||
/* the combined length of all slices in the array */ |
||||
size_t length; |
||||
/* inlined elements to avoid allocations */ |
||||
gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS]; |
||||
} gpr_slice_buffer; |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_GPR_TYPES_H */ |
@ -1,118 +0,0 @@ |
||||
/*
|
||||
* |
||||
* 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_IMPL_CODEGEN_LOG_H |
||||
#define GRPC_IMPL_CODEGEN_LOG_H |
||||
|
||||
#include <inttypes.h> |
||||
#include <stdarg.h> |
||||
#include <stdlib.h> /* for abort() */ |
||||
|
||||
#include <grpc/impl/codegen/port_platform.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* GPR log API.
|
||||
|
||||
Usage (within grpc): |
||||
|
||||
int argument1 = 3; |
||||
char* argument2 = "hello"; |
||||
gpr_log(GPR_DEBUG, "format string %d", argument1); |
||||
gpr_log(GPR_INFO, "hello world"); |
||||
gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */ |
||||
|
||||
/* The severity of a log message - use the #defines below when calling into
|
||||
gpr_log to additionally supply file and line data */ |
||||
typedef enum gpr_log_severity { |
||||
GPR_LOG_SEVERITY_DEBUG, |
||||
GPR_LOG_SEVERITY_INFO, |
||||
GPR_LOG_SEVERITY_ERROR |
||||
} gpr_log_severity; |
||||
|
||||
#define GPR_LOG_VERBOSITY_UNSET -1 |
||||
|
||||
/* Returns a string representation of the log severity */ |
||||
const char *gpr_log_severity_string(gpr_log_severity severity); |
||||
|
||||
/* Macros to build log contexts at various severity levels */ |
||||
#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG |
||||
#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO |
||||
#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR |
||||
|
||||
/* Log a message. It's advised to use GPR_xxx above to generate the context
|
||||
* for each message */ |
||||
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, |
||||
const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5); |
||||
|
||||
GPRAPI void gpr_log_message(const char *file, int line, |
||||
gpr_log_severity severity, const char *message); |
||||
|
||||
/* Set global log verbosity */ |
||||
GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print); |
||||
|
||||
GPRAPI void gpr_log_verbosity_init(); |
||||
|
||||
/* Log overrides: applications can use this API to intercept logging calls
|
||||
and use their own implementations */ |
||||
|
||||
typedef struct { |
||||
const char *file; |
||||
int line; |
||||
gpr_log_severity severity; |
||||
const char *message; |
||||
} gpr_log_func_args; |
||||
|
||||
typedef void (*gpr_log_func)(gpr_log_func_args *args); |
||||
GPRAPI void gpr_set_log_function(gpr_log_func func); |
||||
|
||||
/* abort() the process if x is zero, having written a line to the log.
|
||||
|
||||
Intended for internal invariants. If the error can be recovered from, |
||||
without the possibility of corruption, or might best be reflected via |
||||
an exception in a higher-level language, consider returning error code. */ |
||||
#define GPR_ASSERT(x) \ |
||||
do { \
|
||||
if (!(x)) { \
|
||||
gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0) |
||||
|
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_IMPL_CODEGEN_LOG_H */ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue