1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-26 16:09:27 -05:00

Remove unnecessary boxing of tokio::time::Sleep (#9105)

This commit is contained in:
Bert Belder 2021-01-12 21:48:55 -08:00
parent 18b3150401
commit ca07bab594
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
4 changed files with 34 additions and 23 deletions

1
Cargo.lock generated
View file

@ -431,6 +431,7 @@ dependencies = [
"notify", "notify",
"os_pipe", "os_pipe",
"percent-encoding", "percent-encoding",
"pin-project 1.0.4",
"regex", "regex",
"ring", "ring",
"rustyline", "rustyline",

View file

@ -59,6 +59,7 @@ log = { version = "0.4.13", features = ["serde"] }
lspower = "0.3.0" lspower = "0.3.0"
notify = "5.0.0-pre.4" notify = "5.0.0-pre.4"
percent-encoding = "2.1.0" percent-encoding = "2.1.0"
pin-project = "1.0.4"
regex = "1.4.3" regex = "1.4.3"
ring = "0.16.19" ring = "0.16.19"
rustyline = { version = "7.1.0", default-features = false } rustyline = { version = "7.1.0", default-features = false }

View file

@ -1,10 +1,10 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
use crate::colors; use crate::colors;
use core::task::{Context, Poll};
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::ready;
use deno_core::futures::stream::{Stream, StreamExt}; use deno_core::futures::stream::{Stream, StreamExt};
use deno_core::futures::{Future, FutureExt}; use deno_core::futures::Future;
use notify::event::Event as NotifyEvent; use notify::event::Event as NotifyEvent;
use notify::event::EventKind; use notify::event::EventKind;
use notify::Config; use notify::Config;
@ -12,27 +12,35 @@ use notify::Error as NotifyError;
use notify::RecommendedWatcher; use notify::RecommendedWatcher;
use notify::RecursiveMode; use notify::RecursiveMode;
use notify::Watcher; use notify::Watcher;
use pin_project::pin_project;
use std::path::PathBuf; use std::path::PathBuf;
use std::pin::Pin; use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::task::Context;
use std::task::Poll;
use std::time::Duration; use std::time::Duration;
use tokio::pin;
use tokio::select; use tokio::select;
use tokio::time::sleep; use tokio::time::sleep;
use tokio::time::Instant;
use tokio::time::Sleep;
const DEBOUNCE_INTERVAL_MS: Duration = Duration::from_millis(200); const DEBOUNCE_INTERVAL: Duration = Duration::from_millis(200);
type FileWatcherFuture<T> = Pin<Box<dyn Future<Output = T>>>; type FileWatcherFuture<T> = Pin<Box<dyn Future<Output = T>>>;
#[pin_project(project = DebounceProjection)]
struct Debounce { struct Debounce {
sleep: Pin<Box<dyn Future<Output = ()>>>, #[pin]
timer: Sleep,
event_detected: Arc<AtomicBool>, event_detected: Arc<AtomicBool>,
} }
impl Debounce { impl Debounce {
fn new() -> Self { fn new() -> Self {
Self { Self {
sleep: sleep(DEBOUNCE_INTERVAL_MS).boxed_local(), timer: sleep(DEBOUNCE_INTERVAL),
event_detected: Arc::new(AtomicBool::new(false)), event_detected: Arc::new(AtomicBool::new(false)),
} }
} }
@ -41,25 +49,21 @@ impl Debounce {
impl Stream for Debounce { impl Stream for Debounce {
type Item = (); type Item = ();
/// Note that this never returns `Poll::Ready(None)`, which means that file watcher will be alive /// Note that this never returns `Poll::Ready(None)`, which means that the
/// until the Deno process is terminated. /// file watcher will be alive until the Deno process is terminated.
fn poll_next( fn poll_next(
self: Pin<&mut Self>, self: Pin<&mut Self>,
cx: &mut Context, cx: &mut Context,
) -> Poll<Option<Self::Item>> { ) -> Poll<Option<Self::Item>> {
let inner = self.get_mut(); if self.event_detected.load(Ordering::Relaxed) {
if inner.event_detected.load(Ordering::Relaxed) { self.event_detected.store(false, Ordering::Relaxed);
inner.event_detected.store(false, Ordering::Relaxed);
Poll::Ready(Some(())) Poll::Ready(Some(()))
} else { } else {
match inner.sleep.poll_unpin(cx) { let mut timer = self.project().timer;
Poll::Ready(_) => { ready!(timer.as_mut().poll(cx));
inner.sleep = sleep(DEBOUNCE_INTERVAL_MS).boxed_local(); timer.reset(Instant::now() + DEBOUNCE_INTERVAL);
Poll::Pending Poll::Pending
} }
Poll::Pending => Poll::Pending,
}
}
} }
} }
@ -96,7 +100,8 @@ where
F: Fn() -> Result<Vec<PathBuf>, AnyError>, F: Fn() -> Result<Vec<PathBuf>, AnyError>,
G: Fn(Vec<PathBuf>) -> FileWatcherFuture<Result<(), AnyError>>, G: Fn(Vec<PathBuf>) -> FileWatcherFuture<Result<(), AnyError>>,
{ {
let mut debounce = Debounce::new(); let debounce = Debounce::new();
pin!(debounce);
loop { loop {
let paths = target_resolver()?; let paths = target_resolver()?;
@ -169,7 +174,9 @@ where
G: Fn(T) -> FileWatcherFuture<Result<(), AnyError>>, G: Fn(T) -> FileWatcherFuture<Result<(), AnyError>>,
T: Clone, T: Clone,
{ {
let mut debounce = Debounce::new(); let debounce = Debounce::new();
pin!(debounce);
// Store previous data. If module resolution fails at some point, the watcher will try to // Store previous data. If module resolution fails at some point, the watcher will try to
// continue watching files using these data. // continue watching files using these data.
let mut paths = Vec::new(); let mut paths = Vec::new();

View file

@ -6,7 +6,6 @@ use crate::colors;
use crate::media_type::MediaType; use crate::media_type::MediaType;
use crate::program_state::ProgramState; use crate::program_state::ProgramState;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::FutureExt;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::serde_json::Value; use deno_core::serde_json::Value;
use deno_runtime::inspector::InspectorSession; use deno_runtime::inspector::InspectorSession;
@ -29,6 +28,7 @@ use std::sync::mpsc::SyncSender;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use swc_ecmascript::parser::token::{Token, Word}; use swc_ecmascript::parser::token::{Token, Word};
use tokio::pin;
// Provides helpers to the editor like validation for multi-line edits, completion candidates for // Provides helpers to the editor like validation for multi-line edits, completion candidates for
// tab completion. // tab completion.
@ -305,8 +305,10 @@ async fn read_line_and_poll(
// Because an inspector websocket client may choose to connect at anytime when we have an // Because an inspector websocket client may choose to connect at anytime when we have an
// inspector server we need to keep polling the worker to pick up new connections. // inspector server we need to keep polling the worker to pick up new connections.
let mut timeout = // TODO(piscisaureus): the above comment is a red herring; figure out if/why
tokio::time::sleep(tokio::time::Duration::from_millis(100)).boxed_local(); // the event loop isn't woken by a waker when a websocket client connects.
let timeout = tokio::time::sleep(tokio::time::Duration::from_millis(100));
pin!(timeout);
tokio::select! { tokio::select! {
result = &mut line => { result = &mut line => {
@ -315,7 +317,7 @@ async fn read_line_and_poll(
_ = worker.run_event_loop(), if poll_worker => { _ = worker.run_event_loop(), if poll_worker => {
poll_worker = false; poll_worker = false;
} }
_ = &mut timeout => { _ = timeout => {
poll_worker = true poll_worker = true
} }
} }