Skip to content

Commit 4f7402d

Browse files
authored
RUST-1676 Simplify GenericCursor by refactoring the GetMoreProvider trait into a generic struct (#983)
1 parent 6d4e316 commit 4f7402d

File tree

3 files changed

+165
-310
lines changed

3 files changed

+165
-310
lines changed

src/cursor.rs

Lines changed: 7 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use bson::RawDocument;
1212

1313
#[cfg(test)]
1414
use bson::RawDocumentBuf;
15-
use futures_core::{future::BoxFuture, Stream};
15+
use futures_core::Stream;
1616
use serde::{de::DeserializeOwned, Deserialize};
1717
#[cfg(test)]
1818
use tokio::sync::oneshot;
@@ -21,13 +21,12 @@ use crate::{
2121
change_stream::event::ResumeToken,
2222
client::{options::ServerAddress, AsyncDropToken},
2323
cmap::conn::PinnedConnectionHandle,
24+
cursor::common::ImplicitClientSessionHandle,
2425
error::{Error, Result},
25-
operation::GetMore,
26-
results::GetMoreResult,
2726
Client,
2827
ClientSession,
2928
};
30-
use common::{kill_cursor, GenericCursor, GetMoreProvider, GetMoreProviderResult};
29+
use common::{kill_cursor, GenericCursor};
3130
pub(crate) use common::{
3231
stream_poll_next,
3332
BatchValue,
@@ -119,16 +118,14 @@ impl<T> Cursor<T> {
119118
session: Option<ClientSession>,
120119
pin: Option<PinnedConnectionHandle>,
121120
) -> Self {
122-
let provider = ImplicitSessionGetMoreProvider::new(&spec, session);
123-
124121
Self {
125122
client: client.clone(),
126123
drop_token: client.register_async_drop(),
127-
wrapped_cursor: Some(ImplicitSessionCursor::new(
124+
wrapped_cursor: Some(ImplicitSessionCursor::with_implicit_session(
128125
client,
129126
spec,
130127
PinnedConnection::new(pin),
131-
provider,
128+
ImplicitClientSessionHandle(session),
132129
)),
133130
drop_address: None,
134131
#[cfg(test)]
@@ -176,7 +173,7 @@ impl<T> Cursor<T> {
176173
pub(crate) fn take_implicit_session(&mut self) -> Option<ClientSession> {
177174
self.wrapped_cursor
178175
.as_mut()
179-
.and_then(|c| c.provider_mut().take_implicit_session())
176+
.and_then(|c| c.take_implicit_session())
180177
}
181178

182179
/// Move the cursor forward, potentially triggering requests to the database for more results
@@ -358,121 +355,4 @@ impl<T> Drop for Cursor<T> {
358355

359356
/// A `GenericCursor` that optionally owns its own sessions.
360357
/// This is to be used by cursors associated with implicit sessions.
361-
type ImplicitSessionCursor = GenericCursor<ImplicitSessionGetMoreProvider>;
362-
363-
struct ImplicitSessionGetMoreResult {
364-
get_more_result: Result<GetMoreResult>,
365-
session: Option<Box<ClientSession>>,
366-
}
367-
368-
impl GetMoreProviderResult for ImplicitSessionGetMoreResult {
369-
type Session = Option<Box<ClientSession>>;
370-
371-
fn as_ref(&self) -> std::result::Result<&GetMoreResult, &Error> {
372-
self.get_more_result.as_ref()
373-
}
374-
375-
fn into_parts(self) -> (Result<GetMoreResult>, Self::Session) {
376-
(self.get_more_result, self.session)
377-
}
378-
}
379-
380-
/// A `GetMoreProvider` that optionally owns its own session.
381-
/// This is to be used with cursors associated with implicit sessions.
382-
enum ImplicitSessionGetMoreProvider {
383-
Executing(BoxFuture<'static, ImplicitSessionGetMoreResult>),
384-
Idle(Option<Box<ClientSession>>),
385-
Done,
386-
}
387-
388-
impl ImplicitSessionGetMoreProvider {
389-
fn new(spec: &CursorSpecification, session: Option<ClientSession>) -> Self {
390-
let session = session.map(Box::new);
391-
if spec.id() == 0 {
392-
Self::Done
393-
} else {
394-
Self::Idle(session)
395-
}
396-
}
397-
398-
/// Extract the stored implicit session, if any. The provider cannot be started again after
399-
/// this call.
400-
fn take_implicit_session(&mut self) -> Option<ClientSession> {
401-
match self {
402-
ImplicitSessionGetMoreProvider::Idle(session) => session.take().map(|s| *s),
403-
_ => None,
404-
}
405-
}
406-
}
407-
408-
impl GetMoreProvider for ImplicitSessionGetMoreProvider {
409-
type ResultType = ImplicitSessionGetMoreResult;
410-
type GetMoreFuture = BoxFuture<'static, ImplicitSessionGetMoreResult>;
411-
412-
fn executing_future(&mut self) -> Option<&mut Self::GetMoreFuture> {
413-
match self {
414-
Self::Executing(ref mut future) => Some(future),
415-
Self::Idle { .. } | Self::Done => None,
416-
}
417-
}
418-
419-
fn clear_execution(&mut self, session: Option<Box<ClientSession>>, exhausted: bool) {
420-
// If cursor is exhausted, immediately return implicit session to the pool.
421-
if exhausted {
422-
*self = Self::Done;
423-
} else {
424-
*self = Self::Idle(session);
425-
}
426-
}
427-
428-
fn start_execution(
429-
&mut self,
430-
info: CursorInformation,
431-
client: Client,
432-
pinned_connection: Option<&PinnedConnectionHandle>,
433-
) {
434-
take_mut::take(self, |self_| match self_ {
435-
Self::Idle(mut session) => {
436-
let pinned_connection = pinned_connection.map(|c| c.replicate());
437-
let future = Box::pin(async move {
438-
let get_more = GetMore::new(info, pinned_connection.as_ref());
439-
let get_more_result = client
440-
.execute_operation(get_more, session.as_mut().map(|b| b.as_mut()))
441-
.await;
442-
ImplicitSessionGetMoreResult {
443-
get_more_result,
444-
session,
445-
}
446-
});
447-
Self::Executing(future)
448-
}
449-
Self::Executing(_) | Self::Done => self_,
450-
})
451-
}
452-
453-
fn execute(
454-
&mut self,
455-
info: CursorInformation,
456-
client: Client,
457-
pinned_connection: PinnedConnection,
458-
) -> BoxFuture<'_, Result<GetMoreResult>> {
459-
match self {
460-
Self::Idle(ref mut session) => Box::pin(async move {
461-
let get_more = GetMore::new(info, pinned_connection.handle());
462-
client
463-
.execute_operation(get_more, session.as_mut().map(|b| b.as_mut()))
464-
.await
465-
}),
466-
Self::Executing(_fut) => Box::pin(async {
467-
Err(Error::internal(
468-
"streaming the cursor was cancelled while a request was in progress and must \
469-
be continued before iterating manually",
470-
))
471-
}),
472-
Self::Done => {
473-
// this should never happen
474-
Box::pin(async { Err(Error::internal("cursor iterated after already exhausted")) })
475-
}
476-
}
477-
}
478-
}
358+
type ImplicitSessionCursor = GenericCursor<'static, ImplicitClientSessionHandle>;

0 commit comments

Comments
 (0)