Node.js

Node.jsでCPUコアをフルに使って負荷の高い処理ができるかなと思ったらできた

ちきさんです。

Node.jsでCPUコアをフルに使って負荷の高い処理ができるかなと思ったのでやってみました。
cluster APIを使って書いています。

APIの使い方が正しいかどうかはわかりませんが、loadSizeを大きい数字にするとCPUファンがガンガン回るので楽しいです。

super-power.ts
import * as cluster from 'cluster'
import { Subject } from 'rxjs/Rx'
const numCPUs = require('os').cpus().length

interface Message {
  pid: number
  value: number
}


function superPower(): Promise<number[]> {
  const queue$: Subject<number[]> = new Subject()
  let finishCount: number = 0

  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker) => {
    console.log(`worker ${worker.process.pid} died`)
  })

  cluster.on('message', (worker, message) => {
    console.log(`message: ${JSON.stringify(message)} from ${worker.id}`)
    queue$.next(message.value)
    if (++finishCount === numCPUs) {
      cluster.disconnect() // Workerをシャットダウンする。
      queue$.complete() // このタイミングでこの関数の戻り値が返される。
    }
  })

  return queue$
    .startWith([])
    .reduce((p, value) => p.concat(value))
    .toPromise()
}


function workWorkWork(): void {
  const loadSize: number = Math.round(Math.random() * 10000000000)
  let temp = 0
  // CPUコアに負荷をかける。
  for (let i = 0; i < loadSize; i++) {
    temp = temp + i
  }
  const message: Message = { pid: process.pid, value: loadSize }
  process.send!(message)
}


if (cluster.isMaster) {
  superPower()
    .then(value => {
      console.log('result:', value)
    })
} else {
  workWorkWork()
}

出力はこんな感じ。

OUTPUT
message: {"pid":79291,"value":1039512909} from 5
message: {"pid":79289,"value":2097703303} from 3
message: {"pid":79287,"value":3289584265} from 1
message: {"pid":79290,"value":4997136338} from 4
message: {"pid":79288,"value":6719233976} from 2
message: {"pid":79292,"value":7072344527} from 6
message: {"pid":79293,"value":8830078665} from 7
message: {"pid":79294,"value":8978470370} from 8
result: [ 1039512909,
  2097703303,
  3289584265,
  4997136338,
  6719233976,
  7072344527,
  8830078665,
  8978470370 ]
worker 79288 died
worker 79291 died
worker 79290 died
worker 79292 died
worker 79293 died
worker 79289 died
worker 79287 died
worker 79294 died