Skip to content

Commit

Permalink
fix exercise 2 and add exercise 3
Browse files Browse the repository at this point in the history
  • Loading branch information
kimamula committed Dec 22, 2019
1 parent d8f2d20 commit ae39f24
Showing 1 changed file with 48 additions and 23 deletions.
71 changes: 48 additions & 23 deletions src/ch08/exercises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function createProtocol<P extends Protocol>(script: string) {
new Promise<P[K]['out']>((resolve, reject) => {
let worker = new Worker(script)
worker.onerror = reject
worker.onmessage = event => resolve(event.data.data)
worker.onmessage = event => resolve(event.data)
worker.postMessage({command, args})
})
}
Expand All @@ -73,32 +73,57 @@ parallelDeterminant([[1, 2], [3, 4]]).then(

// WorkerScript.ts

let handlers: {
[C in keyof MatrixProtocol]: (
...args: MatrixProtocol[C]['in']
) => MatrixProtocol[C]['out']
} = {
determinant(matrix) {
return determinant(matrix)
},
['dot-product'](a, b) {
return dotProduct(a, b)
},
invert(matrix) {
return invert(matrix)
type Data<
P extends Protocol,
C extends keyof P = keyof P
> = C extends C
? { command: C; args: P[C]['in'] }
: never

function handle(data: Data<MatrixProtocol>): MatrixProtocol[typeof data.command]['out'] {
switch (data.command) {
case 'determinant':
return determinant(...data.args)
case 'dot-product':
return dotProduct(...data.args)
case 'invert':
return invert(...data.args)
}
}

onmessage = <C extends keyof MatrixProtocol>({
data: {command, args}
}: {
data: {command: C; args: MatrixProtocol[C]['in']}
}) => {
let handler = handlers[command]
let result = handler(...args)
postMessage(result)
}
onmessage = ({data}) => postMessage(handle(data))

declare function determinant(matrix: Matrix): number
declare function dotProduct(matrixA: Matrix, matrixB: Matrix): Matrix
declare function invert(matrix: Matrix): Matrix

// 3. Use a mapped type (as in 「8.6.1 In the Browser: With Web Workers★」) to implement a typesafe message-passing protocol for NodeJS's `child_process`.

// MainThread.ts
import {fork} from 'child_process'

function createProtocolCP<P extends Protocol>(script: string) {
return <K extends keyof P>(command: K) => (...args: P[K]['in']) =>
new Promise<P[K]['out']>((resolve, reject) => {
let child = fork(script)
child.on('error', reject)
child.on('message', resolve)
child.send({command, args})
})
}

let runWithMatrixProtocolCP = createProtocolCP<MatrixProtocol>(
'./ChildThread.js'
)
let parallelDeterminantCP = runWithMatrixProtocolCP('determinant')

parallelDeterminantCP([[1, 2], [3, 4]]).then(
determinant => console.log(determinant) // -2
)

// ChildThread.ts

// type Data ...
// function handle ...

process.on('message', data => process.send!(handle(data)))

0 comments on commit ae39f24

Please sign in to comment.