gRPC 1.2.0 compatibility (#12)

* update for reorganized headers in gRPC v1.1: https://github.com/grpc/grpc/pull/7559

* update nix files

* rename all gpr_slice to grpc_slice since we can't be backwards compatible anyway

* use gRPC 1.1.4

* now compatible with gRPC 1.2.0

* use nixpkgs 17.03 to get protobuf3_2, newer proto3-* deps, fix some warnings

* another warning
This commit is contained in:
Connor Clark 2017-04-14 19:28:01 -07:00 committed by GitHub
parent 4ab231c1d9
commit b550607f60
15 changed files with 147 additions and 137 deletions

View file

@ -4,6 +4,7 @@
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#include <grpc/impl/codegen/grpc_types.h> #include <grpc/impl/codegen/grpc_types.h>
#include <grpc/impl/codegen/compression_types.h> #include <grpc/impl/codegen/compression_types.h>
#include <grpc/slice.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -38,32 +39,47 @@ grpc_call *grpc_channel_create_call_(grpc_channel *channel,
grpc_completion_queue *completion_queue, grpc_completion_queue *completion_queue,
const char *method, const char *host, const char *method, const char *host,
gpr_timespec *deadline, void *reserved) { gpr_timespec *deadline, void *reserved) {
grpc_slice method_slice = grpc_slice_from_copied_string(method);
grpc_slice host_slice = grpc_slice_from_copied_string(host);
return grpc_channel_create_call(channel, parent_call, propagation_mask, return grpc_channel_create_call(channel, parent_call, propagation_mask,
completion_queue, method, host, completion_queue, method_slice,
*deadline, reserved); &host_slice, *deadline, reserved);
} }
size_t gpr_slice_length_(gpr_slice *slice){ grpc_slice* grpc_slice_malloc_(size_t len){
return GPR_SLICE_LENGTH(*slice); grpc_slice* retval = malloc(sizeof(grpc_slice));
} *retval = grpc_slice_malloc(len);
uint8_t *gpr_slice_start_(gpr_slice *slice){
return GPR_SLICE_START_PTR(*slice);
}
gpr_slice* gpr_slice_from_copied_buffer_(const char *source, size_t len){
gpr_slice* retval = malloc(sizeof(gpr_slice));
//note: 'gpr_slice_from_copied_string' handles allocating space for 'source'.
*retval = gpr_slice_from_copied_buffer(source, len);
return retval; return retval;
} }
void gpr_slice_unref_(gpr_slice* slice){ size_t grpc_slice_length_(grpc_slice *slice){
gpr_slice_unref(*slice); return GRPC_SLICE_LENGTH(*slice);
} }
void free_slice(gpr_slice *slice){ uint8_t *grpc_slice_start_(grpc_slice *slice){
gpr_slice_unref(*slice); return GRPC_SLICE_START_PTR(*slice);
}
grpc_slice* grpc_slice_from_copied_string_(const char* source){
grpc_slice* retval = malloc(sizeof(grpc_slice));
*retval = grpc_slice_from_copied_string(source);
return retval;
}
grpc_slice* grpc_slice_from_copied_buffer_(const char *source, size_t len){
grpc_slice* retval = malloc(sizeof(grpc_slice));
//note: 'grpc_slice_from_copied_string' handles allocating space for 'source'.
*retval = grpc_slice_from_copied_buffer(source, len);
return retval;
}
void grpc_slice_unref_(grpc_slice* slice){
grpc_slice_unref(*slice);
}
void free_slice(grpc_slice *slice){
grpc_slice_unref(*slice);
grpc_haskell_free("free_slice", slice); grpc_haskell_free("free_slice", slice);
} }
@ -89,8 +105,8 @@ void byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader){
grpc_haskell_free("byte_buffer_reader_destroy", reader); grpc_haskell_free("byte_buffer_reader_destroy", reader);
} }
gpr_slice *grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader){ grpc_slice *grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader){
gpr_slice *retval = malloc(sizeof(gpr_slice)); grpc_slice *retval = malloc(sizeof(grpc_slice));
*retval = grpc_byte_buffer_reader_readall(reader); *retval = grpc_byte_buffer_reader_readall(reader);
return retval; return retval;
} }
@ -170,24 +186,18 @@ void metadata_free(grpc_metadata* m){
void set_metadata_key_val(char *key, char *val, size_t val_len, void set_metadata_key_val(char *key, char *val, size_t val_len,
grpc_metadata *arr, size_t i){ grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i; grpc_metadata *p = arr + i;
p->key = key; p->key = grpc_slice_from_copied_string(key);
p->value = val; p->value = grpc_slice_from_copied_buffer(val,val_len);
p->value_length = val_len;
} }
const char* get_metadata_key(grpc_metadata *arr, size_t i){ grpc_slice* get_metadata_key(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i; grpc_metadata *p = arr + i;
return p->key; return &p->key;
} }
const char* get_metadata_val(grpc_metadata *arr, size_t i){ grpc_slice* get_metadata_val(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i; grpc_metadata *p = arr + i;
return p->value; return &(p->value);
}
size_t get_metadata_val_len(grpc_metadata *arr, size_t i){
grpc_metadata *p = arr + i;
return p->value_length;
} }
grpc_op* op_array_create(size_t n){ grpc_op* op_array_create(size_t n){
@ -207,7 +217,7 @@ void op_array_destroy(grpc_op* op_array, size_t n){
metadata_free(op->data.send_initial_metadata.metadata); metadata_free(op->data.send_initial_metadata.metadata);
break; break;
case GRPC_OP_SEND_MESSAGE: case GRPC_OP_SEND_MESSAGE:
grpc_byte_buffer_destroy(op->data.send_message); grpc_byte_buffer_destroy(op->data.send_message.send_message);
break; break;
case GRPC_OP_SEND_CLOSE_FROM_CLIENT: case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
break; break;
@ -256,7 +266,7 @@ void op_send_message(grpc_op *op_array, size_t i,
grpc_byte_buffer *payload){ grpc_byte_buffer *payload){
grpc_op *op = op_array + i; grpc_op *op = op_array + i;
op->op = GRPC_OP_SEND_MESSAGE; op->op = GRPC_OP_SEND_MESSAGE;
op->data.send_message = grpc_byte_buffer_copy(payload); op->data.send_message.send_message = grpc_byte_buffer_copy(payload);
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
} }
@ -272,7 +282,7 @@ void op_recv_initial_metadata(grpc_op *op_array, size_t i,
grpc_metadata_array** arr){ grpc_metadata_array** arr){
grpc_op *op = op_array + i; grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_INITIAL_METADATA; op->op = GRPC_OP_RECV_INITIAL_METADATA;
op->data.recv_initial_metadata = *arr; op->data.recv_initial_metadata.recv_initial_metadata = *arr;
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
} }
@ -281,7 +291,7 @@ void op_recv_message(grpc_op *op_array, size_t i,
grpc_byte_buffer **payload_recv){ grpc_byte_buffer **payload_recv){
grpc_op *op = op_array + i; grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_MESSAGE; op->op = GRPC_OP_RECV_MESSAGE;
op->data.recv_message = payload_recv; op->data.recv_message.recv_message = payload_recv;
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
} }
@ -289,13 +299,12 @@ void op_recv_message(grpc_op *op_array, size_t i,
void op_recv_status_client(grpc_op *op_array, size_t i, void op_recv_status_client(grpc_op *op_array, size_t i,
grpc_metadata_array** arr, grpc_metadata_array** arr,
grpc_status_code* status, grpc_status_code* status,
char **details, size_t* details_capacity){ grpc_slice* details){
grpc_op *op = op_array + i; grpc_op *op = op_array + i;
op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
op->data.recv_status_on_client.trailing_metadata = *arr; op->data.recv_status_on_client.trailing_metadata = *arr;
op->data.recv_status_on_client.status = status; op->data.recv_status_on_client.status = status;
op->data.recv_status_on_client.status_details = details; op->data.recv_status_on_client.status_details = details;
op->data.recv_status_on_client.status_details_capacity = details_capacity;
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
} }
@ -310,7 +319,7 @@ void op_recv_close_server(grpc_op *op_array, size_t i, int *was_cancelled){
void op_send_status_server(grpc_op *op_array, size_t i, void op_send_status_server(grpc_op *op_array, size_t i,
size_t metadata_count, grpc_metadata* m, size_t metadata_count, grpc_metadata* m,
grpc_status_code status, char *details){ grpc_status_code status, grpc_slice *details){
grpc_op *op = op_array + i; grpc_op *op = op_array + i;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
op->data.send_status_from_server.trailing_metadata_count = metadata_count; op->data.send_status_from_server.trailing_metadata_count = metadata_count;
@ -319,9 +328,7 @@ void op_send_status_server(grpc_op *op_array, size_t i,
memcpy(op->data.send_status_from_server.trailing_metadata, m, memcpy(op->data.send_status_from_server.trailing_metadata, m,
metadata_count*sizeof(grpc_metadata)); metadata_count*sizeof(grpc_metadata));
op->data.send_status_from_server.status = status; op->data.send_status_from_server.status = status;
op->data.send_status_from_server.status_details op->data.send_status_from_server.status_details = details;
= malloc(sizeof(char)*(strlen(details) + 1));
strcpy((char*)(op->data.send_status_from_server.status_details), details);
op->flags = 0; op->flags = 0;
op->reserved = NULL; op->reserved = NULL;
} }
@ -398,12 +405,12 @@ grpc_call* grpc_channel_create_registered_call_(
*deadline, reserved); *deadline, reserved);
} }
char* call_details_get_method(grpc_call_details* details){ grpc_slice* call_details_get_method(grpc_call_details* details){
return details->method; return &details->method;
} }
char* call_details_get_host(grpc_call_details* details){ grpc_slice* call_details_get_host(grpc_call_details* details){
return details->host; return &details->host;
} }
gpr_timespec* call_details_get_deadline(grpc_call_details* details){ gpr_timespec* call_details_get_deadline(grpc_call_details* details){

View file

@ -19,7 +19,7 @@ Flag Debug
flag with-examples flag with-examples
description: Also build example executables. description: Also build example executables.
manual: True manual: True
default: True default: False
library library
build-depends: build-depends:
@ -29,7 +29,7 @@ library
, stm == 2.4.* , stm == 2.4.*
, containers ==0.5.* , containers ==0.5.*
, managed >= 1.0.0 && < 1.1 , managed >= 1.0.0 && < 1.1
, pipes ==4.1.* , pipes >=4.1 && <=4.4
, transformers , transformers
, proto3-suite , proto3-suite
, proto3-wire , proto3-wire
@ -79,8 +79,8 @@ library
, grpc/status.h , grpc/status.h
, grpc/support/time.h , grpc/support/time.h
, grpc/impl/codegen/compression_types.h , grpc/impl/codegen/compression_types.h
, grpc/impl/codegen/slice_buffer.h , grpc/slice_buffer.h
, grpc/impl/codegen/slice.h , grpc/slice.h
build-tools: c2hs build-tools: c2hs
default-language: Haskell2010 default-language: Haskell2010
ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind ghc-options: -Wall -fwarn-incomplete-patterns -fno-warn-unused-do-bind
@ -206,14 +206,14 @@ test-suite test
, tasty-quickcheck ==0.8.* , tasty-quickcheck ==0.8.*
, containers ==0.5.* , containers ==0.5.*
, managed >= 1.0.0 && < 1.1 , managed >= 1.0.0 && < 1.1
, pipes ==4.1.* , pipes >=4.1 && <=4.4
, proto3-suite , proto3-suite
, transformers , transformers
, safe , safe
, clock >=0.6.0 && <0.8.0 , clock >=0.6.0 && <0.8.0
, turtle >= 1.2.0 , turtle >= 1.2.0
, text , text
, QuickCheck ==2.8.* , QuickCheck >=2.8 && <3.0
other-modules: other-modules:
LowLevelTests, LowLevelTests,
LowLevelTests.Op, LowLevelTests.Op,

View file

@ -4,7 +4,7 @@
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/grpc_security.h> #include <grpc/grpc_security.h>
#include <grpc/impl/codegen/slice.h> #include <grpc/impl/codegen/slice.h>
#include <grpc/impl/codegen/time.h> #include <grpc/support/time.h>
#include <grpc/byte_buffer.h> #include <grpc/byte_buffer.h>
#include <grpc/byte_buffer_reader.h> #include <grpc/byte_buffer_reader.h>
@ -23,13 +23,17 @@ grpc_call *grpc_channel_create_call_(grpc_channel *channel,
const char *method, const char *host, const char *method, const char *host,
gpr_timespec *deadline, void *reserved); gpr_timespec *deadline, void *reserved);
size_t gpr_slice_length_(gpr_slice *slice); grpc_slice* grpc_slice_malloc_(size_t len);
uint8_t *gpr_slice_start_(gpr_slice *slice); size_t grpc_slice_length_(grpc_slice *slice);
gpr_slice* gpr_slice_from_copied_buffer_(const char *source, size_t len); uint8_t *grpc_slice_start_(grpc_slice *slice);
void free_slice(gpr_slice *slice); grpc_slice* grpc_slice_from_copied_string_(const char* source);
grpc_slice* grpc_slice_from_copied_buffer_(const char *source, size_t len);
void free_slice(grpc_slice *slice);
grpc_byte_buffer **create_receiving_byte_buffer(); grpc_byte_buffer **create_receiving_byte_buffer();
@ -39,7 +43,7 @@ grpc_byte_buffer_reader *byte_buffer_reader_create(grpc_byte_buffer *buffer);
void byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader); void byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
gpr_slice* grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader); grpc_slice* grpc_byte_buffer_reader_readall_(grpc_byte_buffer_reader *reader);
void timespec_destroy(gpr_timespec* t); void timespec_destroy(gpr_timespec* t);
@ -68,11 +72,9 @@ void metadata_free(grpc_metadata* m);
void set_metadata_key_val(char *key, char *val, size_t val_len, void set_metadata_key_val(char *key, char *val, size_t val_len,
grpc_metadata *arr, size_t i); grpc_metadata *arr, size_t i);
const char* get_metadata_key(grpc_metadata *arr, size_t i); grpc_slice* get_metadata_key(grpc_metadata *arr, size_t i);
const char* get_metadata_val(grpc_metadata *arr, size_t i); grpc_slice* get_metadata_val(grpc_metadata *arr, size_t i);
size_t get_metadata_val_len(grpc_metadata *arr, size_t i);
grpc_op* op_array_create(size_t n); grpc_op* op_array_create(size_t n);
@ -97,13 +99,13 @@ void op_recv_message(grpc_op *op_array, size_t i,
void op_recv_status_client(grpc_op *op_array, size_t i, void op_recv_status_client(grpc_op *op_array, size_t i,
grpc_metadata_array** arr, grpc_metadata_array** arr,
grpc_status_code* status, grpc_status_code* status,
char **details, size_t* details_capacity); grpc_slice* details);
void op_recv_close_server(grpc_op *op_array, size_t i, int *was_cancelled); void op_recv_close_server(grpc_op *op_array, size_t i, int *was_cancelled);
void op_send_status_server(grpc_op *op_array, size_t i, void op_send_status_server(grpc_op *op_array, size_t i,
size_t metadata_count, grpc_metadata* m, size_t metadata_count, grpc_metadata* m,
grpc_status_code status, char *details); grpc_status_code status, grpc_slice *details);
grpc_status_code* create_status_code_ptr(); grpc_status_code* create_status_code_ptr();
@ -135,9 +137,9 @@ grpc_call* grpc_channel_create_registered_call_(
grpc_completion_queue *completion_queue, void *registered_call_handle, grpc_completion_queue *completion_queue, void *registered_call_handle,
gpr_timespec *deadline, void *reserved); gpr_timespec *deadline, void *reserved);
char* call_details_get_method(grpc_call_details* details); grpc_slice* call_details_get_method(grpc_call_details* details);
char* call_details_get_host(grpc_call_details* details); grpc_slice* call_details_get_host(grpc_call_details* details);
gpr_timespec* call_details_get_deadline(grpc_call_details* details); gpr_timespec* call_details_get_deadline(grpc_call_details* details);

