tonic-rails 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/Cargo.lock +1 -1
- data/ext/tonic_rails_native/Cargo.toml +1 -1
- data/ext/tonic_rails_native/src/client.rs +52 -4
- data/lib/tonic/rails/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cd7973d8a7b1550f1f483912639ec1cbec562297c3368c8751c45780e8472ec1
|
|
4
|
+
data.tar.gz: 385c74ea7100d36e7c128df6f1feda64fb7ac7c3b11a3905afa35d5ac275af26
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d491ec733022fca2b343ca3bb738273945c62614619266a1bccc8e8823f9f377628a2e6b4fb9a4b9c367b623e4c523ace580e18e4094fd66b07f94b7b55a0b97
|
|
7
|
+
data.tar.gz: 58a0d85837cd8f68f063d934b029761ab4239d30b9e2807bed5638b798ac1b18d2efe3e88c20c255dbb5c18aa3a5fee79ba86a8056d785eced8690ce4a6d0c17
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ minor versions may contain breaking changes.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.8.1] - 2026-10-13
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Client: a call whose deadline passed could raise `CANCELLED` ("Timeout
|
|
15
|
+
expired") instead of `DEADLINE_EXCEEDED` (#48), mostly on Windows.
|
|
16
|
+
tonic enforces the deadline too, and when its timer fired first the
|
|
17
|
+
call ended with its status. Calls now raise `DEADLINE_EXCEEDED`
|
|
18
|
+
whichever timer fires first.
|
|
19
|
+
|
|
10
20
|
## [0.8.0] - 2026-10-12
|
|
11
21
|
|
|
12
22
|
### Added
|
|
@@ -207,7 +217,8 @@ First public release.
|
|
|
207
217
|
- Precompiled native gems for Linux (x86_64, aarch64; glibc and musl) and
|
|
208
218
|
macOS (x86_64, arm64), Ruby 3.3 to 4.0.
|
|
209
219
|
|
|
210
|
-
[Unreleased]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.8.
|
|
220
|
+
[Unreleased]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.8.1...HEAD
|
|
221
|
+
[0.8.1]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.8.0...v0.8.1
|
|
211
222
|
[0.8.0]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.7.0...v0.8.0
|
|
212
223
|
[0.7.0]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.6.0...v0.7.0
|
|
213
224
|
[0.6.0]: https://github.com/CodingAnarchy/tonic-rails/compare/v0.5.0...v0.6.0
|
data/Cargo.lock
CHANGED
|
@@ -30,7 +30,7 @@ use tokio::task::JoinHandle;
|
|
|
30
30
|
use tonic::codec::{Codec, DecodeBuf, Decoder, EncodeBuf, Encoder, Streaming};
|
|
31
31
|
use tonic::metadata::MetadataMap;
|
|
32
32
|
use tonic::transport::{Certificate, Channel, ClientTlsConfig, Endpoint, Identity};
|
|
33
|
-
use tonic::{Code, Request, Status};
|
|
33
|
+
use tonic::{Code, Request, Status, TimeoutExpired};
|
|
34
34
|
|
|
35
35
|
use crate::gvl::{Cancel, Wait, block_on, recv_blocking, without_gvl};
|
|
36
36
|
use crate::sync::Mutex;
|
|
@@ -218,13 +218,22 @@ async fn with_timeout(call: impl Future<Output = Outcome>, timeout: Option<Durat
|
|
|
218
218
|
let started = tokio::time::Instant::now();
|
|
219
219
|
let outcome = tokio::time::timeout(timeout, call).await;
|
|
220
220
|
match outcome {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
221
|
+
Ok(outcome) if !(outcome.local && started.elapsed() >= timeout) && !timeout_expired(&outcome) => {
|
|
222
|
+
outcome
|
|
223
|
+
}
|
|
224
224
|
_ => Outcome::error(Code::DeadlineExceeded, "deadline exceeded"),
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
+
/// tonic's channel enforces the grpc-timeout header too, and when its timer
|
|
229
|
+
/// fires before ours it ends the call with CANCELLED "Timeout expired", with
|
|
230
|
+
/// no source to mark it local. (A tonic server enforcing the same deadline
|
|
231
|
+
/// sends that status too.) Coarse timers, like Windows' 15 ms ticks, let
|
|
232
|
+
/// it fire first even though ours started earlier (#48).
|
|
233
|
+
fn timeout_expired(outcome: &Outcome) -> bool {
|
|
234
|
+
outcome.code == Code::Cancelled && outcome.message == TimeoutExpired(()).to_string()
|
|
235
|
+
}
|
|
236
|
+
|
|
228
237
|
/// What every call needs: the method, one request message and its metadata.
|
|
229
238
|
struct CallArgs {
|
|
230
239
|
channel: Channel,
|
|
@@ -663,3 +672,42 @@ fn append_causes(mut message: String, mut source: Option<&dyn std::error::Error>
|
|
|
663
672
|
}
|
|
664
673
|
message
|
|
665
674
|
}
|
|
675
|
+
|
|
676
|
+
#[cfg(test)]
|
|
677
|
+
mod tests {
|
|
678
|
+
use super::*;
|
|
679
|
+
|
|
680
|
+
fn run(call: impl Future<Output = Outcome>, timeout: Option<Duration>) -> Outcome {
|
|
681
|
+
let runtime = Builder::new_current_thread().enable_time().build().unwrap();
|
|
682
|
+
runtime.block_on(with_timeout(call, timeout))
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
async fn status(status: Status) -> Outcome {
|
|
686
|
+
Outcome::status(status, None)
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
#[test]
|
|
690
|
+
fn tonics_timeout_is_a_deadline_however_early_it_fires() {
|
|
691
|
+
let outcome = run(
|
|
692
|
+
status(Status::cancelled("Timeout expired")),
|
|
693
|
+
Some(Duration::from_secs(60)),
|
|
694
|
+
);
|
|
695
|
+
assert_eq!(outcome.code, Code::DeadlineExceeded);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
#[test]
|
|
699
|
+
fn other_cancellations_stay_cancelled() {
|
|
700
|
+
let outcome = run(
|
|
701
|
+
status(Status::cancelled("client went away")),
|
|
702
|
+
Some(Duration::from_secs(60)),
|
|
703
|
+
);
|
|
704
|
+
assert_eq!(outcome.code, Code::Cancelled);
|
|
705
|
+
assert_eq!(outcome.message, "client went away");
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
#[test]
|
|
709
|
+
fn our_timer_is_a_deadline() {
|
|
710
|
+
let outcome = run(std::future::pending(), Some(Duration::from_millis(10)));
|
|
711
|
+
assert_eq!(outcome.code, Code::DeadlineExceeded);
|
|
712
|
+
}
|
|
713
|
+
}
|
data/lib/tonic/rails/version.rb
CHANGED