Skip to content

Latest commit

 

History

History
177 lines (141 loc) · 5.16 KB

20220416.md

File metadata and controls

177 lines (141 loc) · 5.16 KB

今週何知った? week:14

各自発表

[name=ken3ypa]

僕もObservableについて調べてみた

1: 「観察」よりも「通知」

Observerは能動的に観察するのではなく、Subjectから通知されるのを待っている。 そのため、Pub-Sub(Publish - Subsriribe)の表現の方がより適切

image.png (37.1 kB)

2: 1対多の構成

  • Subject(1)-<Observer(多)の関係になる
  • これはMVCにおけるMが1、Vが多の関係と同じ

3: ARにかつて存在していた Observable の仕組み

https://github.com/rails/rails-observers

4: RubyのObservable実装

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 (プロセス間通信) を通じて通信する
    • 各プロセスが独立して動作し、プロセス間で通信を必要としないケースに向いている

cluster モジュール

マルチプロセス化の機能を提供するモジュール

  • 以下のような複数ポートの管理
  • ロードバランサ:子プロセスにリクエストを分散させる
    • スケジューリングポリシー
      • ラウンドロビンポリシー 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)

メモ欄