|
|
@ -35,6 +35,7 @@ |
|
|
|
#define GRPCXX_IMPL_CALL_H |
|
|
|
#define GRPCXX_IMPL_CALL_H |
|
|
|
|
|
|
|
|
|
|
|
#include <grpc/grpc.h> |
|
|
|
#include <grpc/grpc.h> |
|
|
|
|
|
|
|
#include <grpc++/client_context.h> |
|
|
|
#include <grpc++/completion_queue.h> |
|
|
|
#include <grpc++/completion_queue.h> |
|
|
|
#include <grpc++/config.h> |
|
|
|
#include <grpc++/config.h> |
|
|
|
#include <grpc++/status.h> |
|
|
|
#include <grpc++/status.h> |
|
|
@ -51,6 +52,10 @@ namespace grpc { |
|
|
|
class ByteBuffer; |
|
|
|
class ByteBuffer; |
|
|
|
class Call; |
|
|
|
class Call; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FillMetadataMap(grpc_metadata_array* arr, |
|
|
|
|
|
|
|
std::multimap<grpc::string, grpc::string>* metadata); |
|
|
|
|
|
|
|
grpc_metadata* FillMetadataArray(const std::multimap<grpc::string, grpc::string>& metadata); |
|
|
|
|
|
|
|
|
|
|
|
class CallNoOp { |
|
|
|
class CallNoOp { |
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) {} |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) {} |
|
|
@ -59,11 +64,29 @@ class CallNoOp { |
|
|
|
|
|
|
|
|
|
|
|
class CallOpSendInitialMetadata { |
|
|
|
class CallOpSendInitialMetadata { |
|
|
|
public: |
|
|
|
public: |
|
|
|
void SendInitialMetadata(const std::multimap<grpc::string, grpc::string>& metadata); |
|
|
|
CallOpSendInitialMetadata() : send_(false) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SendInitialMetadata(const std::multimap<grpc::string, grpc::string>& metadata) { |
|
|
|
|
|
|
|
send_ = true; |
|
|
|
|
|
|
|
initial_metadata_count_ = metadata.size(); |
|
|
|
|
|
|
|
initial_metadata_ = FillMetadataArray(metadata); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
if (!send_) return; |
|
|
|
|
|
|
|
grpc_op* op = &ops[(*nops)++]; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_INITIAL_METADATA; |
|
|
|
|
|
|
|
op->data.send_initial_metadata.count = initial_metadata_count_; |
|
|
|
|
|
|
|
op->data.send_initial_metadata.metadata = initial_metadata_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
// nothing to do
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool send_; |
|
|
|
|
|
|
|
size_t initial_metadata_count_; |
|
|
|
|
|
|
|
grpc_metadata* initial_metadata_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpSendMessage { |
|
|
|
class CallOpSendMessage { |
|
|
@ -71,7 +94,7 @@ class CallOpSendMessage { |
|
|
|
CallOpSendMessage() : send_buf_(nullptr) {} |
|
|
|
CallOpSendMessage() : send_buf_(nullptr) {} |
|
|
|
|
|
|
|
|
|
|
|
template <class M> |
|
|
|
template <class M> |
|
|
|
bool SendMessage(const M& message) { |
|
|
|
bool SendMessage(const M& message) GRPC_MUST_USE_RESULT { |
|
|
|
return SerializationTraits<M>::Serialize(message, &send_buf_); |
|
|
|
return SerializationTraits<M>::Serialize(message, &send_buf_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -132,50 +155,167 @@ class CallOpRecvMessage { |
|
|
|
|
|
|
|
|
|
|
|
class CallOpGenericRecvMessage { |
|
|
|
class CallOpGenericRecvMessage { |
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
CallOpGenericRecvMessage() : got_message(false) {} |
|
|
|
|
|
|
|
|
|
|
|
template <class R> |
|
|
|
template <class R> |
|
|
|
void RecvMessage(R* message); |
|
|
|
void RecvMessage(R* message) { |
|
|
|
|
|
|
|
deserialize_ = [message](grpc_byte_buffer* buf, int max_message_size) -> Status { |
|
|
|
|
|
|
|
return SerializationTraits<R>::Deserialize(buf, message, max_message_size); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool got_message; |
|
|
|
bool got_message; |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
if (!deserialize_) return; |
|
|
|
|
|
|
|
grpc_op *op = &ops[(*nops)++]; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_MESSAGE; |
|
|
|
|
|
|
|
op->data.recv_message = &recv_buf_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
if (!deserialize_) return; |
|
|
|
|
|
|
|
if (recv_buf_) { |
|
|
|
|
|
|
|
if (*status) { |
|
|
|
|
|
|
|
got_message = true; |
|
|
|
|
|
|
|
*status = deserialize_(recv_buf_, max_message_size).IsOk(); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
got_message = false; |
|
|
|
|
|
|
|
grpc_byte_buffer_destroy(recv_buf_); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
got_message = false; |
|
|
|
|
|
|
|
*status = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::function<Status(grpc_byte_buffer*, int)> deserialize_; |
|
|
|
|
|
|
|
grpc_byte_buffer* recv_buf_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpClientSendClose { |
|
|
|
class CallOpClientSendClose { |
|
|
|
public: |
|
|
|
public: |
|
|
|
void ClientSendClose(); |
|
|
|
CallOpClientSendClose() : send_(false) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientSendClose() { send_ = true; } |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
if (!send_) return; |
|
|
|
|
|
|
|
ops[(*nops)++].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
// nothing to do
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
bool send_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpServerSendStatus { |
|
|
|
class CallOpServerSendStatus { |
|
|
|
public: |
|
|
|
public: |
|
|
|
void ServerSendStatus(const std::multimap<grpc::string, grpc::string>& trailing_metadata, const Status& status); |
|
|
|
CallOpServerSendStatus() : send_status_available_(false) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ServerSendStatus(const std::multimap<grpc::string, grpc::string>& trailing_metadata, const Status& status){ |
|
|
|
|
|
|
|
trailing_metadata_count_ = trailing_metadata.size(); |
|
|
|
|
|
|
|
trailing_metadata_ = FillMetadataArray(trailing_metadata); |
|
|
|
|
|
|
|
send_status_available_ = true; |
|
|
|
|
|
|
|
send_status_code_ = static_cast<grpc_status_code>(status.code()); |
|
|
|
|
|
|
|
send_status_details_ = status.details(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
grpc_op* op = &ops[(*nops)++]; |
|
|
|
|
|
|
|
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; |
|
|
|
|
|
|
|
op->data.send_status_from_server.trailing_metadata_count = |
|
|
|
|
|
|
|
trailing_metadata_count_; |
|
|
|
|
|
|
|
op->data.send_status_from_server.trailing_metadata = |
|
|
|
|
|
|
|
trailing_metadata_; |
|
|
|
|
|
|
|
op->data.send_status_from_server.status = send_status_code_; |
|
|
|
|
|
|
|
op->data.send_status_from_server.status_details = |
|
|
|
|
|
|
|
send_status_details_.empty() ? nullptr : send_status_details_.c_str(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
// nothing to do
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
bool send_status_available_; |
|
|
|
|
|
|
|
grpc_status_code send_status_code_; |
|
|
|
|
|
|
|
grpc::string send_status_details_; |
|
|
|
|
|
|
|
size_t trailing_metadata_count_; |
|
|
|
|
|
|
|
grpc_metadata* trailing_metadata_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpRecvInitialMetadata { |
|
|
|
class CallOpRecvInitialMetadata { |
|
|
|
public: |
|
|
|
public: |
|
|
|
void RecvInitialMetadata(ClientContext* context); |
|
|
|
CallOpRecvInitialMetadata() : recv_initial_metadata_(nullptr) { |
|
|
|
|
|
|
|
memset(&recv_initial_metadata_arr_, 0, sizeof(recv_initial_metadata_arr_)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void RecvInitialMetadata(ClientContext* context) { |
|
|
|
|
|
|
|
context->initial_metadata_received_ = true; |
|
|
|
|
|
|
|
recv_initial_metadata_ = &context->recv_initial_metadata_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
if (!recv_initial_metadata_) return; |
|
|
|
|
|
|
|
grpc_op* op = &ops[(*nops)++]; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_INITIAL_METADATA; |
|
|
|
|
|
|
|
op->data.recv_initial_metadata = &recv_initial_metadata_arr_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::multimap<grpc::string, grpc::string>* recv_initial_metadata_; |
|
|
|
|
|
|
|
grpc_metadata_array recv_initial_metadata_arr_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpClientRecvStatus { |
|
|
|
class CallOpClientRecvStatus { |
|
|
|
public: |
|
|
|
public: |
|
|
|
void ClientRecvStatus(ClientContext* context, Status* status); |
|
|
|
CallOpClientRecvStatus() { |
|
|
|
|
|
|
|
memset(this, 0, sizeof(*this)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ClientRecvStatus(ClientContext* context, Status* status) { |
|
|
|
|
|
|
|
recv_trailing_metadata_ = &context->trailing_metadata_; |
|
|
|
|
|
|
|
recv_status_ = status; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
protected: |
|
|
|
void AddOp(grpc_op* ops, size_t* nops); |
|
|
|
void AddOp(grpc_op* ops, size_t* nops) { |
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size); |
|
|
|
if (recv_status_ == nullptr) return; |
|
|
|
|
|
|
|
grpc_op* op = &ops[(*nops)++]; |
|
|
|
|
|
|
|
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.trailing_metadata = |
|
|
|
|
|
|
|
&recv_trailing_metadata_arr_; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.status = &status_code_; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.status_details = &status_details_; |
|
|
|
|
|
|
|
op->data.recv_status_on_client.status_details_capacity = |
|
|
|
|
|
|
|
&status_details_capacity_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FinishOp(void* tag, bool* status, int max_message_size) { |
|
|
|
|
|
|
|
FillMetadataMap(&recv_trailing_metadata_arr_, recv_trailing_metadata_); |
|
|
|
|
|
|
|
*recv_status_ = Status( |
|
|
|
|
|
|
|
static_cast<StatusCode>(status_code_), |
|
|
|
|
|
|
|
status_details_ ? grpc::string(status_details_) : grpc::string()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::multimap<grpc::string, grpc::string>* recv_trailing_metadata_; |
|
|
|
|
|
|
|
Status* recv_status_; |
|
|
|
|
|
|
|
grpc_metadata_array recv_trailing_metadata_arr_; |
|
|
|
|
|
|
|
grpc_status_code status_code_; |
|
|
|
|
|
|
|
char* status_details_; |
|
|
|
|
|
|
|
size_t status_details_capacity_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class CallOpSetInterface : public CompletionQueueTag { |
|
|
|
class CallOpSetInterface : public CompletionQueueTag { |
|
|
|