Skip to content

Parallel Processing

Brenton Ashworth edited this page Jul 1, 2013 · 10 revisions

Parallel Processing

remove any console logging from code that will run in a web worker.

in simulated/services.cljs, update services-fn to.

(defn services-fn [message input-queue]
  (when (and (= (msg/topic message) [:active-game]) (:value message))
    (start-game-simulation input-queue)))

Using Web Workers with the simulated back end

create a new aspect which will run the simulated game with a web worker

:worker-ui {:uri "/tutorial-client-dev-worker-ui.html"
            :name "Worker UI"
            :order 2
            :out-file "tutorial-client-dev-worker-ui.js"
            :main 'tutorial_client.simulated.worker_start
            :output-root :tools-public
            :template "application.html"
            :workers {"sim_worker" #{#"tutorial_client/behavior.js"
                                     #"tutorial_client/worker/.*"
                                     #"tutorial_client/simulated/worker.js"
                                     #"tutorial_client/simulated/services.js"}}}

create worker/init.cljs

(ns tutorial-client.worker.init
  (:require [io.pedestal.app.protocols :as p]
            [io.pedestal.app :as app]
            [tutorial-client.behavior :as behavior]
            [tutorial-client.post-processing :as post]
            [tutorial-client.clock :as clock]
            [cljs.reader :as reader]
            [io.pedestal.app.render :as render]))

(defn init! [services-ctor effects-fn]
  (let [app (app/build (post/add-post-processors behavior/example-app))
        services (services-ctor app)
        render-fn (fn [deltas _]
                    (doseq [d deltas]
                      (js/postMessage (pr-str d))))
        app-model (render/consume-app-model app render-fn)]
    (app/consume-effects app effects-fn)
    (app/begin app)
    (clock/increment-game-clock (:input app))
    (js/addEventListener "message"
                         (fn [e]
                           (p/put-message (:input app)
                                          (reader/read-string (.-data e))))
                         false)
    (p/start services)))

create simulated/worker.cljs

(ns tutorial-client.simulated.worker
  (:require [tutorial-client.worker.init :as init]
            [tutorial-client.simulated.services :as services]))

(init/init! services/->MockServices services/services-fn)

create simulated/worker_start.cljs

(ns tutorial-client.simulated.worker-start
  (:require [io.pedestal.app.util.web-workers :as ww]
            [tutorial-client.rendering :as rendering]))

(defn ^:export main []
  (ww/run-on-web-worker! "/generated-js/sim_worker.js"
                         :render {:type :push :id "content" :config rendering/render-config}))

With these changes we can now restart and run the Worker UI aspect.

Using Web Workers for the production app

create a development worker aspect and update production config

:worker-development {:uri "/tutorial-client-worker-dev.html"
                     :use-api-server? true
                     :name "Worker Development"
                     :out-file "tutorial-client-worker-dev.js"
                     :main 'tutorial_client.worker_start
                     :order 4
                     :template "application.html"
                     :workers {"worker" #{#"tutorial_client/behavior.js"
                                          #"tutorial_client/worker/.*"
                                          #"tutorial_client/worker.js"
                                          #"tutorial_client/services.js"}}}
:production {:uri "/tutorial-client.html"
             :use-api-server? true
             :name "Production"
             :optimizations :advanced
             :out-file "tutorial-client.js"
             :main 'tutorial_client.worker_start
             :order 7
             :workers {"worker" #{#"tutorial_client/behavior.js"
                                  #"tutorial_client/worker/.*"
                                  #"tutorial_client/worker.js"
                                  #"tutorial_client/services.js"}}}

in config.clj under :build

:ignore [#"tutorial_client.simulated.worker.js"
         #"tutorial_client.worker.js"]

create worker.cljs

(ns tutorial-client.worker
  (:require [tutorial-client.worker.init :as init]
            [tutorial-client.services :as services]))

(init/init! services/->Services services/services-fn)

and worker-start

(ns tutorial-client.worker-start
  (:require [io.pedestal.app.util.web-workers :as ww]
            [tutorial-client.rendering :as rendering]))

(defn ^:export main []
  (ww/run-on-web-worker! "/generated-js/worker.js"
                         :render {:type :push :id "content" :config rendering/render-config}))

Next steps

The tag for this step is v0.1.7.

Home

Clone this wiki locally