improv(service): Plugins shall respond directly, without forwarding middleman

This commit is contained in:
Michael Aaron Murphy 2021-08-16 22:10:17 +02:00
parent 2805d43b2b
commit 2287c40a38
4 changed files with 51 additions and 42 deletions

View file

@ -9,7 +9,7 @@ use std::{
},
};
use crate::{Plugin, PluginResponse, Request};
use crate::{Event, Plugin, PluginResponse, Request};
use async_oneshot::oneshot;
use flume::Sender;
use futures_lite::{AsyncWriteExt, FutureExt, StreamExt};
@ -20,7 +20,8 @@ use smol::{
use tracing::{event, Level};
pub struct ExternalPlugin {
tx: Sender<PluginResponse>,
id: usize,
tx: Sender<Event>,
name: String,
pub cmd: PathBuf,
pub args: Vec<String>,
@ -30,8 +31,15 @@ pub struct ExternalPlugin {
}
impl ExternalPlugin {
pub fn new(name: String, cmd: PathBuf, args: Vec<String>, tx: Sender<PluginResponse>) -> Self {
pub fn new(
id: usize,
name: String,
cmd: PathBuf,
args: Vec<String>,
tx: Sender<Event>,
) -> Self {
Self {
id,
name,
tx,
cmd,
@ -60,6 +68,7 @@ impl ExternalPlugin {
let (trip_tx, trip_rx) = oneshot::<()>();
let tx = self.tx.clone();
let name = self.name().to_owned();
let id = self.id;
// Spawn a background task to forward JSON responses from the child process.
let task = smol::spawn(async move {
@ -79,7 +88,7 @@ impl ExternalPlugin {
}
tracing::debug!("{}: responding with {:?}", name_, response);
let _ = tx_.send(response);
let _ = tx_.send(Event::Response((id, response)));
}
Err(why) => {
event!(Level::ERROR, "{}: serde error: {:?}", name_, why);
@ -98,7 +107,7 @@ impl ExternalPlugin {
// Ensure that a task that was searching sends a finished signal if it dies.
if searching.swap(false, Ordering::SeqCst) {
let _ = tx.send(PluginResponse::Finished);
let _ = tx.send(Event::Response((id, PluginResponse::Finished)));
}
detached.store(true, Ordering::SeqCst);
@ -183,7 +192,10 @@ impl Plugin for ExternalPlugin {
if self.query(&Request::Search(query.to_owned())).await.is_ok() {
self.searching.store(true, Ordering::SeqCst);
} else {
let _ = self.tx.send_async(PluginResponse::Finished).await;
let _ = self
.tx
.send_async(Event::Response((self.id, PluginResponse::Finished)))
.await;
}
}
async fn quit(&mut self, id: u32) {

View file

@ -20,14 +20,16 @@ pub const CONFIG: PluginConfig = PluginConfig {
icon: Some(IconSource::Name(Cow::Borrowed("system-help-symbolic"))),
};
pub struct HelpPlugin {
pub id: usize,
pub details: Slab<PluginHelp>,
pub internal: Sender<Event>,
pub tx: Sender<PluginResponse>,
pub tx: Sender<Event>,
}
impl HelpPlugin {
pub fn new(internal: Sender<Event>, tx: Sender<PluginResponse>) -> Self {
pub fn new(id: usize, internal: Sender<Event>, tx: Sender<Event>) -> Self {
Self {
id,
details: Slab::new(),
internal,
tx,
@ -46,7 +48,13 @@ impl Plugin for HelpPlugin {
async fn activate(&mut self, id: u32) {
if let Some(detail) = self.details.get(id as usize) {
if let Some(help) = detail.help.as_ref() {
let _ = self.tx.send_async(PluginResponse::Fill(help.clone())).await;
let _ = self
.tx
.send_async(Event::Response((
self.id,
PluginResponse::Fill(help.clone()),
)))
.await;
}
}
}
@ -69,19 +77,24 @@ impl Plugin for HelpPlugin {
}
for (id, detail) in self.details.iter() {
if detail.help.is_some() {
let response = PluginResponse::Append(PluginSearchResult {
id: id as u32,
name: detail.name.clone(),
description: detail.description.clone(),
..Default::default()
});
let _ = self
.tx
.send_async(PluginResponse::Append(PluginSearchResult {
id: id as u32,
name: detail.name.clone(),
description: detail.description.clone(),
..Default::default()
}))
.send_async(Event::Response((self.id, response)))
.await;
}
}
let _ = self.tx.send_async(PluginResponse::Finished).await;
let _ = self
.tx
.send_async(Event::Response((self.id, PluginResponse::Finished)))
.await;
}
async fn quit(&mut self, _id: u32) {}