mirror of
https://github.com/unclechu/gRPC-haskell.git
synced 2024-11-26 21:19:43 +01:00
Upgrade to gRPC 1.22 (#85)
This commit is contained in:
parent
35163c3c18
commit
5ceeae74cc
10 changed files with 73 additions and 58 deletions
|
@ -500,10 +500,10 @@ grpc_channel_credentials* grpc_ssl_credentials_create_internal(
|
||||||
grpc_channel_credentials* creds;
|
grpc_channel_credentials* creds;
|
||||||
if(pem_key && pem_cert){
|
if(pem_key && pem_cert){
|
||||||
grpc_ssl_pem_key_cert_pair pair = {pem_key, pem_cert};
|
grpc_ssl_pem_key_cert_pair pair = {pem_key, pem_cert};
|
||||||
creds = grpc_ssl_credentials_create(pem_root_certs, &pair, NULL);
|
creds = grpc_ssl_credentials_create(pem_root_certs, &pair, NULL, NULL);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
creds = grpc_ssl_credentials_create(pem_root_certs, NULL, NULL);
|
creds = grpc_ssl_credentials_create(pem_root_certs, NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
return creds;
|
return creds;
|
||||||
}
|
}
|
||||||
|
@ -537,10 +537,16 @@ grpc_call_credentials* grpc_metadata_credentials_create_from_plugin_(
|
||||||
//This callback is registered as the get_metadata callback for the call, and its
|
//This callback is registered as the get_metadata callback for the call, and its
|
||||||
//only job is to cast the void* state pointer to the correct function pointer
|
//only job is to cast the void* state pointer to the correct function pointer
|
||||||
//type and call the Haskell function with it.
|
//type and call the Haskell function with it.
|
||||||
void metadata_dispatcher(void *state, grpc_auth_metadata_context context,
|
int metadata_dispatcher(void *state,
|
||||||
grpc_credentials_plugin_metadata_cb cb, void *user_data){
|
grpc_auth_metadata_context context,
|
||||||
|
grpc_credentials_plugin_metadata_cb cb,
|
||||||
|
void *user_data,
|
||||||
|
grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX],
|
||||||
|
size_t *num_creds_md,
|
||||||
|
grpc_status_code *status,
|
||||||
|
const char ** error_details) {
|
||||||
((haskell_get_metadata*)state)(&context, cb, user_data);
|
((haskell_get_metadata*)state)(&context, cb, user_data);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpc_metadata_credentials_plugin* mk_metadata_client_plugin(
|
grpc_metadata_credentials_plugin* mk_metadata_client_plugin(
|
||||||
|
|
|
@ -53,7 +53,8 @@ library
|
||||||
Network.GRPC.LowLevel.Call.Unregistered
|
Network.GRPC.LowLevel.Call.Unregistered
|
||||||
Network.GRPC.LowLevel.Client
|
Network.GRPC.LowLevel.Client
|
||||||
extra-libraries:
|
extra-libraries:
|
||||||
grpc
|
grpc
|
||||||
|
, gpr
|
||||||
includes:
|
includes:
|
||||||
include/grpc_haskell.h
|
include/grpc_haskell.h
|
||||||
, grpc/grpc.h
|
, grpc/grpc.h
|
||||||
|
|
|
@ -20,7 +20,6 @@ import Control.Exception (bracket)
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
import Data.ByteString.Char8 (pack)
|
import Data.ByteString.Char8 (pack)
|
||||||
import Data.List (intersperse)
|
import Data.List (intersperse)
|
||||||
import Data.Semigroup ((<>))
|
|
||||||
import Data.String (IsString)
|
import Data.String (IsString)
|
||||||
import Foreign.Marshal.Alloc (free, malloc)
|
import Foreign.Marshal.Alloc (free, malloc)
|
||||||
import Foreign.Ptr (Ptr, nullPtr)
|
import Foreign.Ptr (Ptr, nullPtr)
|
||||||
|
@ -31,6 +30,7 @@ import Network.GRPC.LowLevel.GRPC (MetadataMap,
|
||||||
import qualified Network.GRPC.Unsafe as C
|
import qualified Network.GRPC.Unsafe as C
|
||||||
import qualified Network.GRPC.Unsafe.ByteBuffer as C
|
import qualified Network.GRPC.Unsafe.ByteBuffer as C
|
||||||
import qualified Network.GRPC.Unsafe.Op as C
|
import qualified Network.GRPC.Unsafe.Op as C
|
||||||
|
import qualified Network.GRPC.Unsafe.Time as C
|
||||||
import System.Clock
|
import System.Clock
|
||||||
|
|
||||||
-- | Models the four types of RPC call supported by gRPC (and correspond to
|
-- | Models the four types of RPC call supported by gRPC (and correspond to
|
||||||
|
@ -181,7 +181,7 @@ mgdPtr = managed (bracket malloc free)
|
||||||
|
|
||||||
serverCallIsExpired :: ServerCall a -> IO Bool
|
serverCallIsExpired :: ServerCall a -> IO Bool
|
||||||
serverCallIsExpired sc = do
|
serverCallIsExpired sc = do
|
||||||
currTime <- getTime Monotonic
|
C.CTimeSpec currTime <- bracket (C.gprNow C.GprClockMonotonic) C.timespecDestroy peek
|
||||||
return $ currTime > (callDeadline sc)
|
return $ currTime > (callDeadline sc)
|
||||||
|
|
||||||
debugClientCall :: ClientCall -> IO ()
|
debugClientCall :: ClientCall -> IO ()
|
||||||
|
@ -209,11 +209,11 @@ debugServerCall = const $ return ()
|
||||||
destroyClientCall :: ClientCall -> IO ()
|
destroyClientCall :: ClientCall -> IO ()
|
||||||
destroyClientCall cc = do
|
destroyClientCall cc = do
|
||||||
grpcDebug "Destroying client-side call object."
|
grpcDebug "Destroying client-side call object."
|
||||||
C.grpcCallDestroy (unsafeCC cc)
|
C.grpcCallUnref (unsafeCC cc)
|
||||||
|
|
||||||
destroyServerCall :: ServerCall a -> IO ()
|
destroyServerCall :: ServerCall a -> IO ()
|
||||||
destroyServerCall sc@ServerCall{ unsafeSC = c, .. } = do
|
destroyServerCall sc@ServerCall{ unsafeSC = c, .. } = do
|
||||||
grpcDebug "destroyServerCall(R): entered."
|
grpcDebug "destroyServerCall(R): entered."
|
||||||
debugServerCall sc
|
debugServerCall sc
|
||||||
grpcDebug $ "Destroying server-side call object: " ++ show c
|
grpcDebug $ "Destroying server-side call object: " ++ show c
|
||||||
C.grpcCallDestroy c
|
C.grpcCallUnref c
|
||||||
|
|
|
@ -51,4 +51,4 @@ destroyServerCall call@ServerCall{..} = do
|
||||||
grpcDebug "destroyServerCall(U): entered."
|
grpcDebug "destroyServerCall(U): entered."
|
||||||
debugServerCall call
|
debugServerCall call
|
||||||
grpcDebug $ "Destroying server-side call object: " ++ show unsafeSC
|
grpcDebug $ "Destroying server-side call object: " ++ show unsafeSC
|
||||||
C.grpcCallDestroy unsafeSC
|
C.grpcCallUnref unsafeSC
|
||||||
|
|
|
@ -52,9 +52,6 @@ import qualified Network.GRPC.Unsafe.Constants 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.Time as C
|
import qualified Network.GRPC.Unsafe.Time as C
|
||||||
import System.Clock (Clock (..),
|
|
||||||
getTime)
|
|
||||||
import System.Info (os)
|
|
||||||
|
|
||||||
withCompletionQueue :: GRPC -> (CompletionQueue -> IO a) -> IO a
|
withCompletionQueue :: GRPC -> (CompletionQueue -> IO a) -> IO a
|
||||||
withCompletionQueue grpc = bracket (createCompletionQueue grpc)
|
withCompletionQueue grpc = bracket (createCompletionQueue grpc)
|
||||||
|
@ -62,7 +59,7 @@ withCompletionQueue grpc = bracket (createCompletionQueue grpc)
|
||||||
|
|
||||||
createCompletionQueue :: GRPC -> IO CompletionQueue
|
createCompletionQueue :: GRPC -> IO CompletionQueue
|
||||||
createCompletionQueue _ = do
|
createCompletionQueue _ = do
|
||||||
unsafeCQ <- C.grpcCompletionQueueCreate C.reserved
|
unsafeCQ <- C.grpcCompletionQueueCreateForPluck C.reserved
|
||||||
currentPluckers <- newTVarIO 0
|
currentPluckers <- newTVarIO 0
|
||||||
currentPushers <- newTVarIO 0
|
currentPushers <- newTVarIO 0
|
||||||
shuttingDown <- newTVarIO False
|
shuttingDown <- newTVarIO False
|
||||||
|
@ -142,11 +139,7 @@ serverRequestCall rm s scq ccq =
|
||||||
<*> mgdPayload (methodType rm)
|
<*> mgdPayload (methodType rm)
|
||||||
<*> managed C.withMetadataArrayPtr
|
<*> managed C.withMetadataArrayPtr
|
||||||
dbug = grpcDebug . ("serverRequestCall(R): " ++)
|
dbug = grpcDebug . ("serverRequestCall(R): " ++)
|
||||||
-- On OS X, gRPC gives us a deadline that is just a delta, so we convert
|
convertDeadline timeSpecPtr = C.timeSpec <$> peek timeSpecPtr
|
||||||
-- it to an actual deadline.
|
|
||||||
convertDeadline (fmap C.timeSpec . peek -> d)
|
|
||||||
| os == "darwin" = (+) <$> d <*> getTime Monotonic
|
|
||||||
| otherwise = d
|
|
||||||
|
|
||||||
-- | Register the server's completion queue. Must be done before the server is
|
-- | Register the server's completion queue. Must be done before the server is
|
||||||
-- started.
|
-- started.
|
||||||
|
|
|
@ -167,7 +167,7 @@ shutdownCompletionQueue CompletionQueue{..} = do
|
||||||
drainLoop = do
|
drainLoop = do
|
||||||
grpcDebug "drainLoop: before next() call"
|
grpcDebug "drainLoop: before next() call"
|
||||||
ev <- C.withDeadlineSeconds 1 $ \deadline ->
|
ev <- C.withDeadlineSeconds 1 $ \deadline ->
|
||||||
C.grpcCompletionQueueNext unsafeCQ deadline C.reserved
|
C.grpcCompletionQueuePluck unsafeCQ C.noTag deadline C.reserved
|
||||||
grpcDebug $ "drainLoop: next() call got " ++ show ev
|
grpcDebug $ "drainLoop: next() call got " ++ show ev
|
||||||
case C.eventCompletionType ev of
|
case C.eventCompletionType ev of
|
||||||
C.QueueShutdown -> return ()
|
C.QueueShutdown -> return ()
|
||||||
|
|
|
@ -78,6 +78,9 @@ newtype Tag = Tag {unTag :: Ptr ()} deriving (Show, Eq)
|
||||||
tag :: Int -> Tag
|
tag :: Int -> Tag
|
||||||
tag = Tag . plusPtr nullPtr
|
tag = Tag . plusPtr nullPtr
|
||||||
|
|
||||||
|
noTag :: Tag
|
||||||
|
noTag = Tag nullPtr
|
||||||
|
|
||||||
instance Storable Tag where
|
instance Storable Tag where
|
||||||
sizeOf (Tag p) = sizeOf p
|
sizeOf (Tag p) = sizeOf p
|
||||||
alignment (Tag p) = alignment p
|
alignment (Tag p) = alignment p
|
||||||
|
@ -139,11 +142,18 @@ castPeek p = do
|
||||||
|
|
||||||
{#fun grpc_shutdown as ^ {} -> `()'#}
|
{#fun grpc_shutdown as ^ {} -> `()'#}
|
||||||
|
|
||||||
|
{#fun grpc_shutdown_blocking as ^ {} -> `()'#}
|
||||||
|
|
||||||
{#fun grpc_version_string as ^ {} -> `String' #}
|
{#fun grpc_version_string as ^ {} -> `String' #}
|
||||||
|
|
||||||
-- | Create a new 'CompletionQueue'. See the docs for
|
-- | Create a new 'CompletionQueue' for GRPC_CQ_NEXT. See the docs for
|
||||||
-- 'grpcCompletionQueueShutdown' for instructions on how to clean up afterwards.
|
-- 'grpcCompletionQueueShutdown' for instructions on how to clean up afterwards.
|
||||||
{#fun grpc_completion_queue_create as ^
|
{#fun grpc_completion_queue_create_for_next as ^
|
||||||
|
{unReserved `Reserved'} -> `CompletionQueue'#}
|
||||||
|
|
||||||
|
-- | Create a new 'CompletionQueue' for GRPC_CQ_PLUCK. See the docs for
|
||||||
|
-- 'grpcCompletionQueueShutdown' for instructions on how to clean up afterwards.
|
||||||
|
{#fun grpc_completion_queue_create_for_pluck as ^
|
||||||
{unReserved `Reserved'} -> `CompletionQueue'#}
|
{unReserved `Reserved'} -> `CompletionQueue'#}
|
||||||
|
|
||||||
-- | Block until we get the next event off the given 'CompletionQueue',
|
-- | Block until we get the next event off the given 'CompletionQueue',
|
||||||
|
@ -226,7 +236,9 @@ castPeek p = do
|
||||||
{#fun grpc_call_cancel_with_status as ^
|
{#fun grpc_call_cancel_with_status as ^
|
||||||
{`Call', `StatusCode', `String',unReserved `Reserved'} -> `()'#}
|
{`Call', `StatusCode', `String',unReserved `Reserved'} -> `()'#}
|
||||||
|
|
||||||
{#fun grpc_call_destroy as ^ {`Call'} -> `()'#}
|
{#fun grpc_call_ref as ^ {`Call'} -> `()'#}
|
||||||
|
|
||||||
|
{#fun grpc_call_unref as ^ {`Call'} -> `()'#}
|
||||||
|
|
||||||
-- | Gets the peer of the current call as a string.
|
-- | Gets the peer of the current call as a string.
|
||||||
{#fun grpc_call_get_peer as ^ {`Call'} -> `String' getPeerPeek* #}
|
{#fun grpc_call_get_peer as ^ {`Call'} -> `String' getPeerPeek* #}
|
||||||
|
|
|
@ -802,7 +802,7 @@ testClientMaxReceiveMessageLengthChannelArg = do
|
||||||
-- Expect failure when the max recv payload size is set to 3 bytes, and we
|
-- Expect failure when the max recv payload size is set to 3 bytes, and we
|
||||||
-- are sent 4.
|
-- are sent 4.
|
||||||
shouldFail = clientMax 3 $ \case
|
shouldFail = clientMax 3 $ \case
|
||||||
Left (GRPCIOBadStatusCode StatusInvalidArgument _)
|
Left (GRPCIOBadStatusCode StatusResourceExhausted _)
|
||||||
-> pure ()
|
-> pure ()
|
||||||
rsp
|
rsp
|
||||||
-> clientFail ("Expected failure response, but got: " ++ show rsp)
|
-> clientFail ("Expected failure response, but got: " ++ show rsp)
|
||||||
|
|
|
@ -197,7 +197,7 @@ assertCqEventComplete e = do
|
||||||
eventSuccess e HU.@?= True
|
eventSuccess e HU.@?= True
|
||||||
|
|
||||||
grpc :: IO a -> IO ()
|
grpc :: IO a -> IO ()
|
||||||
grpc = bracket_ grpcInit grpcShutdown . void
|
grpc = bracket_ grpcInit grpcShutdownBlocking . void
|
||||||
|
|
||||||
_nowarnUnused :: a
|
_nowarnUnused :: a
|
||||||
_nowarnUnused = assertCqEventComplete `undefined` threadDelaySecs
|
_nowarnUnused = assertCqEventComplete `undefined` threadDelaySecs
|
||||||
|
|
67
nix/grpc.nix
67
nix/grpc.nix
|
@ -1,42 +1,45 @@
|
||||||
{ darwin, stdenv, lib, fetchgit, fixDarwinDylibNames, autoconf, automake, libtool, which, zlib
|
{ stdenv, fetchFromGitHub, cmake, zlib, c-ares, pkgconfig, openssl, protobuf, gflags }:
|
||||||
, openssl
|
|
||||||
}:
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "grpc-${version}";
|
version = "1.22.1";
|
||||||
version = "1.2.0-${lib.strings.substring 0 7 rev}";
|
name = "grpc-${version}";
|
||||||
rev = "e2cfe9df79c4eda4e376222df064c4c65e616352";
|
src = fetchFromGitHub {
|
||||||
src = fetchgit {
|
owner = "grpc";
|
||||||
inherit rev;
|
repo = "grpc";
|
||||||
url = "https://github.com/grpc/grpc.git";
|
rev = "v${version}";
|
||||||
sha256 = "19ldbjlnbc287hkaylsigm8w9fai2bjdbfxk6315kl75cq54iprr";
|
sha256 = "1ci3v8xrr8iy65ixx2j0aw1i7cmmrm6pll1dnnbvndmjq573qiyk";
|
||||||
};
|
};
|
||||||
|
nativeBuildInputs = [ cmake pkgconfig ];
|
||||||
|
buildInputs = [ zlib c-ares c-ares.cmake-config openssl protobuf gflags ];
|
||||||
|
|
||||||
NIX_CFLAGS_COMPILE = "-Wno-error";
|
cmakeFlags =
|
||||||
|
[ "-DgRPC_ZLIB_PROVIDER=package"
|
||||||
|
"-DgRPC_CARES_PROVIDER=package"
|
||||||
|
"-DgRPC_SSL_PROVIDER=package"
|
||||||
|
"-DgRPC_PROTOBUF_PROVIDER=package"
|
||||||
|
"-DgRPC_GFLAGS_PROVIDER=package"
|
||||||
|
"-DBUILD_SHARED_LIBS=ON"
|
||||||
|
"-DCMAKE_SKIP_BUILD_RPATH=OFF"
|
||||||
|
];
|
||||||
|
|
||||||
# `grpc`'s `Makefile` does some magic to detect the correct `ld` and `strip`
|
# CMake creates a build directory by default, this conflicts with the
|
||||||
# to use along with their flags, too. If Nix supplies `$LD` and `$STRIP` then
|
# basel BUILD file on case-insensitive filesystems.
|
||||||
# this auto-detection fails and the build fails, which is why we unset the
|
preConfigure = ''
|
||||||
# environment variables here and let the `Makefile` set them.
|
rm -vf BUILD
|
||||||
preBuild = ''
|
|
||||||
unset LD
|
|
||||||
unset STRIP
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
preInstall = "export prefix";
|
preBuild = ''
|
||||||
|
export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
|
||||||
|
'';
|
||||||
|
|
||||||
buildInputs = [
|
NIX_CFLAGS_COMPILE = stdenv.lib.optionalString stdenv.cc.isClang "-Wno-error=unknown-warning-option";
|
||||||
autoconf
|
|
||||||
automake
|
|
||||||
libtool
|
|
||||||
which
|
|
||||||
zlib
|
|
||||||
openssl
|
|
||||||
] ++ stdenv.lib.optional stdenv.isDarwin fixDarwinDylibNames;
|
|
||||||
|
|
||||||
# Some versions of `ar` (such as the one provided by OS X) require an explicit
|
enableParallelBuilds = true;
|
||||||
# `-r` flag, whereas other versions assume `-r` is the default if no mode is
|
|
||||||
# specified. For example, OS X requires the `-r` flag, so as a precaution we
|
meta = with stdenv.lib; {
|
||||||
# always specify the flag.
|
description = "The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)";
|
||||||
AROPTS = "-r";
|
license = licenses.asl20;
|
||||||
|
maintainers = [ maintainers.lnl7 ];
|
||||||
|
homepage = https://grpc.io/;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue