-
-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show stdout/stderr from Wasm in terminal #472
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self comment
return | ||
} | ||
/// Respond to WebSocket messages coming from the browser. | ||
nonisolated func webSocketTextHandler( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここなんですが、関数を返す関数から、普通のメソッドにしました。
まず、いきなり大きなラムダ式を開くコードはややこしいです。
全体に余計なインデントがずっと入るし、
メソッドとラムダの間で他のインタラクトに気をつけて読まないといけません。
通常のメソッドにした方が、 actor のメソッドとしての解析や制御がちゃんと機能します。
selfの弱参照についても、
根本のクロージャで書いた方がどういうポリシーで管理しているかわかりやすいでしょう。
このメソッド自体についてですが、
同期のクロージャから呼びたいので nonisolated
にしています。
configuration: ServerWebSocketHandler.Configuration( | ||
onText: self.createWebSocketTextHandler(in: environment, terminal: self.configuration.terminal) | ||
onText: { [weak self] (text) in | ||
self?.webSocketTextHandler(text: text, environment: environment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
処理は普通にメソッドで書いて、weak self を明示的に書いた方が、
参照がどうなっているかと、メソッドで何をするか、
という独立な要素がコードとして分離できてシンプルです。
self?.webSocketTextHandler(text: text, environment: environment) | ||
}, | ||
onBinary: { [weak self] (data) in | ||
self?.webSocketBinaryHandler(data: data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
新たにバイナリメッセージのハンドリングを追加します。
+ " we can add support for it: https://github.com/swiftwasm/carton\n", inColor: .gray | ||
) | ||
terminal.write(rawStackTrace + "\n") | ||
let terminal = self.configuration.terminal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self
から取ってきます。
return | ||
} | ||
|
||
var kind: UInt16 = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2バイトのヘッダをつけるフォーマットにしました。
case .testPassed: | ||
Task { await self.stopTest(hadError: false) } | ||
switch kind { | ||
case 1001: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1001はstdoutのチャンクを転送するコマンドです
case 1001: | ||
// stdout | ||
let chunk = data.subdata(in: 2..<data.count) | ||
if chunk.isEmpty { return } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
空の書き込みが来ることがあるので捨てます。
case let .errorReport(output): | ||
terminal.write("\nAn error occurred:\n", inColor: .red) | ||
terminal.write(output + "\n") | ||
for line in Self.decodeLines(data: chunk) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここまではバイナリで来てますが、
最後のこの場所でコンソールに綺麗に出すために文字列処理します。
|
||
Task { await self.stopTest(hadError: true) } | ||
for line in Self.decodeLines(data: chunk) { | ||
terminal.write("stderr: " + line + "\n", inColor: .red) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
エラーは赤くしたんですが色がつきませんでした。
SwiftPMの問題。
swiftlang/swift-package-manager#7589
@@ -44,9 +44,29 @@ const startWasiTask = async () => { | |||
|
|||
const wasmRunner = WasmRunner( | |||
{ | |||
onStdout(chunk) { | |||
const kindBuffer = new ArrayBuffer(2); | |||
new DataView(kindBuffer).setUint16(0, 1001, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
頭に2バイトのヘッダをつけてからwebsocketに流します。
リトルエンディアンにするので true
を指定しています。
JSのバイナリ処理に慣れてなくて書き方がこれでいいか自信がないです。
なんか冗長です。
|
||
case .testPassed: | ||
Task { await self.stopTest(hadError: false) } | ||
switch kind { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reinterpret with UInt16(littleEndian:)
to ensure the bytes are interpreted as little endian
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
なるほど。そういうのがあるんですね。やりました。
背景
現在 dev.js は Wasmのstdoutとstderrをブラウザのコンソールに転送します。
課題
しかしこれを開くにはちょっと手間がかかります。
また、その出力内容を自動テストするのが難しいです。
提案
Wasmが吐いた stdout, stderr を Dev Server まで届けます。
また、それを Dev Server のコンソールに出力します。
様子
アプリのコード
ターミナル
将来の目標
さらに dev server が読み取った内容を外部に伝える機能を追加します。
それを使って Wasmの出力を自動テストできるようになるでしょう。