View file

@ -3,12 +3,12 @@
stdenv.mkDerivation rec { stdenv.mkDerivation rec {
name = "grpc-${version}"; name = "grpc-${version}";
version = "1.0.1-${lib.strings.substring 0 7 rev}"; version = "1.2.0-${lib.strings.substring 0 7 rev}";
rev = "6040b471bcd1d6bb05b25c126b6545180a1d3528"; rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
src = fetchgit { src = fetchgit {
inherit rev; inherit rev;
url = "https://github.com/grpc/grpc.git"; url = "https://github.com/grpc/grpc.git";
sha256 = "1kx6jkx2dnnfnjfyc50ravfk7mfdszj988vndrlzs1zkd6627k4z"; sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
}; };
preInstall = "export prefix"; preInstall = "export prefix";
buildInputs = buildInputs =

View file

@ -8,8 +8,8 @@ mkDerivation {
version = "0.1.0.0"; version = "0.1.0.0";
src = fetchgit { src = fetchgit {
url = "https://github.com/awakenetworks/proto3-suite.git"; url = "https://github.com/awakenetworks/proto3-suite.git";
sha256 = "1g6w4ddqybgwnj3143bkl7sp9f5ch6d8qpb242fi4m396585bpq9"; sha256 = "1w5qwwlivrxkd6943rxsw3znk9jjpf7ad11gm0zl4lzq6k3kdinp";
rev = "8db2ceb8c48a3f8dc2cbdc492d1e8cbaf8b62a15"; rev = "46f40d38c4db8a6320bab010ae30e75c83fab6ee";
}; };
libraryHaskellDepends = [ libraryHaskellDepends = [
base bytestring cereal containers deepseq filepath haskell-src mtl base bytestring cereal containers deepseq filepath haskell-src mtl

View file

@ -7,8 +7,8 @@ mkDerivation {
version = "1.0.0"; version = "1.0.0";
src = fetchgit { src = fetchgit {
url = "https://github.com/awakenetworks/proto3-wire.git"; url = "https://github.com/awakenetworks/proto3-wire.git";
sha256 = "1v1jsgsdrhaz3ddbil09yqimnps3svgqbjvdk7hil4irpgqkfs98"; sha256 = "10z1sirmiz29r2nx5dza1y1p3kp83wsq80pz4msxqmaykpyh5iaa";
rev = "1b88bf24aad15db1f59a00d201d609fa308157f7"; rev = "62b50ea460847dde5bc8e63d2f93360d9bfcae9d";
}; };
libraryHaskellDepends = [ libraryHaskellDepends = [
base bytestring cereal containers deepseq QuickCheck safe text base bytestring cereal containers deepseq QuickCheck safe text

View file

@ -1,6 +1,6 @@
{ {
"url": "https://github.com/NixOS/nixpkgs.git", "url": "https://github.com/NixOS/nixpkgs.git",
"rev": "7ae9da426924537755ce9164fd5b5f81ce16a1c3", "rev": "1849e695b00a54cda86cb75202240d949c10c7ce",
"date": "2017-01-31T10:35:58-06:00", "date": "2017-03-30T18:32:09+02:00",
"sha256": "1fcvc066c270dd2yfir8cpj0gcslsbvw7grnk2fayb06rkppjxrf" "sha256": "1fw9ryrz1qzbaxnjqqf91yxk1pb9hgci0z0pzw53f675almmv9q2"
} }

View file

@ -62,7 +62,12 @@ let
nixpkgs = import ./nixpkgs.nix; nixpkgs = import ./nixpkgs.nix;
config = { config = {
packageOverrides = pkgs: rec { packageOverrides = pkgs: rec {
cython = pkgs.buildPythonPackage rec { protobuf3_2NoCheck =
pkgs.stdenv.lib.overrideDerivation
pkgs.pythonPackages.protobuf3_2
(oldAttrs : {doCheck = false; doInstallCheck = false;});
cython = pkgs.pythonPackages.buildPythonPackage rec {
name = "Cython-${version}"; name = "Cython-${version}";
version = "0.24.1"; version = "0.24.1";
@ -106,8 +111,8 @@ let
src = pkgs.fetchgit { src = pkgs.fetchgit {
url = "https://github.com/grpc/grpc.git"; url = "https://github.com/grpc/grpc.git";
rev = "c204647295437b01337ad8e6c17c4296609c7a13"; rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
sha256 = "0ifg5acwcb0qyf5g5mrja8ab4x3f1fxdw80rkmhn3kyjkhjzm9ik"; sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
}; };
preConfigure = '' preConfigure = ''
@ -127,7 +132,7 @@ let
propagatedBuildInputs = [ propagatedBuildInputs = [
cython cython
pkgs.pythonPackages.futures pkgs.pythonPackages.futures
pkgs.pythonPackages.protobuf3_0 protobuf3_2NoCheck
pkgs.pythonPackages.enum34 pkgs.pythonPackages.enum34
]; ];
}; };
@ -139,8 +144,8 @@ let
src = pkgs.fetchgit { src = pkgs.fetchgit {
url = "https://github.com/grpc/grpc.git"; url = "https://github.com/grpc/grpc.git";
rev = "c204647295437b01337ad8e6c17c4296609c7a13"; rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
sha256 = "0ifg5acwcb0qyf5g5mrja8ab4x3f1fxdw80rkmhn3kyjkhjzm9ik"; sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
}; };
preConfigure = '' preConfigure = ''
@ -162,7 +167,7 @@ let
propagatedBuildInputs = [ propagatedBuildInputs = [
cython cython
pkgs.pythonPackages.futures pkgs.pythonPackages.futures
pkgs.pythonPackages.protobuf3_0 protobuf3_2NoCheck
pkgs.pythonPackages.enum34 pkgs.pythonPackages.enum34
grpcio grpcio
]; ];

View file

@ -12,19 +12,18 @@ import Control.Monad.Trans.Except
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import qualified Data.ByteString as B import qualified Data.ByteString as B
import Data.Maybe (catMaybes) import Data.Maybe (catMaybes)
import Foreign.C.String (CString)
import Foreign.C.Types (CInt) import Foreign.C.Types (CInt)
import Foreign.Marshal.Alloc (free, malloc, import Foreign.Marshal.Alloc (free, malloc)
mallocBytes)
import Foreign.Ptr (Ptr, nullPtr) import Foreign.Ptr (Ptr, nullPtr)
import Foreign.Storable (peek, poke) import Foreign.Storable (peek)
import Network.GRPC.LowLevel.CompletionQueue import Network.GRPC.LowLevel.CompletionQueue
import Network.GRPC.LowLevel.GRPC import Network.GRPC.LowLevel.GRPC
import qualified Network.GRPC.Unsafe as C (Call) import qualified Network.GRPC.Unsafe as C (Call)
import qualified Network.GRPC.Unsafe.ByteBuffer as C import qualified Network.GRPC.Unsafe.ByteBuffer as C
import qualified Network.GRPC.Unsafe.Metadata as C import qualified Network.GRPC.Unsafe.Metadata as C
import qualified Network.GRPC.Unsafe.Op as C import qualified Network.GRPC.Unsafe.Op as C
import qualified Network.GRPC.Unsafe.Slice as C (Slice, freeSlice) import qualified Network.GRPC.Unsafe.Slice as C
import Network.GRPC.Unsafe.Slice (Slice)
-- | Sum describing all possible send and receive operations that can be batched -- | Sum describing all possible send and receive operations that can be batched
-- and executed by gRPC. Usually these are processed in a handful of -- and executed by gRPC. Usually these are processed in a handful of
@ -46,12 +45,10 @@ data OpContext =
OpSendInitialMetadataContext C.MetadataKeyValPtr Int OpSendInitialMetadataContext C.MetadataKeyValPtr Int
| OpSendMessageContext (C.ByteBuffer, C.Slice) | OpSendMessageContext (C.ByteBuffer, C.Slice)
| OpSendCloseFromClientContext | OpSendCloseFromClientContext
| OpSendStatusFromServerContext C.MetadataKeyValPtr Int C.StatusCode | OpSendStatusFromServerContext C.MetadataKeyValPtr Int C.StatusCode Slice
B.ByteString
| OpRecvInitialMetadataContext (Ptr C.MetadataArray) | OpRecvInitialMetadataContext (Ptr C.MetadataArray)
| OpRecvMessageContext (Ptr C.ByteBuffer) | OpRecvMessageContext (Ptr C.ByteBuffer)
| OpRecvStatusOnClientContext (Ptr C.MetadataArray) (Ptr C.StatusCode) | OpRecvStatusOnClientContext (Ptr C.MetadataArray) (Ptr C.StatusCode) Slice
(Ptr CString)
| OpRecvCloseOnServerContext (Ptr CInt) | OpRecvCloseOnServerContext (Ptr CInt)
deriving Show deriving Show
@ -72,7 +69,7 @@ createOpContext (OpSendStatusFromServer m code (StatusDetails str)) =
uncurry OpSendStatusFromServerContext uncurry OpSendStatusFromServerContext
<$> C.createMetadata m <$> C.createMetadata m
<*> return code <*> return code
<*> return str <*> C.byteStringToSlice str
createOpContext OpRecvInitialMetadata = createOpContext OpRecvInitialMetadata =
fmap OpRecvInitialMetadataContext C.metadataArrayCreate fmap OpRecvInitialMetadataContext C.metadataArrayCreate
createOpContext OpRecvMessage = createOpContext OpRecvMessage =
@ -80,10 +77,8 @@ createOpContext OpRecvMessage =
createOpContext OpRecvStatusOnClient = do createOpContext OpRecvStatusOnClient = do
pmetadata <- C.metadataArrayCreate pmetadata <- C.metadataArrayCreate
pstatus <- C.createStatusCodePtr pstatus <- C.createStatusCodePtr
pstr <- malloc slice <- C.grpcSliceMalloc defaultStatusStringLen
cstring <- mallocBytes defaultStatusStringLen return $ OpRecvStatusOnClientContext pmetadata pstatus slice
poke pstr cstring
return $ OpRecvStatusOnClientContext pmetadata pstatus pstr
createOpContext OpRecvCloseOnServer = createOpContext OpRecvCloseOnServer =
fmap OpRecvCloseOnServerContext $ malloc fmap OpRecvCloseOnServerContext $ malloc
@ -97,14 +92,13 @@ setOpArray arr i (OpSendMessageContext (bb,_)) =
setOpArray arr i OpSendCloseFromClientContext = setOpArray arr i OpSendCloseFromClientContext =
C.opSendCloseClient arr i C.opSendCloseClient arr i
setOpArray arr i (OpSendStatusFromServerContext kvs l code details) = setOpArray arr i (OpSendStatusFromServerContext kvs l code details) =
B.useAsCString details $ \cstr -> C.opSendStatusServer arr i l kvs code details
C.opSendStatusServer arr i l kvs code cstr
setOpArray arr i (OpRecvInitialMetadataContext pmetadata) = setOpArray arr i (OpRecvInitialMetadataContext pmetadata) =
C.opRecvInitialMetadata arr i pmetadata C.opRecvInitialMetadata arr i pmetadata
setOpArray arr i (OpRecvMessageContext pbb) = setOpArray arr i (OpRecvMessageContext pbb) =
C.opRecvMessage arr i pbb C.opRecvMessage arr i pbb
setOpArray arr i (OpRecvStatusOnClientContext pmetadata pstatus pstr) = do setOpArray arr i (OpRecvStatusOnClientContext pmetadata pstatus slice) =
C.opRecvStatusClient arr i pmetadata pstatus pstr defaultStatusStringLen C.opRecvStatusClient arr i pmetadata pstatus slice
setOpArray arr i (OpRecvCloseOnServerContext pcancelled) = do setOpArray arr i (OpRecvCloseOnServerContext pcancelled) = do
C.opRecvCloseServer arr i pcancelled C.opRecvCloseServer arr i pcancelled
@ -120,12 +114,10 @@ freeOpContext (OpRecvInitialMetadataContext metadata) =
C.metadataArrayDestroy metadata C.metadataArrayDestroy metadata
freeOpContext (OpRecvMessageContext pbb) = freeOpContext (OpRecvMessageContext pbb) =
C.destroyReceivingByteBuffer pbb C.destroyReceivingByteBuffer pbb
freeOpContext (OpRecvStatusOnClientContext metadata pcode pstr) = do freeOpContext (OpRecvStatusOnClientContext metadata pcode slice) = do
C.metadataArrayDestroy metadata C.metadataArrayDestroy metadata
C.destroyStatusCodePtr pcode C.destroyStatusCodePtr pcode
str <- peek pstr C.freeSlice slice
free str
free pstr
freeOpContext (OpRecvCloseOnServerContext pcancelled) = freeOpContext (OpRecvCloseOnServerContext pcancelled) =
grpcDebug ("freeOpContext: freeing pcancelled: " ++ show pcancelled) grpcDebug ("freeOpContext: freeing pcancelled: " ++ show pcancelled)
>> free pcancelled >> free pcancelled
@ -176,8 +168,7 @@ resultFromOpContext (OpRecvStatusOnClientContext pmetadata pcode pstr) = do
metadata <- peek pmetadata metadata <- peek pmetadata
metadataMap <- C.getAllMetadataArray metadata metadataMap <- C.getAllMetadataArray metadata
code <- C.derefStatusCodePtr pcode code <- C.derefStatusCodePtr pcode
cstr <- peek pstr statusInfo <- C.sliceToByteString pstr
statusInfo <- B.packCString cstr
return $ Just $ OpRecvStatusOnClientResult metadataMap code statusInfo return $ Just $ OpRecvStatusOnClientResult metadataMap code statusInfo
resultFromOpContext (OpRecvCloseOnServerContext pcancelled) = do resultFromOpContext (OpRecvCloseOnServerContext pcancelled) = do
grpcDebug "resultFromOpContext: OpRecvCloseOnServerContext" grpcDebug "resultFromOpContext: OpRecvCloseOnServerContext"

View file

@ -6,7 +6,7 @@ module Network.GRPC.Unsafe where
import Control.Exception (bracket) import Control.Exception (bracket)
import Control.Monad import Control.Monad
import Data.ByteString (ByteString, useAsCString, packCString) import Data.ByteString (ByteString, useAsCString)
import Foreign.C.String (CString, peekCString) import Foreign.C.String (CString, peekCString)
import Foreign.Marshal.Alloc (free) import Foreign.Marshal.Alloc (free)
@ -20,10 +20,11 @@ import Network.GRPC.Unsafe.Constants
{#import Network.GRPC.Unsafe.Op#} {#import Network.GRPC.Unsafe.Op#}
{#import Network.GRPC.Unsafe.Metadata#} {#import Network.GRPC.Unsafe.Metadata#}
{#import Network.GRPC.Unsafe.ChannelArgs#} {#import Network.GRPC.Unsafe.ChannelArgs#}
{#import Network.GRPC.Unsafe.Slice#}
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/status.h> #include <grpc/status.h>
#include <grpc/impl/codegen/alloc.h> #include <grpc/support/alloc.h>
#include <grpc_haskell.h> #include <grpc_haskell.h>
{#context prefix = "grpc" #} {#context prefix = "grpc" #}
@ -286,8 +287,8 @@ getPeerPeek cstr = do
`CompletionQueue',unTag `Tag'} `CompletionQueue',unTag `Tag'}
-> `CallError'#} -> `CallError'#}
{#fun unsafe call_details_get_method as ^ {`CallDetails'} -> `ByteString' packCString* #} {#fun unsafe call_details_get_method as ^ {`CallDetails'} -> `ByteString' sliceToByteString* #}
{#fun unsafe call_details_get_host as ^ {`CallDetails'} -> `ByteString' packCString* #} {#fun unsafe call_details_get_host as ^ {`CallDetails'} -> `ByteString' sliceToByteString* #}
{#fun call_details_get_deadline as ^ {`CallDetails'} -> `CTimeSpec' peek* #} {#fun call_details_get_deadline as ^ {`CallDetails'} -> `CTimeSpec' peek* #}

View file

@ -3,9 +3,9 @@
module Network.GRPC.Unsafe.ByteBuffer where module Network.GRPC.Unsafe.ByteBuffer where
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/impl/codegen/slice.h> #include <grpc/slice.h>
#include <grpc/impl/codegen/compression_types.h> #include <grpc/impl/codegen/compression_types.h>
#include <grpc/impl/codegen/slice_buffer.h> #include <grpc/slice_buffer.h>
#include <grpc_haskell.h> #include <grpc_haskell.h>

View file

@ -9,7 +9,7 @@ import Foreign.Storable
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/status.h> #include <grpc/status.h>
#include <grpc/impl/codegen/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/impl/codegen/compression_types.h> #include <grpc/impl/codegen/compression_types.h>
#include <grpc_haskell.h> #include <grpc_haskell.h>

View file

@ -4,11 +4,13 @@
module Network.GRPC.Unsafe.Metadata where module Network.GRPC.Unsafe.Metadata where
{#import Network.GRPC.Unsafe.Slice#}
import Control.Exception import Control.Exception
import Control.Monad import Control.Monad
import Data.Function (on) import Data.Function (on)
import Data.ByteString (ByteString, useAsCString, import Data.ByteString (ByteString, useAsCString,
useAsCStringLen, packCString, packCStringLen) useAsCStringLen)
import Data.List (sortBy, groupBy) import Data.List (sortBy, groupBy)
import qualified Data.SortedList as SL import qualified Data.SortedList as SL
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
@ -111,13 +113,10 @@ setMetadataKeyVal k v m i =
useAsCStringLen v $ \(vStr, vLen) -> setMetadataKeyVal' k vStr vLen m i useAsCStringLen v $ \(vStr, vLen) -> setMetadataKeyVal' k vStr vLen m i
{#fun unsafe get_metadata_key as getMetadataKey' {#fun unsafe get_metadata_key as getMetadataKey'
{`MetadataKeyValPtr', `Int'} -> `CString'#} {`MetadataKeyValPtr', `Int'} -> `Slice'#}
{#fun unsafe get_metadata_val as getMetadataVal' {#fun unsafe get_metadata_val as getMetadataVal'
{`MetadataKeyValPtr', `Int'} -> `CString'#} {`MetadataKeyValPtr', `Int'} -> `Slice'#}
{#fun unsafe get_metadata_val_len as getMetadataValLen
{`MetadataKeyValPtr', `Int'} -> `Int'#}
withMetadataArrayPtr :: (Ptr MetadataArray -> IO a) -> IO a withMetadataArrayPtr :: (Ptr MetadataArray -> IO a) -> IO a
withMetadataArrayPtr = bracket metadataArrayCreate metadataArrayDestroy withMetadataArrayPtr = bracket metadataArrayCreate metadataArrayDestroy
@ -126,12 +125,11 @@ withMetadataKeyValPtr :: Int -> (MetadataKeyValPtr -> IO a) -> IO a
withMetadataKeyValPtr i f = bracket (metadataAlloc i) metadataFree f withMetadataKeyValPtr i f = bracket (metadataAlloc i) metadataFree f
getMetadataKey :: MetadataKeyValPtr -> Int -> IO ByteString getMetadataKey :: MetadataKeyValPtr -> Int -> IO ByteString
getMetadataKey m = getMetadataKey' m >=> packCString getMetadataKey m = getMetadataKey' m >=> sliceToByteString
getMetadataVal :: MetadataKeyValPtr -> Int -> IO ByteString getMetadataVal :: MetadataKeyValPtr -> Int -> IO ByteString
getMetadataVal m i = do vStr <- getMetadataVal' m i getMetadataVal m i = do vStr <- getMetadataVal' m i
vLen <- getMetadataValLen m i sliceToByteString vStr
packCStringLen (vStr, vLen)
createMetadata :: MetadataMap -> IO (MetadataKeyValPtr, Int) createMetadata :: MetadataMap -> IO (MetadataKeyValPtr, Int)
createMetadata m = do createMetadata m = do

View file

@ -2,8 +2,9 @@
module Network.GRPC.Unsafe.Op where module Network.GRPC.Unsafe.Op where
{#import Network.GRPC.Unsafe.Slice#}
import Control.Exception import Control.Exception
import Foreign.C.String
import Foreign.C.Types import Foreign.C.Types
import Foreign.Ptr import Foreign.Ptr
{#import Network.GRPC.Unsafe.ByteBuffer#} {#import Network.GRPC.Unsafe.ByteBuffer#}
@ -90,7 +91,7 @@ withOpArray n f = bracket (opArrayCreate n) (flip opArrayDestroy n) f
-- this call. -- this call.
{#fun unsafe op_recv_status_client as ^ {#fun unsafe op_recv_status_client as ^
{`OpArray', `Int',id `Ptr MetadataArray', castPtr `Ptr StatusCode', {`OpArray', `Int',id `Ptr MetadataArray', castPtr `Ptr StatusCode',
castPtr `Ptr CString', `Int'} `Slice'}
-> `()'#} -> `()'#}
-- | Creates an op of type GRPC_OP_RECV_CLOSE_ON_SERVER at the specified index -- | Creates an op of type GRPC_OP_RECV_CLOSE_ON_SERVER at the specified index
@ -104,5 +105,5 @@ withOpArray n f = bracket (opArrayCreate n) (flip opArrayDestroy n) f
-- Metadata and string are copied when creating the op, and can be safely -- Metadata and string are copied when creating the op, and can be safely
-- destroyed immediately after calling this function. -- destroyed immediately after calling this function.
{#fun unsafe op_send_status_server as ^ {#fun unsafe op_send_status_server as ^
{`OpArray', `Int', `Int', `MetadataKeyValPtr', `StatusCode', `CString'} {`OpArray', `Int', `Int', `MetadataKeyValPtr', `StatusCode', `Slice'}
-> `()'#} -> `()'#}

View file

@ -2,7 +2,7 @@
module Network.GRPC.Unsafe.Slice where module Network.GRPC.Unsafe.Slice where
#include <grpc/impl/codegen/slice.h> #include <grpc/slice.h>
#include <grpc_haskell.h> #include <grpc_haskell.h>
import qualified Data.ByteString as B import qualified Data.ByteString as B
@ -12,12 +12,12 @@ import Foreign.Ptr
-- | A 'Slice' is gRPC's string type. We can easily convert these to and from -- | A 'Slice' is gRPC's string type. We can easily convert these to and from
-- ByteStrings. This type is a pointer to a C type. -- ByteStrings. This type is a pointer to a C type.
{#pointer *gpr_slice as Slice newtype #} {#pointer *grpc_slice as Slice newtype #}
deriving instance Show Slice deriving instance Show Slice
-- TODO: we could also represent this type as 'Ptr Slice', by doing this: -- TODO: we could also represent this type as 'Ptr Slice', by doing this:
-- newtype Slice = Slice {#type gpr_slice#} -- newtype Slice = Slice {#type grpc_slice#}
-- This would have no practical effect, but it would communicate intent more -- This would have no practical effect, but it would communicate intent more
-- clearly by emphasizing that the type is indeed a pointer and that the data -- clearly by emphasizing that the type is indeed a pointer and that the data
-- it is pointing to might change/be destroyed after running IO actions. To make -- it is pointing to might change/be destroyed after running IO actions. To make
@ -27,13 +27,18 @@ deriving instance Show Slice
-- maybe the established idiom is to do what c2hs does. -- maybe the established idiom is to do what c2hs does.
-- | Get the length of a slice. -- | Get the length of a slice.
{#fun unsafe gpr_slice_length_ as ^ {`Slice'} -> `CULong'#} {#fun unsafe grpc_slice_length_ as ^ {`Slice'} -> `CULong'#}
-- | Slices allocated using this function must be freed by
-- 'freeSlice'
{#fun unsafe grpc_slice_malloc_ as ^ {`Int'} -> `Slice'#}
-- | Returns a pointer to the start of the character array contained by the -- | Returns a pointer to the start of the character array contained by the
-- slice. -- slice.
{#fun unsafe gpr_slice_start_ as ^ {`Slice'} -> `Ptr CChar' castPtr #} {#fun unsafe grpc_slice_start_ as ^ {`Slice'} -> `Ptr CChar' castPtr #}
{#fun unsafe gpr_slice_from_copied_buffer_ as ^ {`CString', `Int'} -> `Slice'#} -- | Slices must be freed using 'freeSlice'.
{#fun unsafe grpc_slice_from_copied_buffer_ as ^ {`CString', `Int'} -> `Slice'#}
-- | Properly cleans up all memory used by a 'Slice'. Danger: the Slice should -- | Properly cleans up all memory used by a 'Slice'. Danger: the Slice should
-- not be used after this function is called on it. -- not be used after this function is called on it.
@ -46,10 +51,10 @@ deriving instance Show Slice
-- getting and freeing the slice behind the scenes. -- getting and freeing the slice behind the scenes.
sliceToByteString :: Slice -> IO B.ByteString sliceToByteString :: Slice -> IO B.ByteString
sliceToByteString slice = do sliceToByteString slice = do
len <- fmap fromIntegral $ gprSliceLength slice len <- fmap fromIntegral $ grpcSliceLength slice
str <- gprSliceStart slice str <- grpcSliceStart slice
B.packCStringLen (str, len) B.packCStringLen (str, len)
-- | Copies a 'ByteString' to a 'Slice'. -- | Copies a 'ByteString' to a 'Slice'.
byteStringToSlice :: B.ByteString -> IO Slice byteStringToSlice :: B.ByteString -> IO Slice
byteStringToSlice bs = B.useAsCStringLen bs $ uncurry gprSliceFromCopiedBuffer byteStringToSlice bs = B.useAsCStringLen bs $ uncurry grpcSliceFromCopiedBuffer