Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ gRPCClient.jl integrates with ProtoBuf.jl to automatically generate Julia client
using ProtoBuf
using gRPCClient

# Register our service codegen with ProtoBuf.jl
grpc_register_service_codegen()

# Creates Julia bindings for the messages and RPC defined in test.proto
protojl("test/proto/test.proto", ".", "test/gen")
```
Expand Down
2 changes: 1 addition & 1 deletion src/Curl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ mutable struct gRPCCURL
finalizer((x) -> close(x), grpc)

# This is used for the global const gRPCCURL handle
# The user is expected to call grpc_init() in order to use it
# grpc_init() is called automatically via __init__() when the package is loaded
!running && return grpc

open(grpc)
Expand Down
47 changes: 19 additions & 28 deletions src/Streaming.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,27 +115,24 @@ Start a client streaming gRPC request (multiple requests, single response).
```julia
using gRPCClient

# Step 1: Initialize gRPC
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client
# Step 2: Create a client
client = TestService_TestClientStreamRPC_Client("localhost", 8001)

# Step 4: Create a request channel and send requests
# Step 3: Create a request channel and send requests
request_c = Channel{TestRequest}(16)
put!(request_c, TestRequest(1, zeros(UInt64, 1)))

# Step 5: Initiate the streaming request
# Step 4: Initiate the streaming request
req = grpc_async_request(client, request_c)

# Step 6: Close the channel to signal no more requests will be sent
# Step 5: Close the channel to signal no more requests will be sent
# (the server won't respond until the stream ends)
close(request_c)

# Step 7: Wait for the single response
# Step 6: Wait for the single response
test_response = grpc_async_await(client, req)
```
"""
Expand Down Expand Up @@ -175,27 +172,24 @@ Start a server streaming gRPC request (single request, multiple responses).
```julia
using gRPCClient

# Step 1: Initialize gRPC
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client
# Step 2: Create a client
client = TestService_TestServerStreamRPC_Client("localhost", 8001)

# Step 4: Create a response channel to receive multiple responses
# Step 3: Create a response channel to receive multiple responses
response_c = Channel{TestResponse}(16)

# Step 5: Send a single request (the server will respond with multiple messages)
# Step 4: Send a single request (the server will respond with multiple messages)
req = grpc_async_request(client, TestRequest(1, zeros(UInt64, 1)), response_c)

# Step 6: Process streaming responses (channel closes when server finishes)
# Step 5: Process streaming responses (channel closes when server finishes)
for test_response in response_c
@info test_response
end

# Step 7: Check for exceptions
# Step 6: Check for exceptions
grpc_async_await(req)
```
"""
Expand Down Expand Up @@ -242,33 +236,30 @@ Start a bidirectional streaming gRPC request (multiple requests, multiple respon
```julia
using gRPCClient

# Step 1: Initialize gRPC
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client
# Step 2: Create a client
client = TestService_TestBidirectionalStreamRPC_Client("localhost", 8001)

# Step 4: Create request and response channels (streaming in both directions simultaneously)
# Step 3: Create request and response channels (streaming in both directions simultaneously)
request_c = Channel{TestRequest}(16)
response_c = Channel{TestResponse}(16)

# Step 5: Initiate the bidirectional streaming request
# Step 4: Initiate the bidirectional streaming request
req = grpc_async_request(client, request_c, response_c)

# Step 6: Send requests and receive responses concurrently
# Step 5: Send requests and receive responses concurrently
put!(request_c, TestRequest(1, zeros(UInt64, 1)))
for test_response in response_c
@info test_response
break # Exit after first response for this example
end

# Step 7: Close the request channel to signal no more requests will be sent
# Step 6: Close the request channel to signal no more requests will be sent
close(request_c)

# Step 8: Check for exceptions
# Step 7: Check for exceptions
grpc_async_await(req)
```
"""
Expand Down
33 changes: 12 additions & 21 deletions src/Unary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,19 @@ This is ideal when you need to send many requests in parallel and waiting on eac
```julia
using gRPCClient

