Yewにおけるoff-the-main-thread

0fa1c2ed2eb4a18ddec3dd70cb1f72db?s=47 Yosuke Onoue
October 20, 2020
280

 Yewにおけるoff-the-main-thread

0fa1c2ed2eb4a18ddec3dd70cb1f72db?s=128

Yosuke Onoue

October 20, 2020
Tweet

Transcript

  1. ͓ͷ͏͑ʢ!@MJLSʣ :FXʹ͓͚Δ P⒎UIFNBJOUISFBE 3VTUͷ-5ձ4IJOKVLVST!ΦϯϥΠϯ ೥݄೔

  2. ࣗݾ঺հ w ඌ্༸հʢ:PTVLF0OPVFʣ w ೔ຊେֶจཧֶ෦৘ใՊֶՊ।ڭत w גࣜձࣾఇࠃσʔλόϯΫ٬һݚڀһ w 3VTUͱ8FCٕज़͕޷͖Ͱ͢ IUUQTUXJUUFSDPN@MJLS

    IUUQTWETMBCKQ
  3. w ϒϥ΢β্ͷϖʔδͷ؅ཧͷଟ͘͸ ୯ҰͷϝΠϯεϨουʹΑͬͯߦΘΕ͍ͯΔ w ϝΠϯεϨουͷ࢓ࣄ w %0.ͷॲཧ w ϖʔδͷϨΠΞ΢τ w

    ΠϕϯτϋϯυϦϯά w +BWB4DSJQUͷॲཧ w FUD w +BWB4DSJQU΋جຊతʹ͸γϯάϧεϨου 8FCϒϥ΢βͷϝΠϯεϨουʢ6*εϨουʣ
  4. w Ϣʔβʔ΁ͷԠ౴଎౓ͷ௿Լ w ΞχϝʔγϣϯϑϨʔϜϨʔτͷ௿Լ ϝΠϯεϨου઎༗ͷӨڹ 5BTL &WFOU )BOEMJOH 8BJUJOH5JNF &WFOU

    .BJO5ISFBE 5BTL 'SBNF 5BTL 5BTL 5BTL 'SBNF 'SBNF 'SBNF 'SBNF 'SBNF ❌ ❌ .BJO5ISFBE
  5. P⒎UIFNBJOUISFBE w 8FC8PSLFS౳Λ࢖༻ͯ͠ϝΠϯεϨουͷॲཧΛ෼ׂ͢Δ 5BTL 'SBNF 'SBNF 'SBNF 'SBNF 'SBNF 'SBNF

    .BJO5ISFBE 5BTL 'SBNF 5BTL 5BTL 5BTL 'SBNF 'SBNF 'SBNF 'SBNF 'SBNF ❌ ❌ .BJO5ISFBE 5BTL 8PSLFS 5BTL 5BTL 5BTL 5BTL 5BTL 5BTL 5BTL
  6. 3VTUͱ8FCϑϩϯτΤϯυ։ൃ w ϗοτεϙοτΛ3VTUͰ࣮૷ w XBTNQBDL౳Ͱ+BWB4DSJQU༻ͷύοέʔδΛ։ൃ w 8FC"TTFNCMZͷॲཧΛ8PSLFSʹ෼཭ w ΞϓϦέʔγϣϯશମΛ3VTUͰ࣮૷ w

    3VTU࣮૷ͷ8FCϑϩϯτΤϯυϑϨʔϜϫʔΫ w :FXɺ1FSDZɺ4FFEɺFUD w 3VTUͰͷεϨουෛՙ෼ࢄΛߟ͑Δඞཁ͕͋Δ
  7. 8FCϑϩϯτΤϯυͷεςʔτ؅ཧ w 6*G TUBUF  w ΞϓϦέʔγϣϯͷঢ়ଶ؅ཧͱϏϡʔߏஙΛ෼཭ w ७ਮؔ਺ܕͷύϥμΠϜΛΠϯεύΠΞ IUUQTHJUIVCDPNGBDFCPPLqVYUSFFNBTUFSFYBNQMFTqVYDPODFQUT

  8. εςʔτ؅ཧͱP⒎UIFNBJOUISFBE w ϗοτεϙοτͱͳΔΑ͏ͳεςʔτߋ৽Λ8PSLFSʹҕৡ w Πϕϯτൃੜͨ͠Β8PSLFSΛݺͼग़͠ɺ ॲཧ݁ՌΛϝΠϯεϨουʹฦ͢ 4UBUF "DUJPO &WFOU .BJO5ISFBE

    8PSLFS 7JFX
  9. :FXͷ"HFOUT w IUUQTZFXSTEPDTFODPODFQUTBHFOUT w ΞΫλʔϞσϧʹΑͬͯ8FC8PSLFSʹॲཧΛҕৡ w 3VTUͰͷ8FC8PSLFSͷݺͼग़͠ΛӅṭ 6QEBUF )BOEMF*OQVU &WFOU

    "QQMJDBUJPO 6QEBUF "HFOU 7JFX )BOEMF*OQVU
  10. 8PSLFSଆͷίʔυ w ϥΠϑαΠΫϧͷॲཧ w DSFBUF w VQEBUF w IBOEMF@JOQVU 27

    impl Agent for Worker { 28 type Reach = Public<Self>; 29 type Message = Msg; 30 type Input = Request; 31 type Output = Response; 32 33 fn create(link: AgentLink<Self>) -> Self { 34 let duration = Duration::from_secs(3); 35 let callback = link.callback(|_| Msg::Updating); 36 let task = IntervalService::spawn(duration, callback); 37 Worker { 38 link, 39 _task: Box::new(task), 40 } 41 } 42 43 fn update(&mut self, msg: Self::Message) { 44 match msg { 45 Msg::Updating => { 46 info!("Tick..."); 47 } 48 } 49 } 50 51 fn handle_input(&mut self, msg: Self::Input, who: HandlerId) { 52 info!("Request: {:?}", msg); 53 match msg { 54 Request::GetDataFromServer => { 55 // TODO fetch actual data 56 self.link.respond(who, Response::DataFetched); 57 } 58 } 59 } 60 61 fn name_of_resource() -> &'static str { 62 "worker.js" 63 } 64 }
  11. ΞϓϦଆͷίʔυ 19 impl Component for Model { 20 type Message

    = Msg; 21 type Properties = (); 22 23 fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { 24 let callback = link.callback(|_| Msg::DataReceived); 25 let worker = Worker::bridge(callback); 26 27 Model { link, worker } 28 } 29 30 fn update(&mut self, msg: Self::Message) -> ShouldRender { 31 match msg { 32 Msg::SendToWorker => { 33 self.worker.send(Request::GetDataFromServer); 34 } 35 Msg::DataReceived => { 36 info!("DataReceived"); 37 } 38 } 39 true 40 } 41 42 fn view(&self) -> Html { 43 html! { 44 <div> 45 <nav class="menu"> 46 <button onclick=self.link.callback(|_| Msg::SendToWorker)>{ "Send to Thread" }</button> 47 </nav> 48 </div> 49 } 50 } 51 52 fn change(&mut self, _props: Self::Properties) -> ShouldRender { 53 false 54 } 55 }
  12. Ϗϧυ w ΞϓϦଆͱ8PSLFSଆΛͦΕͧΕϏϧυ 1 const path = require("path"); 2 const

    WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin"); 3 4 module.exports = { 5 plugins: [ 6 new WasmPackPlugin({ 7 crateDirectory: path.resolve(__dirname, "crates/app"), 8 args: "--log-level warn", 9 extraArgs: "--target web --no-typescript", 10 outDir: path.resolve(__dirname, "public"), 11 outName: "app", 12 }), 13 new WasmPackPlugin({ 14 crateDirectory: path.resolve(__dirname, "crates/worker"), 15 args: "--log-level warn", 16 extraArgs: "--target no-modules --no-typescript", 17 outDir: path.resolve(__dirname, "public"), 18 outName: "worker", 19 }), 20 ], 21 devServer: { 22 contentBase: path.join(__dirname, "public"), 23 compress: true, 24 port: 9000, 25 }, 26 };
  13. ݱঢ়ͷ՝୊ w ϝΠϯεϨουͱ8PSLFSͰͷίʔυͷॏෳ w ݱঢ়Ͱ͸8PSLFSͷίʔυ΋ϝΠϯͷίʔυʹؚ·ΕΔ w γϦΞϥΠθʔγϣϯͷΦʔόʔϔου w Ծ૝%0.ͷॲཧ͸·ͩϝΠϯεϨου w

    8FC"TTFNCMZ5ISFBET͕͋Ε͹վળՄೳʁ
  14. ·ͱΊ w 8FCϑϩϯτΤϯυ։ൃͰ͸ɺϝΠϯεϨουͷΞΠυϧ࣌ ؒΛ૿΍͢͜ͱ͕ॏཁ w ΞϓϦέʔγϣϯશମΛ3VTUͰ࣮૷͢Δ৔߹ɺ ैདྷ+BWB4DSJQU։ൃऀ͕ߦ͖ͬͯͨ 8FCͷϕετϓϥΫςΟεͷ࣮ફ͕ඞཁ w :FXͷ"HFOUT͸ϝΠϯεϨουͷෛՙ෼ࢄͰ༗༻

  15. 3VTU'FTU(MPCBMͰొஃ͠·͢ʂ w 5IJOL"CPVU'SPOUFOE8FC%FWFMPQNFOUXJUI3VTU w ೥݄ʙ೔ IUUQTSVTUGFTUFV ࢀՃ͓଴͍ͪͯ͠·͢ʂ