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
121 changes: 22 additions & 99 deletions src/Streaming.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,48 +115,27 @@ Start a client streaming gRPC request (multiple requests, single response).
```julia
using gRPCClient

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

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

# ============================================================================
# Step 3: Create a Client for Your Streaming RPC Method
# ============================================================================
# Step 3: Create a client
client = TestService_TestClientStreamRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Create a Request Channel and Send Requests
# ============================================================================
# The channel buffers requests that will be streamed to the server.
# Buffer size of 16 means up to 16 requests can be queued.
# Step 4: Create a request channel and send requests
request_c = Channel{TestRequest}(16)

# Send one or more requests through the channel
put!(request_c, TestRequest(1, zeros(UInt64, 1)))

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

# ============================================================================
# Step 6: Close the Request Channel When Done
# ============================================================================
# IMPORTANT: You must close the channel to signal that no more requests
# will be sent. The server won't send the response until the stream ends.
# Step 6: 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
# ============================================================================
# After all requests are sent and processed, the server returns one response.
# Step 7: Wait for the single response
test_response = grpc_async_await(client, req)
```
"""
Expand Down Expand Up @@ -196,52 +175,27 @@ Start a server streaming gRPC request (single request, multiple responses).
```julia
using gRPCClient

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

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

# ============================================================================
# Step 3: Create a Client for Your Streaming RPC Method
# ============================================================================
# Step 3: Create a client
client = TestService_TestServerStreamRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Create a Response Channel
# ============================================================================
# The channel will receive multiple responses from the server.
# Buffer size of 16 means up to 16 responses can be queued.
# Step 4: Create a response channel to receive multiple responses
response_c = Channel{TestResponse}(16)

# ============================================================================
# Step 5: Initiate the Streaming Request
# ============================================================================
# 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
# ============================================================================
# Read responses from the channel as they arrive. The channel will be closed
# when the server finishes sending all responses.
# Step 5: 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)
for test_response in response_c
@info test_response
end

# ============================================================================
# Step 7: Check for Exceptions
# ============================================================================
# Call grpc_async_await to raise any exceptions that occurred during the request.
# Step 7: Check for exceptions
grpc_async_await(req)
```
"""
Expand Down Expand Up @@ -288,64 +242,33 @@ Start a bidirectional streaming gRPC request (multiple requests, multiple respon
```julia
using gRPCClient

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

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

# ============================================================================
# Step 3: Create a Client for Your Streaming RPC Method
# ============================================================================
# Step 3: Create a client
client = TestService_TestBidirectionalStreamRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Create Request and Response Channels
# ============================================================================
# Both channels allow streaming in both directions simultaneously.
# Buffer size of 16 means up to 16 messages can be queued in each direction.
# Step 4: 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 5: Initiate the bidirectional streaming request
req = grpc_async_request(client, request_c, response_c)

# ============================================================================
# Step 6: Send Requests and Receive Responses Concurrently
# ============================================================================
# In bidirectional streaming, you can send and receive at the same time.
# This example shows a simple pattern, but you can use tasks for more
# complex concurrent communication patterns.

# Send a request
# Step 6: Send requests and receive responses concurrently
put!(request_c, TestRequest(1, zeros(UInt64, 1)))

# Receive responses as they arrive
for test_response in response_c
@info test_response
# Optionally send more requests based on responses
# put!(request_c, ...)
break # Exit after first response for this example
end

# ============================================================================
# Step 7: Close the Request Channel When Done
# ============================================================================
# IMPORTANT: You must close the request channel to signal that no more
# requests will be sent.
# Step 7: Close the request channel to signal no more requests will be sent
close(request_c)

# ============================================================================
# Step 8: Check for Exceptions
# ============================================================================
# Call grpc_async_await to raise any exceptions that occurred during the request.
# Step 8: Check for exceptions
grpc_async_await(req)
```
"""
Expand Down
88 changes: 14 additions & 74 deletions src/Unary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,23 @@ This is ideal when you need to send many requests in parallel and waiting on eac
```julia
using gRPCClient

# ============================================================================
# Step 1: Initialize gRPC
# ============================================================================
# This must be called once before making any gRPC requests.
# It initializes the underlying libcurl multi handle and other resources.
# Step 1: Initialize gRPC (must be called once before making any gRPC requests)
grpc_init()

# ============================================================================
# Step 2: Include Generated Protocol Buffer Bindings
# ============================================================================
# These bindings define the message types (e.g., TestRequest, TestResponse)
# and client stubs for your gRPC service. They are generated from .proto files.
# Step 2: Include generated Protocol Buffer bindings
include("test/gen/test/test_pb.jl")

# ============================================================================
# Step 3: Create a Client for Your RPC Method
# ============================================================================
# The client is bound to a specific RPC method on your gRPC service.
# Arguments: hostname, port
# Step 3: Create a client for your RPC method (hostname, port)
client = TestService_TestRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Send Multiple Async Requests
# ============================================================================
# Use grpc_async_request when you want to send requests without blocking.
# This is useful for sending many requests in parallel.

# Send all requests without waiting for responses
# Step 4: Send all requests without waiting for responses
requests = Vector{gRPCRequest}()
for i in 1:10
# Each request is sent immediately and returns a gRPCRequest handle
push!(
requests,
grpc_async_request(client, TestRequest(1, zeros(UInt64, 1)))
)
push!(requests, grpc_async_request(client, TestRequest(1, zeros(UInt64, 1))))
end

# ============================================================================
# Step 5: Wait for and Process Responses
# ============================================================================
# Use grpc_async_await to retrieve the response when you need it.
# Step 5: Wait for and process responses
for request in requests
# This blocks until the specific request completes
response = grpc_async_await(client, request)
@info response
end
Expand Down Expand Up @@ -105,51 +79,28 @@ This has the advantage over the request / await patern in that you can handle re
```julia
using gRPCClient

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

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

# ============================================================================
# Step 3: Create a Client for Your RPC Method
# ============================================================================
# Step 3: Create a client
client = TestService_TestRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Create a Channel to Receive Responses
# ============================================================================
# Use the channel-based pattern when you want to process responses as soon
# as they arrive, regardless of the order they were sent.
# Step 4: 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 parameter allows you to track which request each response
# corresponds to, since responses may arrive out of order.
# Step 5: 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
# ============================================================================
# Responses are pushed to the channel as they complete. You can process
# them immediately without waiting for all requests to finish first.
# Step 6: Process responses as they arrive
for i in 1:N
cr = take!(channel)

# Check if an exception was thrown during the request
!isnothing(cr.ex) && throw(cr.ex)

# Use the index to match responses to requests
@assert length(cr.response.data) == cr.index
end
```
Expand Down Expand Up @@ -218,27 +169,16 @@ Use this when you want the simplest possible interface for a single request.
```julia
using gRPCClient

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

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

# ============================================================================
# Step 3: Create a Client for Your RPC Method
# ============================================================================
# Step 3: Create a client
client = TestService_TestRPC_Client("localhost", 8001)

# ============================================================================
# Step 4: Make a Synchronous Request
# ============================================================================
# This blocks until the response is ready. It's the simplest way to make
# a single gRPC request when you don't need parallelism.
# Step 4: Make a synchronous request (blocks until response is ready)
response = grpc_sync_request(client, TestRequest(1, zeros(UInt64, 1)))
@info response
```
Expand Down
Loading