# 今週何知った? week:14 ## 各自発表 > [name=ken3ypa] ## 僕もObservableについて調べてみた ### 1: 「観察」よりも「通知」 Observerは能動的に観察するのではなく、Subjectから通知されるのを待っている。 そのため、Pub-Sub(Publish - Subsriribe)の表現の方がより適切 <img width="1339" alt="image.png (37.1 kB)" src="https://img.esa.io/uploads/production/attachments/9475/2022/04/16/39171/70f1a2ab-8c98-4406-a947-d8c46b622065.png"> ### 2: 1対多の構成 - Subject(1)-<Observer(多)の関係になる - これはMVCにおけるMが1、Vが多の関係と同じ ### 3: ARにかつて存在していた Observable の仕組み https://github.com/rails/rails-observers ### 4: RubyのObservable実装 ```ruby module Observable # { # <LowPriceNotifier:0x000000011e97ebf8 @limit=235000>=>:update, # <HighPriceNotifier:0x000000011e97e8b0 @limit=255000>=>:update # } def add_observer(observer, func = :update) @observer_peers = {} unless defined? @observer_peers unless observer.respond_to? func raise NoMethodError, "observer does not respond to `#{func}'" end @observer_peers[observer] = func end def delete_observer(observer) @observer_peers.delete observer if defined? @observer_peers end def delete_observers @observer_peers.clear if defined? @observer_peers end def count_observers if defined? @observer_peers @observer_peers.size else 0 end end def changed(state = true) @observer_state = state end def changed? if defined? @observer_state and @observer_state true else false end end def notify_observers(*arg) if defined? @observer_state and @observer_state if defined? @observer_peers @observer_peers.each do |k, v| k.send v, *arg end end @observer_state = false end end end class Publisher include Observable def run loop do price = Price.fetch changed # notify observers notify_observers(Time.now, price) sleep 1 end end end class Price def self.fetch rand(230_000..260_000) end end class Subscriber def initialize(publisher, limit) @limit = limit publisher.add_observer(self) end end class LowPriceSubscriber < Subscriber def update(time, price) # callback for observer if price < @limit print "#{time.to_s}: 購読者Aが#{price}円で購入しました!(設定価格 #{@limit}円)\n" end end end class HighPriceSubscriber < Subscriber def update(time, price) # callback for observer if price > @limit print "#{time.to_s}: 購読者Bが#{price}円で購入しました!(設定価格 #{@limit}円)\n" end end end publisher = Publisher.new LowPriceSubscriber.new(publisher, 235_000) HighPriceSubscriber.new(publisher, 255_000) publisher.run ``` > [name=makicamel] ## マルチプロセス、マルチスレッド - `cluster` モジュール マルチプロセス化の機能を提供する - `worker_threads` モジュール Node.jx v10 以降、コア API として提供されている。マルチスレッドプログラミングを可能にする  ー [ハンズオン Node.js](https://www.oreilly.co.jp/books/9784873119236/) p.148 ### マルチスレッドとマルチプロセスの向き不向き - マルチスレッド - スレッド間通信:スレッド間でメモリ空間などのリソースを共有している - プロセス間の通信が頻繁・メッセージが大きいケースに向いている - e.g. フィボナッチ数の計算 - マルチプロセス - プロセス間通信:IPC (プロセス間通信) を通じて通信する - 各プロセスが独立して動作し、プロセス間で通信を必要としないケースに向いている - e.g. [Web アプリケーションの並列化](https://github.com/makicamel/til/blob/d101769/books/hands_on_nodejs/part4/ipc/multi-process.js) ### `cluster` モジュール マルチプロセス化の機能を提供するモジュール - 以下のような複数ポートの管理 - 通常ひとつのポートに同時にアクセスできるプロセスはひとつだけ - `cluster.fork()` でフォークされたサブプロセス同士は IPC を通じてポートを共有できる - ref https://github.com/makicamel/til/blob/d101769/books/hands_on_nodejs/part4/ipc/ - ロードバランサ:子プロセスにリクエストを分散させる - スケジューリングポリシー - ラウンドロビンポリシー `cluster.SHED_RR` - Linux・OSX でデフォルトで有効 - OS に任せる `cluster.SCHED_NONE` - Windows でデフォルトで有効 ref [Node.jsのClusterをセットアップして、処理を並列化・高速化する | POSTD](https://postd.cc/setting-up-a-node-js-cluster/) 内部的には [`child_process`](https://nodejs.org/api/child_process.html) モジュールを利用している ```javascript // fork メソッドの引数にサブプロセスで実行したいファイルを指定する const child = child_process.fork('./ipc/web-app') child.send(3000) ``` ## メモ欄
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up