Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix panic when quitting application #1296

Merged
merged 2 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 25 additions & 20 deletions crates/fj-host/src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{Error, Evaluation, Model};

/// Evaluates a model in a background thread
pub struct Evaluator {
trigger_tx: Sender<()>,
trigger_tx: Sender<TriggerEvaluation>,
event_rx: Receiver<ModelEvent>,
}

Expand All @@ -16,24 +16,26 @@ impl Evaluator {
let (event_tx, event_rx) = crossbeam_channel::bounded(0);
let (trigger_tx, trigger_rx) = crossbeam_channel::bounded(0);

thread::spawn(move || loop {
let () = trigger_rx
.recv()
.expect("Expected channel to never disconnect");

let evaluation = match model.evaluate() {
Ok(evaluation) => evaluation,
Err(err) => {
event_tx
.send(ModelEvent::Error(err))
.expect("Expected channel to never disconnect");
continue;
}
};

event_tx
.send(ModelEvent::Evaluation(evaluation))
.expect("Expected channel to never disconnect");
thread::spawn(move || {
while let Ok(TriggerEvaluation) = trigger_rx.recv() {
let evaluation = match model.evaluate() {
Ok(evaluation) => evaluation,
Err(err) => {
event_tx
.send(ModelEvent::Error(err))
.expect("Expected channel to never disconnect");
continue;
}
};

event_tx
.send(ModelEvent::Evaluation(evaluation))
.expect("Expected channel to never disconnect");
}

// The channel is disconnected, which means this instance of
// `Evaluator`, as well as all `Sender`s created from it, have been
// dropped. We're done.
});

Self {
Expand All @@ -43,7 +45,7 @@ impl Evaluator {
}

/// Access a channel for triggering evaluations
pub fn trigger(&self) -> Sender<()> {
pub fn trigger(&self) -> Sender<TriggerEvaluation> {
self.trigger_tx.clone()
}

Expand All @@ -53,6 +55,9 @@ impl Evaluator {
}
}

/// Command received by [`Evaluator`] through its channel
pub struct TriggerEvaluation;

/// An event emitted by [`Evaluator`]
pub enum ModelEvent {
/// The model has been evaluated
Expand Down
10 changes: 7 additions & 3 deletions crates/fj-host/src/watcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::HashSet, ffi::OsStr, path::Path, thread};

use notify::Watcher as _;

use crate::{Error, Evaluator};
use crate::{evaluator::TriggerEvaluation, Error, Evaluator};

/// Watches a model for changes, reloading it continually
pub struct Watcher {
Expand Down Expand Up @@ -65,7 +65,9 @@ impl Watcher {
// application is being shut down.
//
// Either way, not much we can do about it here.
watch_tx.send(()).expect("Channel is disconnected");
watch_tx
.send(TriggerEvaluation)
.expect("Channel is disconnected");
}
},
)?;
Expand All @@ -82,7 +84,9 @@ impl Watcher {
// Will panic, if the receiving end has panicked. Not much we can do
// about that, if it happened.
thread::spawn(move || {
watch_tx_2.send(()).expect("Channel is disconnected")
watch_tx_2
.send(TriggerEvaluation)
.expect("Channel is disconnected")
});

Ok(Self {
Expand Down