技術探し

JavaScriptを中心に記事を書いていきます :;(∩´﹏`∩);:

アクセスを調査した

今回のブログが予想以上にアクセスが多く、面白そうだったので調査資料として残したいと思いました。

abouthiroppy.hatenablog.jp

金曜日と土曜日と日曜日で調査しました。

アクセス数

f:id:about_hiroppy:20171204092833p:plain f:id:about_hiroppy:20171204093958p:plain

金曜日が14438人で土曜日が4742人で日曜日が609人でした。
日曜日になると通常ぐらいに落ち着いてきました。

調査

投稿時間は金曜日の10:30です。
今回の伸びた要因ははてなブログのトップにのったことだと思います。

はてなブログ

hatenablog.com f:id:about_hiroppy:20171202112251p:plain

これはどのように選別されているのか知らないが中の人が手動で決めている気がしますが、指標がわからないです。。

投稿してから毎時間1000人以上流入があったので投稿してすぐにおそらくはてなブログのトップに乗ったと思われます。
土曜日の18:00にはトップからいなくなっていました。

はてなブックマーク

ホッテントリには金曜日はずっと入っていたが、土曜日には入っていなかったです。

f:id:about_hiroppy:20171204093324p:plain

流入

f:id:about_hiroppy:20171204093916p:plain

smartnewsに上がると流入がかなり増えます。
基本的に、経験上総合のホッテントリでなくてもITとかでsmartnewsにのります。
smartnewsに上がる前ははてなブログが一番でした。

f:id:about_hiroppy:20171203174340p:plain

流入バイス

f:id:about_hiroppy:20171203174315p:plain

モバイル多すぎっ!

GA

はてなアクセス解析とGAの数値に差異があるのはおそらくアドブロックのせいだと思われます。

金曜日

f:id:about_hiroppy:20171203174554p:plain f:id:about_hiroppy:20171203174614p:plain

土曜日

f:id:about_hiroppy:20171203174839p:plainf:id:about_hiroppy:20171203174911p:plain

日曜日

f:id:about_hiroppy:20171204093231p:plainf:id:about_hiroppy:20171204093255p:plain

時間別アクセス数

これを見るとわかるように、投稿してからすぐにはてなブログのtopに乗ったと思われます。

f:id:about_hiroppy:20171204093146p:plain

一番多かったのは、土曜日の午後12時で1052人でした。

結論

  • 平日は、昼休みの時間帯である11時 - 12時近くに見る人が多い
  • 意外にも1時でも見ている人がいる(これはエンジニアだけ?)
  • モバイルが60%以上を占めている
  • 案外、google / organicの流入が多いがwww.smartnews.comが二番手に多い
  • GAブロックしている人多い(?)

メルカリを退職した

6ヶ月でしたが、退職することになりました。
本当にありがとうございます。

環境

アメリカと日本のプロダクトで活動していて、フロントエンドチームに所属していました。
特にメンターでチームリーダの方からは、多くの配慮をしていただき入社してからずっと助けて貰ってました。
もちろん、周りの皆さんにも助けて貰っていて、このような結果になってしまい本当に申し訳ないと思っています。
メルカリですが、日本で開発をしながら英語も使えるいい環境でした。
開発の相方が外国人の方で、英語を喋る機会が多かったです。個人的にはもっと日本の会社は多様性・グローバル化をしてほしいと思っています。
特に多様性の部分は自分が気付かない視点を持っている方が多かった印象です。
また、シャッフルランチやメンターランチのような会社からのサポートで知らない方や新しく入った方とご飯に行くサービスも好きでした。
これにより、多くの方と知り合えた気がします。

転職について

転職を決意してから今日に至るまで、複数の企業様からオファーをいただきました。 本当に感謝しています。
そして、入社できない企業様に対し本当に申し訳なく思っています。

新天地では、今以上に活躍できるように努力していきたいと思います。
また、OSSはもちろん、日本でもJSのコミュニティの活動等を引き続きしていきたいです。
ここでのブログのアウトプットも今のところ1 ~ 2週間ペースで記事を更新しているので今後も継続させたいと思っています。

それでは今後共、何卒よろしくお願いします。

Node学園祭2017資料まとめ

nodefest.jp

2017/11/25, 26で開催されました。

今回は、前回よりも更にto be more more globalをテーマに作っていきました。

一日目はセッション、スポンサートーク、LT等でした。
二日目はセッションと参加者が手を動かすワークショップを行いました。
両日ともに、3ラインで進みました。

自分は一日目はBホール(402)の司会をしていて、二日目はCode And LearnでNodeへのコミットのサポートをしていました。

全部見れてないので、わかっている部分の資料だけ貼りたいと思います。
もし資料があったら教えてくれるとついったーとかでください。

Twitter

ハッシュタグ

twitter.com

モーメント

東京Node学園祭 2017 / Twitter

資料まとめ

スケジュールはこちらを参照してください。
時間順で並べてあります。

1日目

Opening talk

見つからない。

Node.js at Alibaba

talks/nodejs_at_alibaba_tokyo.pdf at master · joyeecheung/talks · GitHub

Source to Binary - journey of V8 javascript engine

Source to Binary - journey of V8 javascript engine - Speaker Deck

Alt-Ctrl: Scream Into this Arduino!

Node Interactive から

Alt-Ctrl : Scream into this Arduino - Rachel White, Front End Engineer - YouTube

Open Source Governance Models: From BDFL to Consensus Seeking

Node Interactive から

Open Source governance models · Myles Borins - YouTube

Make you a React: How to build your own JavaScript framework

MakeYouAReact - Google スライド

Node.js Production Checklist

Node.js production checklist - Speaker Deck

The JavaScript Engine in Node.js: TurboFan and Ignition

https://fhinkel.github.io/JSEngines-HowDoTheyEven/NodeFest/assets/player/KeynoteDHTMLPlayer.html

Node.js x Chrome headless で、お手軽WebRTC MCU

Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で…

WebAssembly and the Future of the Web

Node Interactive から

WebAssembly and the Future of the Web [I] - YouTube

標準化ってなに? Webプラットフォーム/ESNextを作る方法

Web Platform ... What is it ? (Webプラットフォームのつくり方) - Speaker Deck

ReactNativeアプリでE2Eテストを回してみた

React NativeアプリでE2Eテストを回してみた - Speaker Deck

No REST for the weary... Introducing GraphQL

No REST for the weary... Introducing GraphQL (NodeFest Japan) - Speaker Deck

Turbo Boost Next Node.js

Turbo Boost Next Node.js - Speaker Deck

今さら聞けないSPAのCORS対策の話

今さら聞けないSPAのCORS対策の話 - Speaker Deck

A Toy Robot and a Functional Pattern

http://robhoward.id.au/talks/2017/11/a-toy-robot-and-a-functional-pattern.pdf

Native ES Module - something almost, but not quite entirely unlike CommonJS

Native ES Modules - something almost, but not quite entirely unlike CommonJS - NodeFestJP - Google スライド

サーバサイドエンジニアがJavaScriptを書いてTradingViewを導入した話

How_To_ Introduce_TradingView - Speaker Deck

Quantum Computing in Node

Quantum Computers and Where to Hide from Them (Japanese)

Sponsor's talk

Sponsors | 東京Node学園祭2017 | 11月25日,26日開催予定!

株式会社ドワンゴ

N予備校プログラミングコースでのNode.js - Speaker Deck

リクルートテクノロジー

見つからない。

株式会社メルカリ

Node 学園祭 2017 スポンサートーク資料 - Speaker Deck

株式会社ヤフー

Node学園祭2017.pdf - Speaker Deck

日産自動車株式会社

https://www.wantedly.com/projects/156247

Auth0® Inc.

見つからない。

Lightning Talks

Angular Universal

SSR with Angular

2017版、React、Lambda、S3で始めるモダンなユーザーデータ可視化ツール

見つからない。

How TypeScript can simplify design decision

https://speakerdeck.com/noraesae/how-typescript-can-simplify-design-decision

Introduction to Visual Regression Testing

Introduction to Visual Regression Testing - Speaker Deck

Whose Community?

Whose Community? - about NodeGirlsJP - Speaker Deck

2日目

Opening talk

見つからない。

Node Discussion

Nodeのメンバーに色々と聞くコーナー。
Nodeのいいところ・悪いところ・要望などを伝えて答える。

Node School

Nodeの勉強をするコーナー。
メンターが付いており、もし躓いたらすぐに聞ける。

Angular2+ Authentication Tutorial with Auth0

Reactに変わった気がするが、タイトルがどこにあるかわからなかったので一旦。
Auth0で働く方に使い方を教えてもらうコーナー。

Sharing is Caring… At Scale!

Node Conf EUから

Sharing is Caring… At Scale! - Sarah Saltrick Meyer - YouTube

LINE Bot Handson

1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest - Qiita

data sketches: A Visualization a Month

見つからない。

Real-world applications of hash functions

見つからない。

JSON Schema Centralized Design

JSON Schema Centralized Design - Speaker Deck

Code And Learn

コミッターがサポートしてNodeへコミットします。

Code And Learn at NodeFest 2017 · Issue #72 · nodejs/code-and-learn · GitHub

Data Visualization Workshop

data sketches: A Visualization a Monthのワークショップ。

Data visualization workshop

Lightning Talks

Self Driving Kit using Android and Node.JS

見つからない。

Node.js × AWS Lambda アプリケーション開発Tips

【東京Node学園祭2017】Node.js × AWS Lambda アプリケーション開発Tips

レスポンシブから逆戻り!?Webサービスのマルチデバイス対応方法

レスポンシブから逆戻り!?Webサービスのマルチデバイス対応方法 (東京Node学園祭 2017)

参加者のブログ

ありがとうございます:)
もし他にも書いている方がいたら教えてください!

yurufuwa-tech.hatenablog.com

https://blog.kadoppe.com/%E6%9D%B1%E4%BA%ACnode%E5%AD%A6%E5%9C%92%E7%A5%AD2017-2%E6%97%A5%E7%9B%AE-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-nodefest-5f92028305cbblog.kadoppe.com

さいごに

運営の仲間のみんな、スポンサーの企業様、参加者のみなさん、本当にありがとうございました。

また来年お会いしましょう!!

Node.jsのドキュメント管理について

じいちゃんが米寿なため、実家で書いています。
あと家族増えてました👨‍👨‍👦‍👦
左の4ヶ月の子。

先日、こちらのOSSドキュメント勉強会で話しました。

kbkz.connpass.com

今回はスライドの要約です。

how to manage the document of Node.js

ドキュメントの重要性

f:id:about_hiroppy:20171120021722p:plain

opensource.guide

ドキュメントは大変重要で、ドキュメントが豊富かどうがでそのフレームワーク・ライブラリが使用されるかどうかも左右されると私は思います。

また、ドキュメントの貢献はOSSへの最初のワンステップとしてはちょうどよく貴重なコミットです。

例えばフレームワークであれば、APIの仕様以外にもexamplesを含めget-startedがあればユーザに優しいと思います。

Node.js Foundationについて

Node.jsはNode.js Foundationというところで管理されています。
Node.js github.com

ここでは、約600人の人々が約120チームに分かれて活動をしています。
また、チームとしては34ヶ国語のサポートがされています。
基本的にissueは英語以外でも問題ないという認識です。

Node.js

github.com

  • 19,914commits
  • 457 releases
  • 1790 contributors
  • 2,527 watchers
  • 42,472 stars
  • 8,831 forks

Node.の中には様々なドキュメントがあります。
以下は一例です。

  • BUILDING.md
  • CHANGELOG.md
  • CODE_OF_CONDUCT.md
  • COLLABORATOR_GUIDE.md
  • CONTRIBUTING.md
  • CPP_STYLE_GUIDE.md
  • GOVERNANCE.md
  • API Documentation

今回はAPIドキュメントについて話しました。

APIドキュメント

Docs | Node.js

nodejs.orgにあるのですが、APIドキュメントだけはNodeの.jsコアにあります。
なのでサイトの管理はnodejs/websiteチームですが、APIドキュメントはnodejs/collaboratorチームが行います。

コミット数

$ git log --grep doc: --pretty=oneline --check | wc
    3367   20994  237596

Node.jsではコミットのルールがあり、エコシステムが必ず先頭につきます。
ドキュメントの場合は、doc: です。

コミット数は3367でした。ちなみにテストは2853でおそらくエコシステムの中で一番多いコミット数だと思います。

issue/prのコメント数によるラベルの種類

f:id:about_hiroppy:20171121085509p:plain

One Week in the Life of Node.js

レビュワー

  • Collaborators
    • PRを承認する権利を持つので必須
  • Documentation
  • Website
    • 主にスタイル
  • その他モジュールに特化したWG(e.g. promise, stream, V8, etc...)

レビューをするポイント

  • typo
  • プラットフォームの依存
    • e.g. これはwindowsでは動かない等
  • コーナーケース
    • e.g. この場合は動かない等
  • 英語修正
    • もちろん、完璧な英語じゃなくても問題ないと思ってます

スタイルガイド

多いので言いたかったのだけ抜粋。

  • ファイル名はlowercase-with-dashes.md
    • jsのファイル名やモジュール名は-が多い(特に昔は)
  • I, we, you, his, guysなどは避ける
    • they, folks, people, developersなどを使う

github.com

Pronouns  |  Google Developer Documentation Style Guide  |  Google Developers

書き方

## module
<!-- YAML
added: v0.10.0
-->

> Stability: 3 - Stable

description and examples.

### module.property
<!-- YAML
added: v0.10.0
-->

* Type

description of the property.

### module.someFunction(x, y, [z=100])
<!-- YAML
added: v0.10.0
-->

* `x` {String} the description of the string
* `y` {Boolean} Should I stay or should I go?
* `z` {Number} How many zebras to bring.

A description of the function.

github.com

yamlの部分はバージョンの管理でそのモジュールが足されたとかの履歴を表示します。

markedjs-yamlを使いHTMLに変換します。
lib/<module>.jsdoc/api/<module>.mdが必ず1:1の対応になります。

オートメーション

CI

Node.js [Jenkins]

CIはNode.js Foundationから提供されているJenkinsを使います。
ここでは様々なプラットフォーム上でテストが行われます。
ドキュメントでは主にスモークテストとlintのテストが実行されます。

Lint

ESLintを使っています。

eslint.org

コアコードと同じルールを適応することにより、コードの書き方の統一化を行っています。

# Makefile

LINT_JS_TARGETS = benchmark doc lib test tools
LINT_JS_CMD = tools/eslint/bin/eslint.js --cache \
    --rulesdir=tools/eslint-rules --ext=.js,.mjs,.md \
    $(LINT_JS_TARGETS)

またdoc内にもeslintrc.ymlがあり、そこで適応できない部分がある場合は上書きしています。

ドキュメントをビルドする

HTMLへ変換します。

$ ./configure && make doc

./configureでNode.jsを生成して、それを使いdocを生成します。
そうすると以下のようなファイルが生成されます。

f:id:about_hiroppy:20171121091349p:plain

サポートツール

Node.jsではまだ使われてませんが、便利なツールを紹介しました。

APIの翻訳

ターゲットとの差分(行が増えた, 消えた等)が見やすく、複数人で翻訳がしやすいサービスです。 GoogleのプロダクトやVueなどで使われています。

gitlocalize.com

英語のタイポ検知

以前、PRでこれを使って修正したというのが来てこのツールを知りました。
修正もしてくれます。

github.com

まとめ

  • ドキュメントはめっちゃめっちゃ大切
  • 英語の主語には注意する
  • 自動化しよう

Code and Learn

来週のNode学園祭の2日目では、Code and Learnと呼ばれるNode.jsへコントリビュートする企画があります。
実際に世界中のNode.jsのコアメンバーの人たちがサポートをし、Node.jsへコミットします。大変おもしろい企画ですので是非参加してみてください:)

そのときに役に立てばいいなと思います。

nodefest.jp

Node.jsのパフォーマンスチューニングのtips

Node9が10/31に出ました🎉🎉🎉

Node v9.0.0 (Current) | Node.js

今回はNode単体の話なので、Express、Nginx等のチューニングに関してはココには書きません。
また、libuv等のコード内部の話もしません。

--inspect, --inspect-brk

もともとあった、--debugから移行されました。(v8.0.0 ~)
Chromeを使いデバッグ、プロファイリング等を使えるようになります。
ブラウザで使えるので、いつも使っている感じと同じです。
--inspect-brk--debug-brkと同様に最初の行にブレークポイントを設置し、起動します。

$ node --inspect test.js
Debugger listening on ws://127.0.0.1:9229/b565921e-23f2-4cee-b124-33e97fc3aa32
For help see https://nodejs.org/en/docs/inspector

chromeからchrome://inspect/#devicesを指定すると以下のように選択肢がでるので、そこからinspectを選ぶと起動します。
f:id:about_hiroppy:20171105204518p:plain

インスペクターのクライアント一覧: Debugging - Getting Started | Node.js
Inspector Help | Node.js
個人的には、NiMを入れると楽かなーと思います。
abouthiroppy.github.io

--trace-opt, --trace-deopt

コードの最適化の解析を行います。

$ node --trace-opt test.js
[marking 0x3ad0f4375d1 <JSFunction normalizeStringPosix (sfi = 0x3ad423d7d81)> for optimized recompilation, reason: hot and stable, ICs with typeinfo: 46/67 (68%), generic ICs: 0/67 (0%)]
[compiling method 0x3ad0f4375d1 <JSFunction normalizeStringPosix (sfi = 0x3ad423d7d81)> using TurboFan]
[optimizing 0x3ad0f4375d1 <JSFunction normalizeStringPosix (sfi = 0x3ad423d7d81)> - took 1.867, 1.776, 0.019 ms]
[completed optimizing 0x3ad0f4375d1 <JSFunction normalizeStringPosix (sfi = 0x3ad423d7d81)>]
[marking 0x3ad423fcee1 <JSFunction Module._nodeModulePaths (sfi = 0x3ad423ba5a1)> for optimized recompilation, reason: hot and stable, ICs with typeinfo: 23/23 (100%), generic ICs: 0/23 (0%)]
[compiling method 0x3ad423fcee1 <JSFunction Module._nodeModulePaths (sfi = 0x3ad423ba5a1)> using TurboFan]
[optimizing 0x3ad423fcee1 <JSFunction Module._nodeModulePaths (sfi = 0x3ad423ba5a1)> - took 0.659, 3.009, 0.049 ms]
[completed optimizing 0x3ad423fcee1 <JSFunction Module._nodeModulePaths (sfi = 0x3ad423ba5a1)>]

markingは再コンパイル用のマーキングで、それは再コンパイルされ最適化されます。
最適化が不可能な場合は、マーキングの代わりにdisabled optimizationというのが付きます。

上記をみればわかるように、その関数が最適化されたかどうかがわかります。

--prof

CPUプロファイリングです。 V8内のプロファイラの実行をサンプリングします。

$ node --prof test.js
$ ls
isolate-0x103000000-v8.log test.js
$ node --prof-process isolate-0x103000000-v8.log # logは読みづらいので読めるようにする

各セクションごとに情報が分かれます。

 [Summary]:
   ticks  total  nonlib   name
      3    5.0%    5.0%  JavaScript
     50   83.3%   83.3%  C++
      1    1.7%    1.7%  GC
      0    0.0%          Shared libraries
      7   11.7%          Unaccounted

取得されたサンプルの比率(5.0%, 83.3%, etc...)が割合となり、その言語のコードで発生したことを示します。
そして、各セクションを見るといいと思います。

セクション例

   ticks parent  name
   6326   44.2%  /lib/x86_64-linux-gnu/libm-2.15.so
   6325  100.0%    LazyCompile: *exp native math.js:91
   6314   99.8%      LazyCompile: *calculateMandelbrot http://localhost:8080/Demo.js:215

各セクションは、ツリーになっており、この場合は親コールの合計時間における44.2%がシステム内のmath.exp()を実行するのに使われています。
関数名の前の*はその時間が最適化された関数で費やされていることを示し、~の場合は最適化された関数ではないことを示します。

詳しくは公式が出している以下の記事を見ると、手順がわかりやすいと思います。
Easy profiling for Node.js Applications | Node.js

github.com

--trace-events-enabled

トレース情報を管理します。
--trace-events-enabledフラグを渡すと有効化されます。
カテゴリを指定したい場合は、--trace-event-categoriesを使い続けてカテゴリを指定します。
カテゴリデフォルトはnodev8になります。
chromechrome://tracing/を指定することにより、生成したのをロードすることが可能です。

$ node --trace-events-enabled test.js
$ node --trace-events-enabled --trace-event-categories v8,custom-category test.js

f:id:about_hiroppy:20171105200300p:plain

Tracing | Node.js v9.0.0 Documentation github.com www.chromium.org

--trace-gc

Garbage Collectionのトレースです。
メモリリークデバッグに役立つでしょう。

$ node --trace-gc test.js
[43929:0x102801c00]       39 ms: Scavenge 3.4 (6.3) -> 3.1 (7.3) MB, 0.9 / 0.0 ms  allocation failure
[43929:0x102801c00]       50 ms: Scavenge 3.6 (7.3) -> 3.5 (8.3) MB, 1.2 / 0.0 ms  allocation failure

$ node --optimize_for_size --max_old_space_size=4096 --gc_interval=100 #このようにV8のGCを操作することも可能

--expose-gcを指定することにより、手動でGCを起こすことも可能です。

メモリリーク周りは以下の記事を参考にするとわかりやすくていいと思います。

postd.cc

実例

github.com

node-report

公式が出しているモジュールです。
現在、node-reportはCoreとは別で切り分けられておりスタンドアローンですが、将来的にはCoreに入る予定です。
ネイティブのスタックトレース、ヒープ統計情報、プラットフォーム情報、リソース使用状況などが人間が読める形でレポート化されます。

$ npm i node-report
$ node -r node-report test.js
$ cat node-report.20171105.202142.9066.001.txt
================================================================================
==== Node Report ===============================================================
...
Node.js version: v9.0.0
...
================================================================================
==== JavaScript Stack Trace ====================================================
...
================================================================================
==== Native Stack Trace ========================================================
...
================================================================================
==== JavaScript Heap and Garbage Collector =====================================
...
================================================================================
==== Resource Usage ============================================================
...
================================================================================
==== Node.js libuv Handle Summary ==============================================
...
================================================================================
==== System Information ========================================================
...
================================================================================

github.com

Performance Timing API

v8.5.0から入ったブラウザでも使われるAPIです。
現在はStability: 1(実験的)です。

Performance Timing API | Node.js v8.9.0 Documentation

詳しくは以下の記事をどうぞ

abouthiroppy.hatenablog.jp

優しいコードの書き方へ

v8.3.0からV8のTurbofan, IgnitionがデフォルトでCrankshaftから移行され、昔のような最適化のためのコードの書き方をしなくても良くなりました。

abouthiroppy.hatenablog.jp

先日のChrome Dev SummitでもV8チームが今後はそのようなアンチパターンをなくしていくと言っています。(つまりどの書き方をしても同じ結果になる)
また、トランスパイルは気をつけるべきです。
Babelにはbabel-preset-envというターゲットバージョンによりトランスパイルをするツールがあります。
babel-preset-envではNodeのバージョンを指定することにより、V8に優しいコードに変換することが可能です。
すべてのコードをトランスパイルするべきではありません。
基本的にトランスパイルされるコードは無駄な処理が多いからです。(これはそのものがエンジン側で実装されてないため)
なので、エンジン側で未実装なもの(e.g. stage-x)だけをトランスパイルするべきです。

{
  "presets": [
    ["@babel/env", {
      "targets": {
        "node": "current"
      }
    }]
  ]
}

github.com

先日、monorepoのbabelへ移行され次のバージョンではscoped packagesになりました🎉

v8::SnapshotCreator

将来的に入るかもしれませんが、今現在、ArrayBuffersに関して議論中です。

github.com

さいごに

今回は、パフォーマンスチューニングをするのに手助けになる手法を数個列挙してみました。
しかし、Node, V8の最適化周りのオプションの話をするとまだたくさんあるとおもいますが一旦このへんで。
詳しくはnode --v8-optionsへ。--print-code, --print-opt-code, --code-comments --track-heap-objects, etc...
その他には、I/O(libuv)とイベントループの理解も大切だと思います。

もしチューニング等でお困りでしたら、Twitterかメールで聞いてくだされば答えれるかもしれません。

また、今月Node学園祭があるので是非お越し下さい:)

nodefest.jp

Chrome Dev Summitに行ってきた話

SFOで行われたChrome Dev Summitに行ってきました。

developer.chrome.com

メインの話はPWA/AMPだった感じだった。
ただの感想文なので特に技術的な話はココでは無しです。

Chrome Dev Summit2017

f:id:about_hiroppy:20171023080036j:plain f:id:about_hiroppy:20171023081100j:plain f:id:about_hiroppy:20171023095031j:plain f:id:about_hiroppy:20171023080825j:plain f:id:about_hiroppy:20171024154819j:plain f:id:about_hiroppy:20171024123337j:plain

よかったこと

学びが多い

PWA/AMPを進めているGoogleだからこそ自分たちが知らないことを話していて勉強になった。
主に、様々な会社の実例が入っていてよかった。
また、WASM, VR, Media等の自分が詳しくない分野の話を聞けて興味がでた。(特にMedia)
これは後ほど別でまとめますのでお楽しみに;)

海外カンファレンスの敷居が案外低かったことがわかった

実は自分は今回が初の海外カンファレンスだったりする。
知らない外国人の方やあまり話せてなかった日本人の方とも話せてよかった。
(ありがとうございます、及川さん、らこさん、armorik83さん、英志さん、etc...:))
知らない人と技術の話をするのは楽しく、様々な分野(VR, etc...)の方と話していた。
また、有名なコミッターの方も多く、そういう人と会える貴重な機会である。(hzoo, sean larkin, etc...)
行ったことがない人は是非行ってみて欲しいと思った、すごい楽しい。(日本には無さそうなお祭り感があった)
あと日本に昔住んでいた外国人の方が多かった(自分は2人と会った)

Googleの有名なエンジニアと話せた

今回は、Alex Russell さんと Paul Irish さんに 30 - 60 minぐらい話せてよかった。
TC39の話、PWAの話、Lighthouseの話、etc...、な話をしました。
TC39のメンバーの方と顔を合わせて喋るのは初めてだった。
こんな貴重な体験、普通ではできないので 宇都宮さん には感謝しかありません。

将来

自分が仕事として何をしたいのかがわかった気がする。
また、今自分に足りないものがわかった。 それをクリアすればいいだなーっていう感じ。
相変わらず海外で働きたいなっていう考えは変わらずです。

OSSへのモチベーション復帰

自分がメンテをしているOSSが発表中に出てくると現実感がある。
頑張ろうって思った。

地域

サンフランシスコ

ちょうど先週はインディアンサマーだったので、雲ひとつなく大変過ごしやすい気候だった。
本来はもっと寒いらしく革ジャンを持っていったのだが一回しか使わなかった。
また、メルカリにはUSオフィスがありお邪魔した。
SFOは危険な地域もあったりするので、行く前に調べたほうがよさそう。(テンダーロインとか)
どこのマンションにもプールやスポーツジムが家についており、最高だった。
ただ、その反面、お風呂とかトイレとかは日本の方が良さそう。

f:id:about_hiroppy:20171021113546j:plain f:id:about_hiroppy:20171025093513j:plain f:id:about_hiroppy:20171024181900j:plain

マウンテンビュー

こちらも雲ひとつなく晴天であった。
みんなTシャツだったりする。
入ったらすぐにGoogle社だったりする。

Google

本当に大学のキャンバスみたいだった。
多国籍だったり、お昼からビーチバレーしたりとかとりあえずすごかった。
こういう風に開放的な方が生産効率は上がるのかな?(メリハリは付きそう)
f:id:about_hiroppy:20171025110427j:plainf:id:about_hiroppy:20171025110538j:plain

最後に

自分がメンテナンスしているOSSがカンファレンスのスライドで発表されるの最高に嬉しいのでこういう報われ方もあるんだなーって思いました。
また、技術的内容などの報告は別ブログや明日のNode学園で話します;)

nodejs.connpass.com

今後も積極的にカンファレンスに参加したいなーって思う。
そして家帰ったら、Google home miniが届いてたのでNature Remoを買ってすべて一括管理するようにしようと準備をし始めた。

未完成のパズルを思い出す

AyoでWorkerの実装が進んでいる

Chrome Dev Summitのため、サンフランシスコで書いています。

さて、最近、Ayo側でWorkerの動きが活発なのでそろそろまとめてみた。
f:id:about_hiroppy:20171023090343p:plain 昨日一日でこれだけ出ている...!

Ayo側

$ ./ayo --version
v9.0.0-pre

github.com

実装者はAnna、過去にNodeにWorkerを入れようという動きもあったため、petkaantonov/io.jsからベースは引用されています。
例えば、initial implementationはこちら

github.com

この間、第一回目のコアチームミーティングが開催されたが、自分は参加してないので何が話し合われたのかわからないです。
後ほど、アップされるとのことなのでそれを待ちます。

github.com

ただ、WorkerがAyoのコアには入っているので、基本的にはStabilityを2まで持っていく方針だと思われます。
Stabilityとは? About this Documentation | Node.js v8.7.0 Documentation

これが最初のNodeとAyoとの技術的な優位性です。

Node側

NodeもAyoからのコミットを入れるかどうかのPRが上がっています。

github.com

ただ今現在、このPRの1つしか存在せず、進んでいないです。
もし、入れたいと思う人がいればここにコメントするとよさそう;)

Workerとは?

独立したスレッドで動作する環境を構築し、それらの間にメッセージチャンネルを構築します。
WorkerはCPU集約型のJavaScriptの操作を実行するのに便利です。
子プロセスやClusterとは違い、それらの間でWorkerはArrayBufferインスタンス間の転送をしたり、 それらの間でSharedArrayBufferインスタンスを共有をすることによりメモリを効率的に共有することが可能です。

Eventの説明は省きます

const worker = require('worker');
const { Worker, isMainThread, postMessage, workerData } = require('worker');

if (isMainThread) {
  module.exports = async function parseJSAsync(script) {
    return new Promise((resolve, reject) => {
      const worker = new Worker(__filename, {
        workerData: script
      });
      worker.on('message', resolve);
      worker.on('error', reject);
      worker.on('exit', (code) => {
        if (code !== 0)
          reject(new Error(`Worker stopped with exit code ${code}`));
      });
    });
  };
} else {
  const { parse } = require('some-js-parsing-library');
  const script = workerData;
  postMessage(parse(script));
}

メソッド・変数

isMainThread

Workerスレッド内で実行されているかを返します。
実行されてなければ、trueを返します。

postMessage(value[, transferList])

Workerスレッド内でのみ、使用可能です。
worker.on('message')を経由し、受信される親スレッドのWorkerインスタンスにメッセージを送信します。

threadId

現在のスレッドのIdを返します。

workerData

Workerコンストラクタに渡されるデータの複製を含む任意のJavaScriptデータ。

クラス

MessageChannel

このインスタンスは、非同期の双方向通信チャネルを示します。
独自のメソッドを持ちません。

const { MessageChannel } = require('worker');

const { port1, port2 } = new MessageChannel();
port1.on('message', (message) => console.log('received', message));
port2.postMessage({ foo: 'bar' });
// prints from L4: received { foo: 'bar' }

上記のコードは、終了しません。(exit)
ずっと待ち続けます。

MessagePort

非同期の双方向通信チャネルの一端を表します。
構造化データ、メモリ領域、および他のMessagePortsを異なるWorkerまたはVMコンテキスト間で転送するために使用できます。 これは、EventEmitterの拡張です。
また、EventTargetsではなくEventEmitterであるMessagePortsを除いて、この実装はブラウザのMessagePortsと同じです。

postMessage(value[, transferList])

Worker

独立したJavaScript実行スレッドを示します。
殆どのAyoのAPIは、この中で実行可能です。

new Worker(filename, options)
filename

filename絶対パスでなければなりません。
options.evaltrueの場合、パスではなくJavaScriptコードを含む文字列となります。

options
  • eval Workerがオンラインになった時に実行されるJavaScript
  • data クローンされ、require('worker').workerDataとして利用可能となるJavaScript値。 複製は、Structured_clone_algorithmと同様に行われできない場合はエラーが飛ばされます(e.g. 関数が含まれている場合)

developer.mozilla.org

  • maxSemiSpaceSize スレッドのヒープのセミスペースのオプションのメモリ制限(MB単位)。
    ほとんどのshort-lived objectsはここに含まれます。

  • maxOldSpaceSize スレッドのメインヒープのオプションのメモリ制限(MB単位)。

const assert = require('assert');
const { Worker, MessageChannel, MessagePort, isMainThread } = require('worker');
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on('message', (value) => {
    console.log('received:', value);
  });
} else {
  require('worker').once('workerMessage', (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage('the worker is sending this');
    value.hereIsYourPort.close();
  });
}
// prints from L8: received: the worker is sending this
Worker内の大きな違い
  • process.stdinprocess.stdoutprocess.stderrはnullに設定されています
  • domainモジュールは使えません
  • require('worker').isMainThreadfalseに設定されています
  • require('worker').postMessage()が使用可能で、require( 'worker')on( 'workerMessage')がエミットされます
  • process.exit()はプログラム全体を停止せずに単一のスレッドだけを処理し、process.abort()は使用できません
  • process.chdir()及び、グループまたはユーザーIDを設定するプロセスメソッドは使用できません
  • process.env環境変数に対する読み取り専用の参照となります
  • process.titleは変更できません
  • 明示的にWorkerサポートでビルドされていないネイティブのアドオンはロードできません
  • worker.terminate()が呼び出された結果、実行が停止することが可能性があります
  • 親プロセスからのIPCチャネルにはアクセスできません
postMessage(value[, transferList])

require('worker').on( 'workerMessage')を経由し、受信されるメッセージをworkerに送信します。
require('worker').postMessageと違い、require('worker').on( 'workerMessage')を経由することに注意して下さい。
require('worker').postMessageworker.on('message')

terminate([callback])

可能な限り早く、workerスレッド内のすべてのJavaScript実行を止めます。
callbackは終了したら呼び出されます。

threadId

参照されるスレッドIDを返します。

最後に

これらはstabilityが1なのでまだ不安定 + 変更があります。
WorkerはClusterよりもパフォーマンスが良く、利便性があります。
今はAyoだけですが、今後Node側へも入る可能性はあるので注目しておいても良いかもです。