Skip to content

Commit

Permalink
Add the ability to send metadata from the client
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 687424273
  • Loading branch information
Jonathan Godbout authored and copybara-github committed Oct 18, 2024
1 parent 6c11552 commit 937cd00
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 17 deletions.
21 changes: 21 additions & 0 deletions client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ void* new_tag(int num) {
return new int(num);
}

grpc_metadata_array* create_new_grpc_metadata_array_with_data(grpc_metadata* metadata, size_t count) {
grpc_metadata_array* arr = new grpc_metadata_array();
grpc_metadata_array_init(arr);
arr->count = count;
if (count > 0) arr->metadata = metadata;
return arr;
}

grpc_metadata_array* create_new_grpc_metadata_array() {
grpc_metadata_array* arr = new grpc_metadata_array();
grpc_metadata_array_init(arr);
Expand Down Expand Up @@ -118,6 +126,19 @@ void grpc_ops_free(grpc_op* ops, int size) {
free(ops);
}

grpc_metadata* lisp_make_grpc_metadata(const char* key,
const char* value) {
grpc_slice slice_key = grpc_slice_from_copied_string(key);
grpc_slice slice_value = grpc_slice_from_copied_string(value);

grpc_metadata* metadata = new grpc_metadata;
*metadata = grpc_metadata {
slice_key,
slice_value,
};
return metadata;
}

// Takes in a preallocated grpc_op array.
// Stores the given metadata, flags, and count for the
// GRPC_OP_SEND_INITIAL_METADATA operation.
Expand Down
9 changes: 5 additions & 4 deletions client.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ RECEIVE_STATUS_ON_CLIENT op and RECEIVE-STATUS-ON-CLIENT-INDEX in the ops."

(defconstant +num-ops-for-starting-call+ 3)

(defun start-grpc-call (channel service-method-name)
(defun start-grpc-call (channel service-method-name client-context)
"Start a grpc call. Requires a pointer to a grpc CHANNEL object, and a SERVICE-METHOD-NAME
string to direct the call to."
(let* ((num-ops-for-sending-message +num-ops-for-starting-call+)
Expand All @@ -171,9 +171,10 @@ string to direct the call to."
(make-call :c-call c-call
:c-tag tag
:c-ops ops
:ops-plist ops-plist)))
:ops-plist ops-plist
:context client-context)))

(defun grpc-call (channel service-method-name bytes-to-send
(defun grpc-call (channel service-method-name bytes-to-send client-context
server-stream client-stream)
"Uses CHANNEL to call SERVICE-METHOD-NAME on the server with BYTES-TO-SEND
as the arguement to the method and returns the response<list of byte arrays>
Expand All @@ -182,7 +183,7 @@ BYTES-TO-SEND should be a list of byte-vectors each containing a message to
send in a single call to the server. In the case of a server or bidirectional
call we return a list a list of byte vectors each being a response from the server,
otherwise it's a single byte vector list containing a single response."
(let* ((call (start-grpc-call channel service-method-name)))
(let* ((call (start-grpc-call channel service-method-name client-context)))
(unwind-protect
(progn
(if client-stream
Expand Down
53 changes: 41 additions & 12 deletions shared.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -418,18 +418,39 @@ i of grpc_byte_buffer BUFFER."
these operation guide the interaction between the client and server."
(num-ops :int))

(defun make-metadata (metadata)
"Sets OP[INDEX] to a Send Initial Metadata operation by adding metadata
METADATA, the count of metadata COUNT, and the flag FLAG."
(let* ((arr-size (length metadata))
(metadata
(loop for (key value) in metadata
collect
(cffi:foreign-funcall "lisp_make_grpc_metadata"
:string key
:string value)))
(l-arr (make-array (list arr-size)
:initial-contents metadata)))
(cffi:with-foreign-array (arr l-arr (list :array :int64 arr-size))
(cffi:foreign-funcall "create_new_grpc_metadata_array_with_data"
:pointer arr
:size arr-size))))

(defun make-send-metadata-op (op metadata
&key count flag
index)
index)
"Sets OP[INDEX] to a Send Initial Metadata operation by adding metadata
METADATA, the count of metadata COUNT, and the flag FLAG."
(cffi:foreign-funcall "lisp_grpc_make_send_metadata_op"
:pointer op
:int index
:pointer metadata
:int count
:int (convert-metadata-flag-to-integer flag)
:void))
(let ((metadata-ptr (if metadata
(make-metadata metadata)
(cffi:null-pointer))))

(cffi:foreign-funcall "lisp_grpc_make_send_metadata_op"
:pointer op
:int index
:pointer metadata-ptr
:int count
:int (convert-metadata-flag-to-integer flag)
:void))

(defun make-send-message-op (op message &key index)
"Sets OP[INDEX] to a 'Send Message' operation that sends MESSAGE
Expand Down Expand Up @@ -509,7 +530,7 @@ want. Returns a plist containing keys being the op type and values being the ind
(setf (getf ops-plist message-type) (incf cur-index))))

(when send-metadata
(make-send-metadata-op ops (cffi:null-pointer)
(make-send-metadata-op ops send-metadata
:count 0 :flag 0 :index (next-marker :send-metadata)))
(when send-message
(make-send-message-op ops send-message :index (next-marker :send-message)))
Expand Down Expand Up @@ -585,9 +606,12 @@ macros and only call once."
(method-name "" :type string)
;; This is a plist where the key is a keyword for a type of op
;; and the value is the index of that op in an op-array.
(ops-plist nil :type list))
(ops-plist nil :type list)
(context nil :type (or null client-context server-context)))

;; Shared call functions
(defstruct context
(deadline -1 :type integer)
(metadata nil :type list))

(defun receive-message (call)
"Receive a message from the client for a CALL."
Expand Down Expand Up @@ -628,7 +652,12 @@ macros and only call once."
(ops (create-new-grpc-ops num-ops))
(grpc-slice
(convert-bytes-to-grpc-byte-buffer bytes-to-send))
(ops-plist (prepare-ops ops :send-message grpc-slice))
(context (call-context call))
(ops-plist (prepare-ops
ops
:send-message grpc-slice
:send-metadata (and context
(context-metadata context))))
(call-code (call-start-batch c-call ops num-ops tag)))
(declare (ignore ops-plist))
(unless (eql call-code :grpc-call-ok)
Expand Down
6 changes: 5 additions & 1 deletion tests/integration-test.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,13 @@ Parameters
(grpc:with-insecure-channel
(channel
(concatenate 'string hostname ":" (write-to-string port-number)))
(let* ((message "Hello World")
(let* ((client-context
(grpc::make-context :metadata '(("my" "name")
("is" "Lyra"))))
(message "Hello World")
(response (grpc:grpc-call channel method-name
(flexi-streams:string-to-octets message)
client-context
nil nil))
(actual-client-response (flexi-streams:octets-to-string
(car response))))
Expand Down

0 comments on commit 937cd00

Please sign in to comment.