Skip to content

Commit dfda435

Browse files
tyranronLegNeato
authored andcommitted
Improve description and fix some test errors
1 parent 9bd9727 commit dfda435

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

docs/book/content/types/objects/using_contexts.md

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ struct User {
5959
// Assign Database as the context type for User
6060
#[graphql_object(context = Database)]
6161
impl User {
62-
// Inject the context by specifying an argument
63-
// with the context type.
62+
// Inject the context by specifying an argument with the context type.
6463
// Note:
6564
// - the type must be a reference
6665
// - the name of the argument SHOULD be `context`
@@ -86,20 +85,26 @@ impl User {
8685
You only get an immutable reference to the context, so if you want to affect
8786
change to the execution, you'll need to use [interior
8887
mutability](https://doc.rust-lang.org/book/first-edition/mutability.html#interior-vs-exterior-mutability)
89-
using e.g. `RwLock` or `RefCell`. \
90-
If you are using async runtime like `tokio` for mutable references you will need to use a corresponding async version of RwLock:
88+
using e.g. `RwLock` or `RefCell`.
89+
90+
91+
92+
93+
## Dealing with mutable references
94+
95+
Context cannot be specified by a mutable reference, because concurrent fields resolving may be performed. If you have something in your context that requires access by mutable reference, then you need to leverage the [interior mutability][1] for that.
96+
97+
For example, when using async runtime with [work stealing][2] (like `tokio`), which obviously requires thread safety in addition, you will need to use a corresponding async version of `RwLock`:
9198
```rust
9299
# extern crate juniper;
93100
# use std::collections::HashMap;
94101
# use juniper::graphql_object;
95-
# use tokio::sync::RwLock;
96-
#
97-
// This struct represents our context.
102+
use tokio::sync::RwLock;
103+
98104
struct Database {
99105
requested_count: HashMap<i32, i32>,
100106
}
101107

102-
// Mark the Database as a valid context type for Juniper
103108
impl juniper::Context for Database {}
104109

105110
struct User {
@@ -108,21 +113,15 @@ struct User {
108113
times_requested: i32,
109114
}
110115

111-
// Assign Database as the context type for User and envelope it in RwLock
112116
#[graphql_object(context = RwLock<Database>)]
113117
impl User {
114-
// Inject the context by specifying an argument
115-
// with the context type.
116-
// Note:
117-
// - the type must be a reference
118-
// - the name of the argument SHOULD be `context`
119-
fn times_requested<'db>(&self, context: &'db RwLock<Database>) -> Vec<&'db User> {
118+
async fn times_requested<'db>(&self, context: &'db RwLock<Database>) -> Vec<&'db User> {
120119
// Acquire a mutable reference and await if async RwLock is used,
121-
// which is neccessary if context consists async operations
122-
// like querying remote databases
123-
// If context is immutable use .read() on RwLock
120+
// which is necessary if context consists async operations like
121+
// querying remote databases.
122+
// If context is immutable use .read() on RwLock.
124123
let mut context = context.write().await;
125-
// Preform a mutable operation
124+
// Preform a mutable operation.
126125
context.requested_count.entry(self.id).and_modify(|e| { *e += 1 }).or_insert(1)
127126
}
128127

@@ -137,4 +136,10 @@ impl User {
137136
#
138137
# fn main() { }
139138
```
140-
Replace `tokio::sync::RwLock` with `std::sync::RwLock` if async runtime is not intended
139+
Replace `tokio::sync::RwLock` with `std::sync::RwLock` (or similar) if you don't intend to use async resolving.
140+
141+
142+
143+
144+
[1]: https://doc.rust-lang.org/book/ch15-05-interior-mutability.html
145+
[2]: https://en.wikipedia.org/wiki/Work_stealing

docs/book/tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ iron = "0.5"
1616
mount = "0.4"
1717
skeptic = "0.13"
1818
serde_json = "1.0"
19-
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
19+
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync"] }
2020
uuid = "0.8"
2121

2222
[build-dependencies]

0 commit comments

Comments
 (0)