# Step 1: Initialize gRPC (must be called once before making any gRPC requests)
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client for your RPC method (hostname, port)
# Step 2: Create a client for your RPC method (hostname, port)
client = TestService_TestRPC_Client("localhost", 8001)

# Step 4: Send all requests without waiting for responses
# Step 3: Send all requests without waiting for responses
requests = Vector{gRPCRequest}()
for i in 1:10
push!(requests, grpc_async_request(client, TestRequest(1, zeros(UInt64, 1))))
end

# Step 5: Wait for and process responses
# Step 4: Wait for and process responses
for request in requests
response = grpc_async_await(client, request)
@info response
Expand Down Expand Up @@ -79,25 +76,22 @@ This has the advantage over the request / await patern in that you can handle re
```julia
using gRPCClient

# Step 1: Initialize gRPC
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client
# Step 2: Create a client
client = TestService_TestRPC_Client("localhost", 8001)

# Step 4: Create a channel to receive responses (processes responses as they arrive, in any order)
# Step 3: Create a channel to receive responses (processes responses as they arrive, in any order)
N = 10
channel = Channel{gRPCAsyncChannelResponse{TestResponse}}(N)

# Step 5: Send all requests (the index tracks which response corresponds to which request)
# Step 4: Send all requests (the index tracks which response corresponds to which request)
for (index, request) in enumerate([TestRequest(i, zeros(UInt64, i)) for i in 1:N])
grpc_async_request(client, request, channel, index)
end

# Step 6: Process responses as they arrive
# Step 5: Process responses as they arrive
for i in 1:N
cr = take!(channel)
!isnothing(cr.ex) && throw(cr.ex)
Expand Down Expand Up @@ -169,16 +163,13 @@ Use this when you want the simplest possible interface for a single request.
```julia
using gRPCClient

# Step 1: Initialize gRPC
grpc_init()

# Step 2: Include generated Protocol Buffer bindings
# Step 1: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# Step 3: Create a client
# Step 2: Create a client
client = TestService_TestRPC_Client("localhost", 8001)

# Step 4: Make a synchronous request (blocks until response is ready)
# Step 3: Make a synchronous request (blocks until response is ready)
response = grpc_sync_request(client, TestRequest(1, zeros(UInt64, 1)))
@info response
```
Expand Down
17 changes: 3 additions & 14 deletions src/gRPC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,17 @@ grpc_global_handle() = _grpc
"""
grpc_init([grpc_curl::gRPCCURL])

Initializes the `gRPCCURL` object. This should be called once before making gRPC calls. There is no harm in calling this more than once (ie by different packages/dependencies). Typical usage looks like this:

```julia
grpc_init()

client = TestService_TestRPC_Client("172.238.177.88", 8001)

# Make some gRPC calls

# Shut down the global gRPC handle
grpc_shutdown()
```
Initializes the `gRPCCURL` object. The global handle is initialized automatically when the package is loaded. There is no harm in calling this more than once (ie by different packages/dependencies).

Unless specifying a `gRPCCURL` the global one provided by `grpc_global_handle()` is used. Each `gRPCCURL` state has its own connection pool and request semaphore, so sometimes you may want to manage your own like shown below:

```julia
```julia
grpc_myapp = gRPCCURL()
grpc_init(grpc_myapp)

client = TestService_TestRPC_Client("172.238.177.88", 8001; grpc=grpc_myapp)

# Make some gRPC calls
# Make some gRPC calls

# Only shuts down your gRPC handle
grpc_shutdown(grpc_myapp)
Expand Down
5 changes: 5 additions & 0 deletions src/gRPCClient.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,9 @@ export gRPCAsyncChannelResponse
export gRPCException
export gRPCServiceCallException

function __init__()
grpc_init()
grpc_register_service_codegen()
end

end