The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
\dontrun{}: each one drives a client and a server in the
same process over the loopback interface. grpc_tls() keeps
a \dontrun{} example because it needs certificate
files.grpc to rgrpc before the
first release: the bare name is a search token owned by the upstream
project, and a unique name keeps this package’s docs and issues
findable. Exported functions keep their grpc_* names.grpc_fd().
Runs on Linux, Windows (Rtools >= 4.3), and macOS. The 0.0.1.x
entries below record the development history.src/wake.h replaces it with the same contract everywhere –
a self-pipe on Unix, a loopback socket pair on Windows, readable exactly
while events are queued. Windows links the gRPC that Rtools >= 4.3
bundles, through a static Makevars.win, and
OS_type: unix left DESCRIPTION. CI gains a macOS leg
building against Homebrew’s gRPC.grpc_await() now works on a server
"grpc_request" too, closing the asymmetry 0.0.1.11 left
behind: the docs said “one queue serves the whole client or
server” while the remedy shipped for the client only, so a server
driving concurrent streaming calls still hand-rolled the id
dispatch that had already gone wrong five times downstream. A handler
can drain one client-streaming call with
grpc_await(req, timeout_ms) and see nothing belonging to
any other.grpc_await() became an S3 generic to accommodate that
third class. Call sites are unaffected: the signature is unchanged and
the existing "grpc_call" and "grpc_stream"
behaviour is identical."stream_msg", "client_done",
"stream_writable", "cancelled"), since the
request arrives from grpc_poll() in the first place. A
server call has no terminal event of its own – it ends when the handler
ends it – so "client_done" is what a client-streaming
handler loops to.grpc_await(x, timeout_ms): waits for events
belonging to one call or stream. Other calls’ events are stepped over
and left queued in arrival order, and the wait ends only when a matching
event arrives. This is the demultiplexing every other gRPC binding does
for you – Python hands back a per-call future or response iterator and
never exposes a completion queue – and its absence is what made the
attribution mistakes in 0.0.1.10 possible in the first place. Use it for
sequential code; use grpc_poll() and dispatch on
id when calls really are concurrent, since awaiting one
call means not looking at the others.grpc_await() leaves the call exactly as it
was: await it again to keep waiting. That resumability is what keeps a
required timeout_ms from being the empty-batch trap in new
clothing, so it is now stated rather than implied, along with which
clock is which (deadline_ms bounds the RPC,
timeout_ms bounds one wait). Examples check the batch
before indexing it: on a slow peer
grpc_await(call, timeout_ms = 1000)[[1]] raises
subscript out of bounds, which reads like a caller bug
rather than the timeout it is.inst/examples/cri-list-pods.R,
all indexed a poll batch as evs[[1]] or hand-rolled a
drain() helper that returned the first event of whatever
arrived. Correct only while nothing else is in flight, which is exactly
how a caller infers the wrong model.grpc_poll() (#12). The
eventfd carries one signal per event, but the counter was drained
outside the mutex guarding the ready deque, so every signal posted
between the drain and the batch below stayed counted even though the
batch took those events. The leftover count was then spent as instant,
empty polls: a caller that reads “no events” as “this call never
started” abandons a live stream, which showed up as sequential
server-streaming calls on a shared client failing 1-7 times in 30. The
drain and a re-arm now happen under that mutex, so the descriptor is
readable exactly while events are queued. Affects clients and servers
alike, and grpc_fd() integrations most of all, since a
partial batch used to leave the descriptor unreadable with events still
pending.grpc_poll() result means: the
wait expired, not that the call is over.id. Taking
events[[1]] as the answer to a unary call and accumulating
every "stream_msg" into one stream’s payload are the same
assumption – one queue per call – and it does not hold. Abandoning a
stream unread does not stop it, and its queued messages go on surfacing
alongside later calls; grpc_cancel() bounds how many more
are produced but cannot recall events already queued. Verified against
the runtime rather than assumed: over 40 rounds of a deliberately
abandoned stream followed by a second stream on the same client, no
event’s id ever disagreed with its payload, while an
accumulator that ignored id got the wrong byte count 36
times out of 40.grpc_r_call_start() and
grpc_r_stream_start() read the call id after releasing the
mutex, and a fast completion can free the call state on the drain thread
in that window. The id is now captured under the lock.tools/sanitize.sh is fail-closed about its own
preconditions, after three stacked silent failures let earlier sanitizer
passes run the plain build: libraries are injected via
R_LIBS and asserted with find.package()
(littler’s -L silently does not prepend), sanitizer flags
go through CXX17FLAGS and instrumentation is proven via
__asan/__tsan symbols in the built
.so, installs use --preclean, an exit trap
removes flagged objects even on failure, non-data-race TSan warnings are
fatal, and the report classifier self-tests against synthetic logs at
every run.keepalive_ms/keepalive_timeout_ms on
grpc_client() and grpc_server(), plus
min_ping_interval_ms (server tolerance for client pings;
gRPC’s default is 5 minutes and kills faster clients). Enabling
keepalive also lifts gRPC’s ping policing so pings flow on quiet
connections.grpc_finish(drain = FALSE) discards
queued stream writes and prioritizes the terminal status (fencing);
grpc_cancel() now also works on server requests as the hard
escalation past a peer that has stopped reading.cq.Shutdown(). A
shutting flag now suppresses all drain-thread op posts
during close, on both client and server.docker/: two-stage build on
rocker/r2u:noble, runtime carries only
libgrpc++1.51t64 and r-cran-rprotobuf; built
and smoke-tested. The base image release must match the build host’s —
the binary is tied to the distro ABI.SystemRequirements now name
libprotobuf-dev alongside libgrpc++-dev (not
pulled automatically under --no-install-recommends).grpc_tls() builds PEM credentials
for both sides (TLS server, CA-pinned client, mTLS with
require_client_cert, target_name_override for
testing); server request events carry the transport peer
and, under mTLS, the verified peer_identity;
grpc_state() observes channel connectivity;
GRPC_TRACE/GRPC_VERBOSITY documented.grpc.health.v1) and server reflection
(grpc.reflection.v1) protos vendored and proven through the
generic path — unary Check and bidi ServerReflectionInfo — with no
special machinery.grpc_stream() opens client-, server-, and
bidirectional streams (typed or raw); grpc_send() (bounded
write queue with stream_writable backpressure events),
grpc_writes_done(), automatic bounded inbound buffering
with HTTP/2 backpressure, and a terminal stream_status
event. Server side: grpc_read() pulls inbound stream
messages, grpc_send() queues outbound ones,
grpc_finish() ends the stream after writes drain.
grpc_cancel() is now a generic over calls and streams;
client events carry kind.GetContainerEvents against containerd.Version, ListPodSandbox,
ListImages, all through the typed layer. CRI v1 schema
vendored as a self-contained import root under
inst/proto/cri; live tests gate on socket access
(GRPC_R_CRI_SOCKET);
inst/examples/cri-list-pods.R for humans.grpc_service() /
grpc_method() resolve services and methods from the runtime
descriptor pool (via the FileDescriptorProto, sidestepping
rprotobuf#116); grpc_call() accepts a
grpc_method plus a Message, validates the
request type, and auto-decodes OK responses as
response_message; grpc_reply() accepts a
Message; grpc_decode() decodes payload bytes.
RProtoBuf remains a Suggests.AsyncGenericService:
grpc_server() accepts any method dynamically;
grpc_reply() answers with a payload or a typed status plus
trailing metadata. Bounded accept window and max_active
apply backpressure.grpc_poll(), grpc_fd(),
grpc_pending(), and grpc_close() are now S3
generics over clients and servers. Peer cancellation and deadline expiry
surface as "cancelled" events; late replies are refused
rather than crashing.GenericStub:
grpc_client(), grpc_call(),
grpc_poll(), grpc_cancel(),
grpc_pending(), grpc_close(), with deadlines,
metadata, and typed status codes.grpc_fd() for later::later_fd()-style
integration; polling is the fallback, not the primitive.pkg-config, spike shim proving safe
create/destroy of channels, completion queues, and generic servers.These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.