aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Tim Emiola <tbetbetbe@users.noreply.github.com>2015-03-24 13:57:06 -0700
committerGravatar Tim Emiola <tbetbetbe@users.noreply.github.com>2015-03-24 13:57:06 -0700
commitdad14be4eb359326a11253196f035c8f36fbdc86 (patch)
tree83bc9c19023e82535724e472e2f7f856e76fd105
parente6c108e9cb50f902f9a645772065f75ede91f95d (diff)
parent9c4425a4d5302f567075ca08a18c7bfbcfde6458 (diff)
Merge pull request #1014 from murgatroid99/php_new_core_api
Update PHP to the new batch API
-rw-r--r--src/php/ext/grpc/call.c531
-rw-r--r--src/php/ext/grpc/call.h17
-rw-r--r--src/php/ext/grpc/channel.c23
-rw-r--r--src/php/ext/grpc/completion_queue.c170
-rwxr-xr-xsrc/php/ext/grpc/completion_queue.h62
-rwxr-xr-xsrc/php/ext/grpc/config.m42
-rw-r--r--src/php/ext/grpc/event.c150
-rwxr-xr-xsrc/php/ext/grpc/event.h51
-rw-r--r--src/php/ext/grpc/php_grpc.c36
-rw-r--r--src/php/ext/grpc/server.c76
-rwxr-xr-xsrc/php/ext/grpc/server.h1
-rwxr-xr-xsrc/php/lib/Grpc/ActiveCall.php31
-rwxr-xr-xsrc/php/tests/unit_tests/CallTest.php62
-rwxr-xr-xsrc/php/tests/unit_tests/CompletionQueueTest.php46
-rwxr-xr-xsrc/php/tests/unit_tests/EndToEndTest.php186
-rwxr-xr-xsrc/php/tests/unit_tests/SecureEndToEndTest.php197
16 files changed, 557 insertions, 1084 deletions
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 798747109a..d0e324e2cc 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -49,11 +49,11 @@
#include <stdbool.h>
#include "grpc/support/log.h"
+#include "grpc/support/alloc.h"
#include "grpc/grpc.h"
#include "timeval.h"
#include "channel.h"
-#include "completion_queue.h"
#include "byte_buffer.h"
zend_class_entry *grpc_ce_call;
@@ -61,7 +61,19 @@ zend_class_entry *grpc_ce_call;
/* Frees and destroys an instance of wrapped_grpc_call */
void free_wrapped_grpc_call(void *object TSRMLS_DC) {
wrapped_grpc_call *call = (wrapped_grpc_call *)object;
+ grpc_event *event;
if (call->owned && call->wrapped != NULL) {
+ if (call->queue != NULL) {
+ grpc_completion_queue_shutdown(call->queue);
+ event = grpc_completion_queue_next(call->queue, gpr_inf_future);
+ while (event != NULL) {
+ if (event->type == GRPC_QUEUE_SHUTDOWN) {
+ break;
+ }
+ event = grpc_completion_queue_next(call->queue, gpr_inf_future);
+ }
+ grpc_completion_queue_destroy(call->queue);
+ }
grpc_call_destroy(call->wrapped);
}
efree(call);
@@ -88,17 +100,23 @@ zend_object_value create_wrapped_grpc_call(zend_class_entry *class_type
/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the struct
should be destroyed at the end of the object's lifecycle */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned) {
+zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue,
+ bool owned) {
zval *call_object;
MAKE_STD_ZVAL(call_object);
object_init_ex(call_object, grpc_ce_call);
wrapped_grpc_call *call =
(wrapped_grpc_call *)zend_object_store_get_object(call_object TSRMLS_CC);
call->wrapped = wrapped;
+ call->queue = queue;
return call_object;
}
-zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) {
+/* Creates and returns a PHP array object with the data in a
+ * grpc_metadata_array. Returns NULL on failure */
+zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array) {
+ int count = metadata_array->count;
+ grpc_metadata *elements = metadata_array->metadata;
int i;
zval *array;
zval **data = NULL;
@@ -139,6 +157,64 @@ zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) {
return array;
}
+/* Populates a grpc_metadata_array with the data in a PHP array object.
+ Returns true on success and false on failure */
+bool create_metadata_array(zval *array, grpc_metadata_array *metadata) {
+ zval **inner_array;
+ zval **value;
+ HashTable *array_hash;
+ HashPosition array_pointer;
+ HashTable *inner_array_hash;
+ HashPosition inner_array_pointer;
+ char *key;
+ uint key_len;
+ ulong index;
+ if (Z_TYPE_P(array) != IS_ARRAY) {
+ return false;
+ }
+ grpc_metadata_array_init(metadata);
+ array_hash = Z_ARRVAL_P(array);
+ for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
+ zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ &array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(array_hash, &array_pointer)) {
+ if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
+ &array_pointer) != HASH_KEY_IS_STRING) {
+ return false;
+ }
+ if (Z_TYPE_P(*inner_array) != IS_ARRAY) {
+ return false;
+ }
+ inner_array_hash = Z_ARRVAL_P(*inner_array);
+ metadata->capacity += zend_hash_num_elements(inner_array_hash);
+ }
+ metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata));
+ for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
+ zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ &array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(array_hash, &array_pointer)) {
+ if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
+ &array_pointer) != HASH_KEY_IS_STRING) {
+ return false;
+ }
+ inner_array_hash = Z_ARRVAL_P(*inner_array);
+ for (zend_hash_internal_pointer_reset_ex(inner_array_hash,
+ &inner_array_pointer);
+ zend_hash_get_current_data_ex(inner_array_hash, (void**)&value,
+ &inner_array_pointer) == SUCCESS;
+ zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) {
+ if (Z_TYPE_P(*value) != IS_STRING) {
+ return false;
+ }
+ metadata->metadata[metadata->count].key = key;
+ metadata->metadata[metadata->count].value = Z_STRVAL_P(*value);
+ metadata->metadata[metadata->count].value_length = Z_STRLEN_P(*value);
+ metadata->count += 1;
+ }
+ }
+ return true;
+}
+
/**
* Constructs a new instance of the Call class.
* @param Channel $channel The channel to associate the call with. Must not be
@@ -157,9 +233,10 @@ PHP_METHOD(Call, __construct) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO", &channel_obj,
grpc_ce_channel, &method, &method_len,
&deadline_obj, grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "Call expects a Channel, a String, and a Timeval",
- 1 TSRMLS_CC);
+ zend_throw_exception(
+ spl_ce_InvalidArgumentException,
+ "Call expects a Channel, a String, and a Timeval",
+ 1 TSRMLS_CC);
return;
}
wrapped_grpc_channel *channel =
@@ -175,289 +252,235 @@ PHP_METHOD(Call, __construct) {
wrapped_grpc_timeval *deadline =
(wrapped_grpc_timeval *)zend_object_store_get_object(
deadline_obj TSRMLS_CC);
- call->wrapped = grpc_channel_create_call_old(
- channel->wrapped, method, channel->target, deadline->wrapped);
+ call->queue = grpc_completion_queue_create();
+ call->wrapped = grpc_channel_create_call(
+ channel->wrapped, call->queue, method, channel->target,
+ deadline->wrapped);
}
/**
- * Add metadata to the call. All array keys must be strings. If the value is a
- * string, it is added as a key/value pair. If it is an array, each value is
- * added paired with the same string
- * @param array $metadata The metadata to add
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
+ * Start a batch of RPC actions.
+ * @param array batch Array of actions to take
+ * @return object Object with results of all actions
*/
-PHP_METHOD(Call, add_metadata) {
+PHP_METHOD(Call, start_batch) {
wrapped_grpc_call *call =
(wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- grpc_metadata metadata;
- grpc_call_error error_code;
+ grpc_op ops[8];
+ size_t op_num = 0;
zval *array;
- zval **inner_array;
zval **value;
+ zval **inner_value;
HashTable *array_hash;
HashPosition array_pointer;
- HashTable *inner_array_hash;
- HashPosition inner_array_pointer;
+ HashTable *status_hash;
char *key;
uint key_len;
ulong index;
- long flags = 0;
- /* "a|l" == 1 array, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &flags) ==
+ grpc_metadata_array metadata;
+ grpc_metadata_array trailing_metadata;
+ grpc_metadata_array recv_metadata;
+ grpc_metadata_array recv_trailing_metadata;
+ grpc_status_code status;
+ char *status_details = NULL;
+ size_t status_details_capacity = 0;
+ grpc_byte_buffer *message;
+ int cancelled;
+ grpc_call_error error;
+ grpc_event *event;
+ zval *result;
+ char *message_str;
+ size_t message_len;
+ zval *recv_status;
+ grpc_metadata_array_init(&metadata);
+ grpc_metadata_array_init(&trailing_metadata);
+ grpc_metadata_array_init(&recv_metadata);
+ grpc_metadata_array_init(&recv_trailing_metadata);
+ MAKE_STD_ZVAL(result);
+ object_init(result);
+ /* "a" == 1 array */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) ==
FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "add_metadata expects an array and an optional long",
- 1 TSRMLS_CC);
- return;
+ "start_batch expects an array", 1 TSRMLS_CC);
+ goto cleanup;
}
array_hash = Z_ARRVAL_P(array);
for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer);
- zend_hash_get_current_data_ex(array_hash, (void**)&inner_array,
+ zend_hash_get_current_data_ex(array_hash, (void**)&value,
&array_pointer) == SUCCESS;
zend_hash_move_forward_ex(array_hash, &array_pointer)) {
if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0,
- &array_pointer) != HASH_KEY_IS_STRING) {
+ &array_pointer) != HASH_KEY_IS_LONG) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata keys must be strings", 1 TSRMLS_CC);
- return;
+ "batch keys must be integers", 1 TSRMLS_CC);
+ goto cleanup;
}
- if (Z_TYPE_P(*inner_array) != IS_ARRAY) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata values must be arrays",
- 1 TSRMLS_CC);
- return;
- }
- inner_array_hash = Z_ARRVAL_P(*inner_array);
- for (zend_hash_internal_pointer_reset_ex(inner_array_hash,
- &inner_array_pointer);
- zend_hash_get_current_data_ex(inner_array_hash, (void**)&value,
- &inner_array_pointer) == SUCCESS;
- zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) {
- if (Z_TYPE_P(*value) != IS_STRING) {
+ switch(index) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ if (!create_metadata_array(*value, &metadata)) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Bad metadata value given", 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_initial_metadata.count =
+ metadata.count;
+ ops[op_num].data.send_initial_metadata.metadata =
+ metadata.metadata;
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ if (Z_TYPE_PP(value) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Expected a string for send message",
+ 1 TSRMLS_CC);
+ }
+ ops[op_num].data.send_message =
+ string_to_byte_buffer(Z_STRVAL_PP(value), Z_STRLEN_PP(value));
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ status_hash = Z_ARRVAL_PP(value);
+ if (zend_hash_find(status_hash, "metadata", sizeof("metadata"),
+ (void **)&inner_value) == SUCCESS) {
+ if (!create_metadata_array(*inner_value, &trailing_metadata)) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Bad trailing metadata value given",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.trailing_metadata =
+ trailing_metadata.metadata;
+ ops[op_num].data.send_status_from_server.trailing_metadata_count =
+ trailing_metadata.count;
+ }
+ if (zend_hash_find(status_hash, "code", sizeof("code"),
+ (void**)&inner_value) == SUCCESS) {
+ if (Z_TYPE_PP(inner_value) != IS_LONG) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Status code must be an integer",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.status =
+ Z_LVAL_PP(inner_value);
+ } else {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Integer status code is required",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ if (zend_hash_find(status_hash, "details", sizeof("details"),
+ (void**)&inner_value) == SUCCESS) {
+ if (Z_TYPE_PP(inner_value) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "Status details must be a string",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ ops[op_num].data.send_status_from_server.status_details =
+ Z_STRVAL_PP(inner_value);
+ } else {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ "String status details is required",
+ 1 TSRMLS_CC);
+ goto cleanup;
+ }
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ ops[op_num].data.recv_initial_metadata = &recv_metadata;
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ ops[op_num].data.recv_message = &message;
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ ops[op_num].data.recv_status_on_client.trailing_metadata =
+ &recv_trailing_metadata;
+ ops[op_num].data.recv_status_on_client.status = &status;
+ ops[op_num].data.recv_status_on_client.status_details =
+ &status_details;
+ ops[op_num].data.recv_status_on_client.status_details_capacity =
+ &status_details_capacity;
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ ops[op_num].data.recv_close_on_server.cancelled = &cancelled;
+ break;
+ default:
zend_throw_exception(spl_ce_InvalidArgumentException,
- "metadata values must be arrays of strings",
- 1 TSRMLS_CC);
- return;
- }
- metadata.key = key;
- metadata.value = Z_STRVAL_P(*value);
- metadata.value_length = Z_STRLEN_P(*value);
- error_code = grpc_call_add_metadata_old(call->wrapped, &metadata, 0u);
- MAYBE_THROW_CALL_ERROR(add_metadata, error_code);
+ "Unrecognized key in batch", 1 TSRMLS_CC);
+ goto cleanup;
}
+ ops[op_num].op = (grpc_op_type)index;
+ op_num++;
}
-}
-
-/**
- * Invoke the RPC. Starts sending metadata and request headers over the wire
- * @param CompletionQueue $queue The completion queue to use with this call
- * @param long $metadata_tag The tag to associate with returned metadata
- * @param long $finished_tag The tag to associate with the finished event
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, invoke) {
- grpc_call_error error_code;
- long tag1;
- long tag2;
- zval *queue_obj;
- long flags = 0;
- /* "Oll|l" == 1 Object, 3 mandatory longs, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oll|l", &queue_obj,
- grpc_ce_completion_queue, &tag1, &tag2,
- &flags) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "invoke needs a CompletionQueue, 2 longs, and an optional long",
- 1 TSRMLS_CC);
- return;
- }
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
- error_code = grpc_call_invoke_old(call->wrapped, queue->wrapped, (void *)tag1,
- (void *)tag2, (gpr_uint32)flags);
- MAYBE_THROW_CALL_ERROR(invoke, error_code);
-}
-
-/**
- * Accept an incoming RPC, binding a completion queue to it. To be called after
- * adding metadata to the call, but before sending messages. Can only be called
- * on the server
- * @param CompletionQueue $queue The completion queue to use with this call
- * @param long $finished_tag The tag to associate with the finished event
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, server_accept) {
- long tag;
- zval *queue_obj;
- grpc_call_error error_code;
- /* "Ol|l" == 1 Object, 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &queue_obj,
- grpc_ce_completion_queue, &tag) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "server_accept expects a CompletionQueue, a long, and an optional long",
- 1 TSRMLS_CC);
- return;
+ error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped);
+ if (error != GRPC_CALL_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "start_batch was called incorrectly",
+ (long)error TSRMLS_CC);
+ goto cleanup;
}
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
- error_code =
- grpc_call_server_accept_old(call->wrapped, queue->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(server_accept, error_code);
-}
-
-PHP_METHOD(Call, server_end_initial_metadata) {
- grpc_call_error error_code;
- long flags = 0;
- /* "|l" == 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) ==
- FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "server_end_initial_metadata expects an optional long",
- 1 TSRMLS_CC);
- }
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- error_code = grpc_call_server_end_initial_metadata_old(call->wrapped, flags);
- MAYBE_THROW_CALL_ERROR(server_end_initial_metadata, error_code);
-}
-
-/**
- * Called by clients to cancel an RPC on the server.
- * @return Void
- */
-PHP_METHOD(Call, cancel) {
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- grpc_call_error error_code = grpc_call_cancel(call->wrapped);
- MAYBE_THROW_CALL_ERROR(cancel, error_code);
-}
-
-/**
- * Queue a byte buffer for writing
- * @param string $buffer The buffer to queue for writing
- * @param long $tag The tag to associate with this write
- * @param long $flags A bitwise combination of the Grpc\WRITE_* constants
- * (optional)
- * @return Void
- */
-PHP_METHOD(Call, start_write) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- char *buffer;
- int buffer_len;
- long tag;
- long flags = 0;
- /* "Ol|l" == 1 Object, 1 mandatory long, 1 optional long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &buffer,
- &buffer_len, &tag, &flags) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "start_write expects a string and an optional long",
+ event = grpc_completion_queue_pluck(call->queue, call->wrapped,
+ gpr_inf_future);
+ if (event->data.op_complete != GRPC_OP_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "The batch failed for some reason",
1 TSRMLS_CC);
- return;
- }
- error_code = grpc_call_start_write_old(
- call->wrapped, string_to_byte_buffer(buffer, buffer_len), (void *)tag,
- (gpr_uint32)flags);
- MAYBE_THROW_CALL_ERROR(start_write, error_code);
-}
-
-/**
- * Queue a status for writing
- * @param long $status_code The status code to send
- * @param string $status_details The status details to send
- * @param long $tag The tag to associate with this status
- * @return Void
- */
-PHP_METHOD(Call, start_write_status) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long status_code;
- int status_details_length;
- long tag;
- char *status_details;
- /* "lsl" == 1 long, 1 string, 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsl", &status_code,
- &status_details, &status_details_length,
- &tag) == FAILURE) {
- zend_throw_exception(
- spl_ce_InvalidArgumentException,
- "start_write_status expects a long, a string, and a long", 1 TSRMLS_CC);
- return;
+ goto cleanup;
}
- error_code = grpc_call_start_write_status_old(call->wrapped,
- (grpc_status_code)status_code,
- status_details, (void *)tag);
- MAYBE_THROW_CALL_ERROR(start_write_status, error_code);
-}
-
-/**
- * Indicate that there are no more messages to send
- * @return Void
- */
-PHP_METHOD(Call, writes_done) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "writes_done expects a long", 1 TSRMLS_CC);
- return;
+ for (int i = 0; i < op_num; i++) {
+ switch(ops[i].op) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ add_property_bool(result, "send_metadata", true);
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ add_property_bool(result, "send_message", true);
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ add_property_bool(result, "send_close", true);
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ add_property_bool(result, "send_status", true);
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ add_property_zval(result, "metadata",
+ grpc_parse_metadata_array(&recv_metadata));
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ byte_buffer_to_string(message, &message_str, &message_len);
+ add_property_stringl(result, "message", message_str, message_len,
+ false);
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ MAKE_STD_ZVAL(recv_status);
+ object_init(recv_status);
+ add_property_zval(recv_status, "metadata",
+ grpc_parse_metadata_array(&recv_trailing_metadata));
+ add_property_long(recv_status, "code", status);
+ add_property_string(recv_status, "details", status_details, true);
+ add_property_zval(result, "status", recv_status);
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ add_property_bool(result, "cancelled", cancelled);
+ break;
+ default:
+ break;
+ }
}
- error_code = grpc_call_writes_done_old(call->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(writes_done, error_code);
-}
-
-/**
- * Initiate a read on a call. Output event contains a byte buffer with the
- * result of the read
- * @param long $tag The tag to associate with this read
- * @return Void
- */
-PHP_METHOD(Call, start_read) {
- grpc_call_error error_code;
- wrapped_grpc_call *call =
- (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "start_read expects a long", 1 TSRMLS_CC);
- return;
+cleanup:
+ grpc_metadata_array_destroy(&metadata);
+ grpc_metadata_array_destroy(&trailing_metadata);
+ grpc_metadata_array_destroy(&recv_metadata);
+ grpc_metadata_array_destroy(&recv_trailing_metadata);
+ if (status_details != NULL) {
+ gpr_free(status_details);
}
- error_code = grpc_call_start_read_old(call->wrapped, (void *)tag);
- MAYBE_THROW_CALL_ERROR(start_read, error_code);
+ RETURN_DESTROY_ZVAL(result);
}
static zend_function_entry call_methods[] = {
PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(Call, server_accept, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, server_end_initial_metadata, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, add_metadata, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, invoke, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_read, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_write, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, start_write_status, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, writes_done, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
+ PHP_ME(Call, start_batch, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
void grpc_init_call(TSRMLS_D) {
zend_class_entry ce;
diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h
index bce5d82974..743effe5a1 100644
--- a/src/php/ext/grpc/call.h
+++ b/src/php/ext/grpc/call.h
@@ -45,17 +45,6 @@
#include "grpc/grpc.h"
-// Throw an exception if error_code is not OK
-#define MAYBE_THROW_CALL_ERROR(func_name, error_code) \
- do { \
- if (error_code != GRPC_CALL_OK) { \
- zend_throw_exception(spl_ce_LogicException, \
- #func_name " was called incorrectly", \
- (long)error_code TSRMLS_CC); \
- return; \
- } \
- } while (0)
-
/* Class entry for the Call PHP class */
extern zend_class_entry *grpc_ce_call;
@@ -65,16 +54,18 @@ typedef struct wrapped_grpc_call {
bool owned;
grpc_call *wrapped;
+ grpc_completion_queue *queue;
} wrapped_grpc_call;
/* Initializes the Call PHP class */
void grpc_init_call(TSRMLS_D);
/* Creates a Call object that wraps the given grpc_call struct */
-zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned);
+zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue,
+ bool owned);
/* Creates and returns a PHP associative array of metadata from a C array of
* call metadata */
-zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements);
+zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array);
#endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 5e99332fab..c96fb128a6 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -51,7 +51,6 @@
#include "grpc/support/log.h"
#include "grpc/grpc_security.h"
-#include "completion_queue.h"
#include "server.h"
#include "credentials.h"
@@ -139,6 +138,9 @@ PHP_METHOD(Channel, __construct) {
HashTable *array_hash;
zval **creds_obj = NULL;
wrapped_grpc_credentials *creds = NULL;
+ zval **override_obj;
+ char *override;
+ int override_len;
/* "s|a" == 1 string, 1 optional array */
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &target,
&target_length, &args_array) == FAILURE) {
@@ -146,6 +148,8 @@ PHP_METHOD(Channel, __construct) {
"Channel expects a string and an array", 1 TSRMLS_CC);
return;
}
+ override = target;
+ override_len = target_length;
if (args_array == NULL) {
channel->wrapped = grpc_channel_create(target, NULL);
} else {
@@ -162,6 +166,19 @@ PHP_METHOD(Channel, __construct) {
*creds_obj TSRMLS_CC);
zend_hash_del(array_hash, "credentials", 12);
}
+ if (zend_hash_find(array_hash, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
+ sizeof(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG),
+ (void **)&override_obj) == SUCCESS) {
+ if (Z_TYPE_PP(override_obj) != IS_STRING) {
+ zend_throw_exception(spl_ce_InvalidArgumentException,
+ GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
+ " must be a string",
+ 1 TSRMLS_CC);
+ return;
+ }
+ override = Z_STRVAL_PP(override_obj);
+ override_len = Z_STRLEN_PP(override_obj);
+ }
php_grpc_read_args_array(args_array, &args);
if (creds == NULL) {
channel->wrapped = grpc_channel_create(target, &args);
@@ -172,8 +189,8 @@ PHP_METHOD(Channel, __construct) {
}
efree(args.args);
}
- channel->target = ecalloc(target_length + 1, sizeof(char));
- memcpy(channel->target, target, target_length);
+ channel->target = ecalloc(override_len + 1, sizeof(char));
+ memcpy(channel->target, override, override_len);
}
/**
diff --git a/src/php/ext/grpc/completion_queue.c b/src/php/ext/grpc/completion_queue.c
deleted file mode 100644
index 93abf5df36..0000000000
--- a/src/php/ext/grpc/completion_queue.c
+++ /dev/null
@@ -1,170 +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.
- *
- */
-
-#include "completion_queue.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "ext/spl/spl_exceptions.h"
-#include "php_grpc.h"
-
-#include "zend_exceptions.h"
-
-#include <stdbool.h>
-
-#include "grpc/grpc.h"
-
-#include "event.h"
-#include "timeval.h"
-
-zend_class_entry *grpc_ce_completion_queue;
-
-/* Frees and destroys a wrapped instance of grpc_completion_queue */
-void free_wrapped_grpc_completion_queue(void *object TSRMLS_DC) {
- wrapped_grpc_completion_queue *queue = NULL;
- grpc_event *event;
- queue = (wrapped_grpc_completion_queue *)object;
- if (queue->wrapped != NULL) {
- grpc_completion_queue_shutdown(queue->wrapped);
- event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
- while (event != NULL) {
- if (event->type == GRPC_QUEUE_SHUTDOWN) {
- break;
- }
- event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future);
- }
- grpc_completion_queue_destroy(queue->wrapped);
- }
- efree(queue);
-}
-
-/* Initializes an instance of wrapped_grpc_channel to be associated with an
- * object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_completion_queue(
- zend_class_entry *class_type TSRMLS_DC) {
- zend_object_value retval;
- wrapped_grpc_completion_queue *intern;
-
- intern = (wrapped_grpc_completion_queue *)emalloc(
- sizeof(wrapped_grpc_completion_queue));
- memset(intern, 0, sizeof(wrapped_grpc_completion_queue));
-
- zend_object_std_init(&intern->std, class_type TSRMLS_CC);
- object_properties_init(&intern->std, class_type);
- retval.handle = zend_objects_store_put(
- intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
- free_wrapped_grpc_completion_queue, NULL TSRMLS_CC);
- retval.handlers = zend_get_std_object_handlers();
- return retval;
-}
-
-/**
- * Construct an instance of CompletionQueue
- */
-PHP_METHOD(CompletionQueue, __construct) {
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- queue->wrapped = grpc_completion_queue_create();
-}
-
-/**
- * Blocks until an event is available, the completion queue is being shutdown,
- * or timeout is reached. Returns NULL on timeout, otherwise the event that
- * occurred. Callers should call event.finish once they have processed the
- * event.
- * @param Timeval $timeout The timeout for the event
- * @return Event The event that occurred
- */
-PHP_METHOD(CompletionQueue, next) {
- zval *timeout;
- /* "O" == 1 Object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &timeout,
- grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "next needs a Timeval", 1 TSRMLS_CC);
- return;
- }
- wrapped_grpc_completion_queue *completion_queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- wrapped_grpc_timeval *wrapped_timeout =
- (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
- grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped,
- wrapped_timeout->wrapped);
- if (event == NULL) {
- RETURN_NULL();
- }
- zval *wrapped_event = grpc_php_convert_event(event);
- RETURN_DESTROY_ZVAL(wrapped_event);
-}
-
-PHP_METHOD(CompletionQueue, pluck) {
- long tag;
- zval *timeout;
- /* "lO" == 1 long, 1 Object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &tag, &timeout,
- grpc_ce_timeval) == FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "pluck needs a long and a Timeval", 1 TSRMLS_CC);
- }
- wrapped_grpc_completion_queue *completion_queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis()
- TSRMLS_CC);
- wrapped_grpc_timeval *wrapped_timeout =
- (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC);
- grpc_event *event = grpc_completion_queue_pluck(
- completion_queue->wrapped, (void *)tag, wrapped_timeout->wrapped);
- if (event == NULL) {
- RETURN_NULL();
- }
- zval *wrapped_event = grpc_php_convert_event(event);
- RETURN_DESTROY_ZVAL(wrapped_event);
-}
-
-static zend_function_entry completion_queue_methods[] = {
- PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
-
-void grpc_init_completion_queue(TSRMLS_D) {
- zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, "Grpc\\CompletionQueue", completion_queue_methods);
- ce.create_object = create_wrapped_grpc_completion_queue;
- grpc_ce_completion_queue = zend_register_internal_class(&ce TSRMLS_CC);
-}
diff --git a/src/php/ext/grpc/completion_queue.h b/src/php/ext/grpc/completion_queue.h
deleted file mode 100755
index 1d386cc58f..0000000000
--- a/src/php/ext/grpc/completion_queue.h
+++ /dev/null
@@ -1,62 +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 NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_
-#define NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
-
-#include "grpc/grpc.h"
-
-/* Class entry for the PHP CompletionQueue class */
-extern zend_class_entry *grpc_ce_completion_queue;
-
-/* Wrapper class for grpc_completion_queue that can be associated with a
- PHP object */
-typedef struct wrapped_grpc_completion_queue {
- zend_object std;
-
- grpc_completion_queue *wrapped;
-} wrapped_grpc_completion_queue;
-
-/* Initialize the CompletionQueue class */
-void grpc_init_completion_queue(TSRMLS_D);
-
-#endif /* NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_ */
diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4
index 27c67781e7..d1a8decb73 100755
--- a/src/php/ext/grpc/config.m4
+++ b/src/php/ext/grpc/config.m4
@@ -66,5 +66,5 @@ if test "$PHP_GRPC" != "no"; then
PHP_SUBST(GRPC_SHARED_LIBADD)
- PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c completion_queue.c credentials.c event.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -pedantic -std=c99)
+ PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c credentials.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -pedantic -std=c99)
fi
diff --git a/src/php/ext/grpc/event.c b/src/php/ext/grpc/event.c
deleted file mode 100644
index 452c4b8bcb..0000000000
--- a/src/php/ext/grpc/event.c
+++ /dev/null
@@ -1,150 +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.
- *
- */
-
-#include "event.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
-
-#include <stdbool.h>
-
-#include "grpc/grpc.h"
-
-#include "byte_buffer.h"
-#include "call.h"
-#include "timeval.h"
-
-/* Create a new PHP object containing the event data in the event struct.
- event must not be used after this function is called */
-zval *grpc_php_convert_event(grpc_event *event) {
- zval *data_object;
- char *detail_string;
- size_t detail_len;
- char *method_string;
- size_t method_len;
- char *host_string;
- size_t host_len;
- char *read_string;
- size_t read_len;
-
- zval *event_object;
-
- if (event == NULL) {
- return NULL;
- }
-
- MAKE_STD_ZVAL(event_object);
- object_init(event_object);
-
- add_property_zval(
- event_object, "call",
- grpc_php_wrap_call(event->call, event->type == GRPC_SERVER_RPC_NEW));
- add_property_long(event_object, "type", event->type);
- add_property_long(event_object, "tag", (long)event->tag);
-
- switch (event->type) {
- case GRPC_QUEUE_SHUTDOWN:
- add_property_null(event_object, "data");
- break;
- case GRPC_READ:
- if (event->data.read == NULL) {
- add_property_null(event_object, "data");
- } else {
- byte_buffer_to_string(event->data.read, &read_string, &read_len);
- add_property_stringl(event_object, "data", read_string, read_len, true);
- }
- break;
- case GRPC_WRITE_ACCEPTED:
- add_property_long(event_object, "data", (long)event->data.write_accepted);
- break;
- case GRPC_FINISH_ACCEPTED:
- add_property_long(event_object, "data",
- (long)event->data.finish_accepted);
- break;
- case GRPC_CLIENT_METADATA_READ:
- data_object = grpc_call_create_metadata_array(
- event->data.client_metadata_read.count,
- event->data.client_metadata_read.elements);
- add_property_zval(event_object, "data", data_object);
- break;
- case GRPC_FINISHED:
- MAKE_STD_ZVAL(data_object);
- object_init(data_object);
- add_property_long(data_object, "code", event->data.finished.status);
- if (event->data.finished.details == NULL) {
- add_property_null(data_object, "details");
- } else {
- detail_len = strlen(event->data.finished.details);
- detail_string = ecalloc(detail_len + 1, sizeof(char));
- memcpy(detail_string, event->data.finished.details, detail_len);
- add_property_string(data_object, "details", detail_string, true);
- }
- add_property_zval(data_object, "metadata",
- grpc_call_create_metadata_array(
- event->data.finished.metadata_count,
- event->data.finished.metadata_elements));
- add_property_zval(event_object, "data", data_object);
- break;
- case GRPC_SERVER_RPC_NEW:
- MAKE_STD_ZVAL(data_object);
- object_init(data_object);
- method_len = strlen(event->data.server_rpc_new.method);
- method_string = ecalloc(method_len + 1, sizeof(char));
- memcpy(method_string, event->data.server_rpc_new.method, method_len);
- add_property_string(data_object, "method", method_string, false);
- host_len = strlen(event->data.server_rpc_new.host);
- host_string = ecalloc(host_len + 1, sizeof(char));
- memcpy(host_string, event->data.server_rpc_new.host, host_len);
- add_property_string(data_object, "host", host_string, false);
- add_property_zval(
- data_object, "absolute_timeout",
- grpc_php_wrap_timeval(event->data.server_rpc_new.deadline));
- add_property_zval(data_object, "metadata",
- grpc_call_create_metadata_array(
- event->data.server_rpc_new.metadata_count,
- event->data.server_rpc_new.metadata_elements));
- add_property_zval(event_object, "data", data_object);
- break;
- default:
- add_property_null(event_object, "data");
- break;
- }
- grpc_event_finish(event);
- return event_object;
-}
diff --git a/src/php/ext/grpc/event.h b/src/php/ext/grpc/event.h
deleted file mode 100755
index ef5846aee1..0000000000
--- a/src/php/ext/grpc/event.h
+++ /dev/null
@@ -1,51 +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 NET_GRPC_PHP_GRPC_EVENT_H_
-#define NET_GRPC_PHP_GRPC_EVENT_H_
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_grpc.h"
-
-#include "grpc/grpc.h"
-
-/* Create a new Event object that wraps an existing grpc_event struct */
-zval *grpc_php_convert_event(grpc_event *event);
-
-#endif /* NET_GRPC_PHP_GRPC_COMPLETION_CHANNEL_H */
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 67e366c385..1f9edfe881 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -34,8 +34,6 @@
#include "call.h"
#include "channel.h"
#include "server.h"
-#include "completion_queue.h"
-#include "event.h"
#include "timeval.h"
#include "credentials.h"
#include "server_credentials.h"
@@ -127,27 +125,12 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_INVALID_FLAGS",
GRPC_CALL_ERROR_INVALID_FLAGS, CONST_CS);
- /* Register op error constants */
- REGISTER_LONG_CONSTANT("Grpc\\OP_OK", GRPC_OP_OK, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\OP_ERROR", GRPC_OP_ERROR, CONST_CS);
-
/* Register flag constants */
REGISTER_LONG_CONSTANT("Grpc\\WRITE_BUFFER_HINT", GRPC_WRITE_BUFFER_HINT,
CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\WRITE_NO_COMPRESS", GRPC_WRITE_NO_COMPRESS,
CONST_CS);
- /* Register completion type constants */
- REGISTER_LONG_CONSTANT("Grpc\\QUEUE_SHUTDOWN", GRPC_QUEUE_SHUTDOWN, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\READ", GRPC_READ, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\FINISH_ACCEPTED", GRPC_FINISH_ACCEPTED,
- CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\WRITE_ACCEPTED", GRPC_WRITE_ACCEPTED, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\CLIENT_METADATA_READ",
- GRPC_CLIENT_METADATA_READ, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\FINISHED", GRPC_FINISHED, CONST_CS);
- REGISTER_LONG_CONSTANT("Grpc\\SERVER_RPC_NEW", GRPC_SERVER_RPC_NEW, CONST_CS);
-
/* Register status constants */
REGISTER_LONG_CONSTANT("Grpc\\STATUS_OK", GRPC_STATUS_OK, CONST_CS);
REGISTER_LONG_CONSTANT("Grpc\\STATUS_CANCELLED", GRPC_STATUS_CANCELLED,
@@ -181,10 +164,27 @@ PHP_MINIT_FUNCTION(grpc) {
REGISTER_LONG_CONSTANT("Grpc\\STATUS_DATA_LOSS", GRPC_STATUS_DATA_LOSS,
CONST_CS);
+ /* Register op type constants */
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_INITIAL_METADATA",
+ GRPC_OP_SEND_INITIAL_METADATA, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_MESSAGE",
+ GRPC_OP_SEND_MESSAGE, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_CLOSE_FROM_CLIENT",
+ GRPC_OP_SEND_CLOSE_FROM_CLIENT, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_STATUS_FROM_SERVER",
+ GRPC_OP_SEND_STATUS_FROM_SERVER, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_INITIAL_METADATA",
+ GRPC_OP_RECV_INITIAL_METADATA, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_MESSAGE",
+ GRPC_OP_RECV_MESSAGE, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_STATUS_ON_CLIENT",
+ GRPC_OP_RECV_STATUS_ON_CLIENT, CONST_CS);
+ REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER",
+ GRPC_OP_RECV_CLOSE_ON_SERVER, CONST_CS);
+
grpc_init_call(TSRMLS_C);
grpc_init_channel(TSRMLS_C);
grpc_init_server(TSRMLS_C);
- grpc_init_completion_queue(TSRMLS_C);
grpc_init_timeval(TSRMLS_C);
grpc_init_credentials(TSRMLS_C);
grpc_init_server_credentials(TSRMLS_C);
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index a5cfd95287..86b29958fb 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -52,15 +52,27 @@
#include "grpc/grpc_security.h"
#include "server.h"
-#include "completion_queue.h"
#include "channel.h"
#include "server_credentials.h"
+#include "timeval.h"
zend_class_entry *grpc_ce_server;
/* Frees and destroys an instance of wrapped_grpc_server */
void free_wrapped_grpc_server(void *object TSRMLS_DC) {
wrapped_grpc_server *server = (wrapped_grpc_server *)object;
+ grpc_event *event;
+ if (server->queue != NULL) {
+ grpc_completion_queue_shutdown(server->queue);
+ event = grpc_completion_queue_next(server->queue, gpr_inf_future);
+ while (event != NULL) {
+ if (event->type == GRPC_QUEUE_SHUTDOWN) {
+ break;
+ }
+ event = grpc_completion_queue_next(server->queue, gpr_inf_future);
+ }
+ grpc_completion_queue_destroy(server->queue);
+ }
if (server->wrapped != NULL) {
grpc_server_shutdown(server->wrapped);
grpc_server_destroy(server->wrapped);
@@ -95,26 +107,22 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type
PHP_METHOD(Server, __construct) {
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
- zval *queue_obj;
zval *args_array = NULL;
grpc_channel_args args;
- /* "O|a" == 1 Object, 1 optional array */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj,
- grpc_ce_completion_queue, &args_array) == FAILURE) {
+ /* "|a" == 1 optional array */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) ==
+ FAILURE) {
zend_throw_exception(spl_ce_InvalidArgumentException,
- "Server expects a CompletionQueue and an array",
+ "Server expects an array",
1 TSRMLS_CC);
return;
}
- add_property_zval(getThis(), "completion_queue", queue_obj);
- wrapped_grpc_completion_queue *queue =
- (wrapped_grpc_completion_queue *)zend_object_store_get_object(
- queue_obj TSRMLS_CC);
+ server->queue = grpc_completion_queue_create();
if (args_array == NULL) {
- server->wrapped = grpc_server_create(queue->wrapped, NULL);
+ server->wrapped = grpc_server_create(server->queue, NULL);
} else {
php_grpc_read_args_array(args_array, &args);
- server->wrapped = grpc_server_create(queue->wrapped, &args);
+ server->wrapped = grpc_server_create(server->queue, &args);
efree(args.args);
}
}
@@ -129,16 +137,40 @@ PHP_METHOD(Server, request_call) {
grpc_call_error error_code;
wrapped_grpc_server *server =
(wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC);
- long tag_new;
- /* "l" == 1 long */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag_new) ==
- FAILURE) {
- zend_throw_exception(spl_ce_InvalidArgumentException,
- "request_call expects a long", 1 TSRMLS_CC);
- return;
+ grpc_call *call;
+ grpc_call_details details;
+ grpc_metadata_array metadata;
+ zval *result;
+ grpc_event *event;
+ MAKE_STD_ZVAL(result);
+ object_init(result);
+ grpc_call_details_init(&details);
+ grpc_metadata_array_init(&metadata);
+ error_code = grpc_server_request_call(server->wrapped, &call, &details,
+ &metadata, server->queue, NULL);
+ if (error_code != GRPC_CALL_OK) {
+ zend_throw_exception(spl_ce_LogicException, "request_call failed",
+ (long)error_code TSRMLS_CC);
+ goto cleanup;
+ }
+ event = grpc_completion_queue_pluck(server->queue, NULL, gpr_inf_future);
+ if (event->data.op_complete != GRPC_OP_OK) {
+ zend_throw_exception(spl_ce_LogicException,
+ "Failed to request a call for some reason",
+ 1 TSRMLS_CC);
+ goto cleanup;
}
- error_code = grpc_server_request_call_old(server->wrapped, (void *)tag_new);
- MAYBE_THROW_CALL_ERROR(request_call, error_code);
+ add_property_zval(result, "call", grpc_php_wrap_call(call, server->queue,
+ true));
+ add_property_string(result, "method", details.method, true);
+ add_property_string(result, "host", details.host, true);
+ add_property_zval(result, "absolute_deadline",
+ grpc_php_wrap_timeval(details.deadline));
+ add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata));
+cleanup:
+ grpc_call_details_destroy(&details);
+ grpc_metadata_array_destroy(&metadata);
+ RETURN_DESTROY_ZVAL(result);
}
/**
@@ -168,7 +200,7 @@ PHP_METHOD(Server, add_secure_http2_port) {
int addr_len;
zval *creds_obj;
/* "sO" == 1 string, 1 object */
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len,
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len,
&creds_obj, grpc_ce_server_credentials) ==
FAILURE) {
zend_throw_exception(
diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h
index b55689c581..ebb8d25ae1 100755
--- a/src/php/ext/grpc/server.h
+++ b/src/php/ext/grpc/server.h
@@ -53,6 +53,7 @@ typedef struct wrapped_grpc_server {
zend_object std;
grpc_server *wrapped;
+ grpc_completion_queue *queue;
} wrapped_grpc_server;
/* Initializes the Server class */
diff --git a/src/php/lib/Grpc/ActiveCall.php b/src/php/lib/Grpc/ActiveCall.php
index f0d0d55582..af4dca50d7 100755
--- a/src/php/lib/Grpc/ActiveCall.php
+++ b/src/php/lib/Grpc/ActiveCall.php
@@ -38,9 +38,7 @@ require_once realpath(dirname(__FILE__) . '/../autoload.php');
* Represents an active call that allows sending and recieving binary data
*/
class ActiveCall {
- private $completion_queue;
private $call;
- private $flags;
private $metadata;
/**
@@ -48,24 +46,15 @@ class ActiveCall {
* @param Channel $channel The channel to communicate on
* @param string $method The method to call on the remote server
* @param array $metadata Metadata to send with the call, if applicable
- * @param long $flags Write flags to use with this call
*/
public function __construct(Channel $channel,
$method,
- $metadata = array(),
- $flags = 0) {
- $this->completion_queue = new CompletionQueue();
+ $metadata = array()) {
$this->call = new Call($channel, $method, Timeval::inf_future());
- $this->call->add_metadata($metadata, 0);
- $this->flags = $flags;
- // Invoke the call.
- $this->call->invoke($this->completion_queue,
- CLIENT_METADATA_READ,
- FINISHED, 0);
- $metadata_event = $this->completion_queue->pluck(CLIENT_METADATA_READ,
- Timeval::inf_future());
- $this->metadata = $metadata_event->data;
+ $event = $this->call->start_batch([OP_SEND_INITIAL_METADATA => $metadata]);
+
+ $this->metadata = $event->metadata;
}
/**
@@ -87,8 +76,7 @@ class ActiveCall {
* @return The next message from the server, or null if there is none.
*/
public function read() {
- $this->call->start_read(READ);
- $read_event = $this->completion_queue->pluck(READ, Timeval::inf_future());
+ $read_event = $this->call->start_batch([OP_RECV_MESSAGE => true]);
return $read_event->data;
}
@@ -98,16 +86,14 @@ class ActiveCall {
* @param ByteBuffer $data The data to write
*/
public function write($data) {
- $this->call->start_write($data, WRITE_ACCEPTED, $this->flags);
- $this->completion_queue->pluck(WRITE_ACCEPTED, Timeval::inf_future());
+ $this->call->start_batch([OP_SEND_MESSAGE => $data]);
}
/**
* Indicate that no more writes will be sent.
*/
public function writesDone() {
- $this->call->writes_done(FINISH_ACCEPTED);
- $this->completion_queue->pluck(FINISH_ACCEPTED, Timeval::inf_future());
+ $this->call->start_batch([OP_SEND_CLOSE_FROM_CLIENT => true]);
}
/**
@@ -116,8 +102,7 @@ class ActiveCall {
* and array $metadata members
*/
public function getStatus() {
- $status_event = $this->completion_queue->pluck(FINISHED,
- Timeval::inf_future());
+ $status_event = $this->call->start_batch([RECV_STATUS_ON_CLIENT => true]);
return $status_event->data;
}
}
diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php
index 8bb0927f21..d361ce0030 100755
--- a/src/php/tests/unit_tests/CallTest.php
+++ b/src/php/tests/unit_tests/CallTest.php
@@ -36,65 +36,47 @@ class CallTest extends PHPUnit_Framework_TestCase{
static $port;
public static function setUpBeforeClass() {
- $cq = new Grpc\CompletionQueue();
- self::$server = new Grpc\Server($cq, []);
+ self::$server = new Grpc\Server([]);
self::$port = self::$server->add_http2_port('0.0.0.0:0');
}
public function setUp() {
- $this->cq = new Grpc\CompletionQueue();
$this->channel = new Grpc\Channel('localhost:' . self::$port, []);
$this->call = new Grpc\Call($this->channel,
'/foo',
Grpc\Timeval::inf_future());
}
- /**
- * @expectedException LogicException
- * @expectedExceptionCode Grpc\CALL_ERROR_INVALID_FLAGS
- * @expectedExceptionMessage invoke
- */
- public function testInvokeRejectsBadFlags() {
- $this->call->invoke($this->cq, 0, 0, 0xDEADBEEF);
- }
-
- /**
- * @expectedException LogicException
- * @expectedExceptionCode Grpc\CALL_ERROR_NOT_ON_CLIENT
- * @expectedExceptionMessage server_accept
- */
- public function testServerAcceptFailsCorrectly() {
- $this->call->server_accept($this->cq, 0);
- }
-
- /* These test methods with assertTrue(true) at the end just check that the
- method calls completed without errors. PHPUnit warns for tests with no
- asserts, and this avoids that warning without changing the meaning of the
- tests */
-
public function testAddEmptyMetadata() {
- $this->call->add_metadata([], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => []
+ ];
+ $result = $this->call->start_batch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddSingleMetadata() {
- $this->call->add_metadata(['key' => ['value']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']]
+ ];
+ $result = $this->call->start_batch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddMultiValueMetadata() {
- $this->call->add_metadata(['key' => ['value1', 'value2']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']]
+ ];
+ $result = $this->call->start_batch($batch);
+ $this->assertTrue($result->send_metadata);
}
public function testAddSingleAndMultiValueMetadata() {
- $this->call->add_metadata(
- ['key1' => ['value1'],
- 'key2' => ['value2', 'value3']], 0);
- /* Dummy assert: Checks that the previous call completed without error */
- $this->assertTrue(true);
+ $batch = [
+ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'],
+ 'key2' => ['value2', 'value3']]
+ ];
+ $result = $this->call->start_batch($batch);
+ $this->assertTrue($result->send_metadata);
}
}
diff --git a/src/php/tests/unit_tests/CompletionQueueTest.php b/src/php/tests/unit_tests/CompletionQueueTest.php
deleted file mode 100755
index 76ee61dfe8..0000000000
--- a/src/php/tests/unit_tests/CompletionQueueTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/*
- *
- * 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.
- *
- */
-class CompletionQueueTest extends PHPUnit_Framework_TestCase{
- public function testNextReturnsNullWithNoCall() {
- $cq = new Grpc\CompletionQueue();
- $event = $cq->next(Grpc\Timeval::zero());
- $this->assertNull($event);
- }
-
- public function testPluckReturnsNullWithNoCall() {
- $cq = new Grpc\CompletionQueue();
- $event = $cq->pluck(0, Grpc\Timeval::zero());
- $this->assertNull($event);
- }
-}
diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php
index 0cbc506c8e..3e165b7213 100755
--- a/src/php/tests/unit_tests/EndToEndTest.php
+++ b/src/php/tests/unit_tests/EndToEndTest.php
@@ -33,18 +33,15 @@
*/
class EndToEndTest extends PHPUnit_Framework_TestCase{
public function setUp() {
- $this->client_queue = new Grpc\CompletionQueue();
- $this->server_queue = new Grpc\CompletionQueue();
- $this->server = new Grpc\Server($this->server_queue, []);
+ $this->server = new Grpc\Server([]);
$port = $this->server->add_http2_port('0.0.0.0:0');
$this->channel = new Grpc\Channel('localhost:' . $port, []);
+ $this->server->start();
}
public function tearDown() {
unset($this->channel);
unset($this->server);
- unset($this->client_queue);
- unset($this->server_queue);
}
public function testSimpleRequestBody() {
@@ -53,55 +50,45 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
-
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // check that a server rpc new was received
- $this->server->start();
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
- $server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
+ $event = $call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
+ ]);
- // the server sends the status
- $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
- // the client gets CLIENT_METADATA_READ
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
+ $event = $this->server->request_call();
+ $this->assertSame('dummy_method', $event->method);
+ $this->assertSame([], $event->metadata);
+ $server_call = $event->call;
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+ $event = $server_call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->start_batch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
-
unset($call);
unset($server_call);
}
@@ -115,79 +102,52 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
+ $event = $call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => $req_text
+ ]);
- // the client writes
- $call->start_write($req_text, $tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
- // check that a server rpc new was received
- $this->server->start();
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+ $event = $this->server->request_call();
+ $this->assertSame('dummy_method', $event->method);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // start the server read
- $server_call->start_read($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($req_text, $event->data);
-
- // the server replies
- $server_call->start_write($reply_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // the client reads the metadata
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client reads the reply
- $call->start_read($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($reply_text, $event->data);
-
- // the client sends writes done
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the server sends the status
- $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => $reply_text,
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->start_batch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
-
unset($call);
unset($server_call);
}
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index 896afeac49..2d62fe9d5e 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -33,17 +33,16 @@
*/
class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
public function setUp() {
- $this->client_queue = new Grpc\CompletionQueue();
- $this->server_queue = new Grpc\CompletionQueue();
$credentials = Grpc\Credentials::createSsl(
file_get_contents(dirname(__FILE__) . '/../data/ca.pem'));
$server_credentials = Grpc\ServerCredentials::createSsl(
null,
file_get_contents(dirname(__FILE__) . '/../data/server1.key'),
file_get_contents(dirname(__FILE__) . '/../data/server1.pem'));
- $this->server = new Grpc\Server($this->server_queue);
+ $this->server = new Grpc\Server();
$port = $this->server->add_secure_http2_port('0.0.0.0:0',
$server_credentials);
+ $this->server->start();
$this->channel = new Grpc\Channel(
'localhost:' . $port,
[
@@ -55,70 +54,58 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
public function tearDown() {
unset($this->channel);
unset($this->server);
- unset($this->client_queue);
- unset($this->server_queue);
}
public function testSimpleRequestBody() {
- $this->server->start();
$deadline = Grpc\Timeval::inf_future();
$status_text = 'xyz';
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
- $server_tag = 2;
-
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // check that a server rpc new was received
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+
+ $event = $call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+
+ $event = $this->server->request_call();
+ $this->assertSame('dummy_method', $event->method);
+ $this->assertSame([], $event->metadata);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // the server sends the status
- $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets CLIENT_METADATA_READ
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertFalse($event->cancelled);
+
+ $event = $call->start_batch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
-
unset($call);
unset($server_call);
}
public function testClientServerFullRequestResponse() {
- $this->server->start();
$deadline = Grpc\Timeval::inf_future();
$req_text = 'client_server_full_request_response';
$reply_text = 'reply:client_server_full_request_response';
@@ -127,78 +114,52 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{
$call = new Grpc\Call($this->channel,
'dummy_method',
$deadline);
- $tag = 1;
- $call->invoke($this->client_queue, $tag, $tag);
-
- $server_tag = 2;
-
- // the client writes
- $call->start_write($req_text, $tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // check that a server rpc new was received
- $this->server->request_call($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type);
+
+ $event = $call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_CLOSE_FROM_CLIENT => true,
+ Grpc\OP_SEND_MESSAGE => $req_text
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_close);
+ $this->assertTrue($event->send_message);
+
+ $event = $this->server->request_call();
+ $this->assertSame('dummy_method', $event->method);
$server_call = $event->call;
- $this->assertNotNull($server_call);
- $server_call->server_accept($this->server_queue, $server_tag);
-
- $server_call->server_end_initial_metadata();
-
- // start the server read
- $server_call->start_read($server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($req_text, $event->data);
-
- // the server replies
- $server_call->start_write($reply_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type);
-
- // the client reads the metadata
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type);
-
- // the client reads the reply
- $call->start_read($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\READ, $event->type);
- $this->assertSame($reply_text, $event->data);
-
- // the client sends writes done
- $call->writes_done($tag);
- $event = $this->client_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the server sends the status
- $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag);
- $event = $this->server_queue->next($deadline);
- $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type);
- $this->assertSame(Grpc\OP_OK, $event->data);
-
- // the client gets FINISHED
- $event = $this->client_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
- $status = $event->data;
+
+ $event = $server_call->start_batch([
+ Grpc\OP_SEND_INITIAL_METADATA => [],
+ Grpc\OP_SEND_MESSAGE => $reply_text,
+ Grpc\OP_SEND_STATUS_FROM_SERVER => [
+ 'metadata' => [],
+ 'code' => Grpc\STATUS_OK,
+ 'details' => $status_text
+ ],
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_CLOSE_ON_SERVER => true,
+ ]);
+
+ $this->assertTrue($event->send_metadata);
+ $this->assertTrue($event->send_status);
+ $this->assertTrue($event->send_message);
+ $this->assertFalse($event->cancelled);
+ $this->assertSame($req_text, $event->message);
+
+ $event = $call->start_batch([
+ Grpc\OP_RECV_INITIAL_METADATA => true,
+ Grpc\OP_RECV_MESSAGE => true,
+ Grpc\OP_RECV_STATUS_ON_CLIENT => true,
+ ]);
+
+ $this->assertSame([], $event->metadata);
+ $this->assertSame($reply_text, $event->message);
+ $status = $event->status;
+ $this->assertSame([], $status->metadata);
$this->assertSame(Grpc\STATUS_OK, $status->code);
$this->assertSame($status_text, $status->details);
- // and the server gets FINISHED
- $event = $this->server_queue->next($deadline);
- $this->assertNotNull($event);
- $this->assertSame(Grpc\FINISHED, $event->type);
-
unset($call);
unset($server_call);
}