mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Implement PrivateAgent (#2318)
* Implement PrivateAgent, Separate Threaded into PublicAgent & PrivateAgent. * Add migration docs. * Update docs.
This commit is contained in:
parent
c46cda1e6f
commit
6f6519dab4
@ -1,5 +1,5 @@
|
||||
use agents::native_worker::Worker;
|
||||
use yew_agent::Threaded;
|
||||
use yew_agent::PublicAgent;
|
||||
|
||||
fn main() {
|
||||
wasm_logger::init(wasm_logger::Config::default());
|
||||
|
||||
@ -5,7 +5,7 @@ pub mod agent;
|
||||
pub mod app;
|
||||
use app::Model;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use yew_agent::Threaded;
|
||||
use yew_agent::PublicAgent;
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn start() {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//! This module contains types to support multi-threading and state management.
|
||||
//! This module contains Yew's web worker implementation.
|
||||
|
||||
mod hooks;
|
||||
mod link;
|
||||
@ -10,7 +10,7 @@ pub use link::AgentLink;
|
||||
pub(crate) use link::*;
|
||||
pub(crate) use pool::*;
|
||||
pub use pool::{Dispatched, Dispatcher};
|
||||
pub use worker::{Private, Public, Threaded};
|
||||
pub use worker::{Private, PrivateAgent, Public, PublicAgent};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
@ -2,8 +2,8 @@ mod private;
|
||||
mod public;
|
||||
mod queue;
|
||||
|
||||
pub use private::Private;
|
||||
pub use public::Public;
|
||||
pub use private::{Private, PrivateAgent};
|
||||
pub use public::{Public, PublicAgent};
|
||||
|
||||
use super::*;
|
||||
use js_sys::{Array, Reflect, Uint8Array};
|
||||
@ -13,11 +13,19 @@ use web_sys::{
|
||||
Blob, BlobPropertyBag, DedicatedWorkerGlobalScope, MessageEvent, Url, Worker, WorkerOptions,
|
||||
};
|
||||
|
||||
/// Implements rules to register a worker in a separate thread.
|
||||
pub trait Threaded {
|
||||
/// Executes an agent in the current environment.
|
||||
/// Uses in `main` function of a worker.
|
||||
fn register();
|
||||
pub(crate) struct WorkerResponder {}
|
||||
|
||||
impl<AGN> Responder<AGN> for WorkerResponder
|
||||
where
|
||||
AGN: Agent,
|
||||
<AGN as Agent>::Input: Serialize + for<'de> Deserialize<'de>,
|
||||
<AGN as Agent>::Output: Serialize + for<'de> Deserialize<'de>,
|
||||
{
|
||||
fn respond(&self, id: HandlerId, output: AGN::Output) {
|
||||
let msg = FromWorker::ProcessOutput(id, output);
|
||||
let data = msg.pack();
|
||||
worker_self().post_message_vec(data);
|
||||
}
|
||||
}
|
||||
|
||||
/// Message packager, based on serde::Serialize/Deserialize
|
||||
|
||||
@ -21,6 +21,56 @@ pub struct Private<AGN> {
|
||||
_agent: PhantomData<AGN>,
|
||||
}
|
||||
|
||||
/// A trait to enable private agents being registered in a web worker.
|
||||
pub trait PrivateAgent {
|
||||
/// Executes an agent in the current environment.
|
||||
/// Uses in `main` function of a worker.
|
||||
fn register();
|
||||
}
|
||||
|
||||
impl<AGN> PrivateAgent for AGN
|
||||
where
|
||||
AGN: Agent<Reach = Private<AGN>>,
|
||||
<AGN as Agent>::Input: Serialize + for<'de> Deserialize<'de>,
|
||||
<AGN as Agent>::Output: Serialize + for<'de> Deserialize<'de>,
|
||||
{
|
||||
fn register() {
|
||||
let scope = AgentScope::<AGN>::new();
|
||||
let responder = WorkerResponder {};
|
||||
let link = AgentLink::connect(&scope, responder);
|
||||
let upd = AgentLifecycleEvent::Create(link);
|
||||
scope.send(upd);
|
||||
let handler = move |data: Vec<u8>| {
|
||||
let msg = ToWorker::<AGN::Input>::unpack(&data);
|
||||
match msg {
|
||||
ToWorker::Connected(_id) => {
|
||||
let upd = AgentLifecycleEvent::Connected(SINGLETON_ID);
|
||||
scope.send(upd);
|
||||
}
|
||||
ToWorker::ProcessInput(_id, value) => {
|
||||
let upd = AgentLifecycleEvent::Input(value, SINGLETON_ID);
|
||||
scope.send(upd);
|
||||
}
|
||||
ToWorker::Disconnected(_id) => {
|
||||
let upd = AgentLifecycleEvent::Disconnected(SINGLETON_ID);
|
||||
scope.send(upd);
|
||||
}
|
||||
ToWorker::Destroy => {
|
||||
let upd = AgentLifecycleEvent::Destroy;
|
||||
scope.send(upd);
|
||||
// Terminates web worker
|
||||
worker_self().close();
|
||||
}
|
||||
}
|
||||
};
|
||||
let loaded: FromWorker<AGN::Output> = FromWorker::WorkerLoaded;
|
||||
let loaded = loaded.pack();
|
||||
let worker = worker_self();
|
||||
worker.set_onmessage_closure(handler);
|
||||
worker.post_message_vec(loaded);
|
||||
}
|
||||
}
|
||||
|
||||
impl<AGN> Discoverer for Private<AGN>
|
||||
where
|
||||
AGN: Agent,
|
||||
|
||||
@ -181,22 +181,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct WorkerResponder {}
|
||||
|
||||
impl<AGN> Responder<AGN> for WorkerResponder
|
||||
where
|
||||
AGN: Agent,
|
||||
<AGN as Agent>::Input: Serialize + for<'de> Deserialize<'de>,
|
||||
<AGN as Agent>::Output: Serialize + for<'de> Deserialize<'de>,
|
||||
{
|
||||
fn respond(&self, id: HandlerId, output: AGN::Output) {
|
||||
let msg = FromWorker::ProcessOutput(id, output);
|
||||
let data = msg.pack();
|
||||
worker_self().post_message_vec(data);
|
||||
}
|
||||
/// A trait to enable public agents being registered in a web worker.
|
||||
pub trait PublicAgent {
|
||||
/// Executes an agent in the current environment.
|
||||
/// Uses in `main` function of a worker.
|
||||
fn register();
|
||||
}
|
||||
|
||||
impl<AGN> Threaded for AGN
|
||||
impl<AGN> PublicAgent for AGN
|
||||
where
|
||||
AGN: Agent<Reach = Public<AGN>>,
|
||||
<AGN as Agent>::Input: Serialize + for<'de> Deserialize<'de>,
|
||||
|
||||
@ -36,8 +36,8 @@ The code can be found in the <desc> tag of the svgs.
|
||||
When no bridges are connected to this agent, the agent will disappear.
|
||||
|
||||
* Private - Spawn a new agent in a web worker for every new bridge. This is good for moving shared but
|
||||
independent behavior that communicates with the browser out of components. \(TODO verify\) When
|
||||
the task is done, the agent will disappear.
|
||||
independent behavior that communicates with the browser out of components. When
|
||||
the the connected bridge is dropped, the agent will disappear.
|
||||
|
||||
* Global \(WIP\)
|
||||
|
||||
|
||||
@ -2,8 +2,21 @@
|
||||
title: "From 0.1.0 to 0.2.0"
|
||||
---
|
||||
|
||||
## Removal of `Context` and `Job` Agents
|
||||
|
||||
The `Context` and `Job` Agents have been removed in favour of Yew's Context API.
|
||||
|
||||
You can see the updated [`pub_sub`](https://github.com/yewstack/yew/tree/master/examples/pub_sub) example about how to use Context API.
|
||||
|
||||
For users of `yew_agent::utils::store`, you may switch to third party solutions like: [Yewdux](https://github.com/intendednull/yewdux) or [Bounce](https://github.com/futursolo/bounce).
|
||||
|
||||
## `Threaded` is separated into `PublicAgent` and `PrivateAgent`
|
||||
|
||||
Replace `use yew_agent::Threaded;` with `use yew_agent::PublicAgent;`.
|
||||
|
||||
:::note
|
||||
|
||||
`Threaded` was never implemented for Private Agents.
|
||||
All existing web worker-based agents are Public Agents.
|
||||
|
||||
:::
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user