[name=ken3ypa]
Observerは能動的に観察するのではなく、Subjectから通知されるのを待っている。 そのため、Pub-Sub(Publish - Subsriribe)の表現の方がより適切
- Subject(1)-<Observer(多)の関係になる
- これはMVCにおけるMが1、Vが多の関係と同じ
https://github.com/rails/rails-observers
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 p.148
- マルチスレッド
- スレッド間通信:スレッド間でメモリ空間などのリソースを共有している
- プロセス間の通信が頻繁・メッセージが大きいケースに向いている
- e.g. フィボナッチ数の計算
- マルチプロセス
- プロセス間通信:IPC (プロセス間通信) を通じて通信する
- 各プロセスが独立して動作し、プロセス間で通信を必要としないケースに向いている
- e.g. Web アプリケーションの並列化
マルチプロセス化の機能を提供するモジュール
- 以下のような複数ポートの管理
- 通常ひとつのポートに同時にアクセスできるプロセスはひとつだけ
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
内部的には child_process
モジュールを利用している
// fork メソッドの引数にサブプロセスで実行したいファイルを指定する
const child = child_process.fork('./ipc/web-app')
child.send(3000)