先日、“.NET Conf 2019 meetup in AICHI”を開催・登壇したので、その話をまとめます。
2つ目のセッションの話を先に
私は2つのセッションで喋りました:
1. “.NET Core 3の更新内容・紹介”
2. “パターンでわかる! .NET Coreの非同期処理”
最初の方はキーノートのまとめ的なものにしようと思っていたのですが、その話はまた後で。
非同期処理のセッションですが、今回はあんまり内部の技術的な話ではなくて、.NET Core 3.0とC# 8.0で.NETの非同期処理が一応の完成を見たと思っているので、改めて全体を網羅するような内容にしようと思ったものです。その上で、
* 度々非同期処理の誤用が話題に登ったり、辛しみのあるコードを目撃することから「こんな」記事を書いたりしていたのですが、もっと網羅的にまとめたいなーと思っていたので良い機会として共有しよう
というところを目標にしました。
スライド: パターンでわかる! .NET Coreの非同期処理 (SlideShare)
セッション50分でこの分量は無理ゲーなのはわかっていたので、スライドは後で読み返すことが出来るような構成にして、如何に喋りで補えるかに注意しました。が、セッションを聞きながら見ていない場合は、少し足りない(わかりにくい)部分があるような気はしています。セッションビデオと両方で補完してもらえればと思います。
なお、最近twitter上で非同期の事について話ししたものをいくつか置いておきます。この辺の話が今回のセッションをやりたいと思う動機につながっています:
lockしてる処理の中でTask.Delay(5000)の配列をforeachで回して、5秒待った後にFile.AppendAllTextする処理実行すると全イテレーションが終わってlockのスコープ抜けるまでファイルに結果書き込まれないんだけど、どういう仕組みになってんのかな…
— ねこ (@neko3cs) August 23, 2019
過去ブログで一生懸命Wait()とかResultとかするなと書いたのに、その記事を参照しつつ全部のawaitableでWait()とResultを使ってるのって、どういうことなの… つらたん – .NET Core環境下でのAWS SDKのメソッド呼び出しはすべて非同期メソッドを用います https://t.co/Jvghh2gHcs
— Kouji Matsui (@kekyo2) June 4, 2019
ところでワシ、「ワーカースレッドの数と CPU のコア数は同じがよい」のが何故なのかわからないマン……
— あえとす 10/14 池袋ボドゲ会 (@aetos382) July 9, 2019
上記の内容や過去の自分が書いた記事、構文的な書き方はわかるんだけど、具体にどう書いていいのかわからない… みたいなところから、ちょっとずつネタを拝借。
で、最初のセッション
最初のセッションの方は、参加した方には普通に楽しんでもらえたと思っているのですが、懇親会で舞台裏の話をしていたら、それをブログにまとめろとのお達しが… なので、普段、この方面の話は書かないのですが、楽屋ネタを書きます。
このセッションは、当初は私が全部.NET Core 3.0のキーポイントをまとめて1セッション構成するつもりだったのですが、水面下ではMSHQのScott Hanselmanが、日本のコミュニティ向けに何か喋ってくれるかもしれない、という話がもちあがり、それならその方向から構成を考えるために、決定するまで待つかと思っていました。
みなさんご存知の通り、大変に忙しいキーパーソンなので、この試みがキャンセルされるという事態も考えられましたが、関係者が頑張って調整に入っているようなので、ギリギリまで待つつもりでした。
ところで、コミュニティイベントを開催された方なら同意してもらえると思うのですが、イベント開催のためには以下のようなハードルをこなす必要があります:
* 会場の地理的なアクセスのしやすさの検討
* 会場収容人数
* 会場は有償か無償か。有償なら費用をどうするか
* プロジェクターや音声設備の有無・レンタル費用
* WiFiや有線LANなどの通信経路の確保
* 運営メンバーの募集と決定
* 登壇者の募集・登壇内容の調整
* ビデオ撮りあるいはストリーミングライブ配信するのかどうか(合意形成も含めて)
* チェックイン作業
* スポンサーを募集するのかどうか
* 集金や支払いなどの金回り
* ノベルティーなどのグッズ・抽選の有無
* 提供するおかしなど
* 終了後のハッピーアワーや懇親会の検討・場所の確保と誘導・支払い徴収
運営は本当に頭の痛い問題なのですが(これで折れてしまう方もいるので、私は自分が出来る範囲で出来ることしかやらない事を守るスタンスです)、登壇する側としても、セッションネタを考える場合に、上記の制限条件からネタ構成を考える必要も出てきます。例えば:
* 収容人数: 10名・30名・50名・100名かそれ以上、によって、セッションの構成(しゃべる内容や構成、進行方法)を変えたほうが良い。人数が多くなると、後ろの方の席の人は、スライドが読みにくいだとか、声が聞こえないとか、没入感が得られない、といった潜在的な問題が発生しそう。
* プロジェクターや音声設備: スライドの色校正(たいてい黒地だとハマる会場は多いが、パリッとした映像を出せる会場なら、逆に黒地が映える。動画を流す場合は音量に注意しないと、うるさいとか音が小さいとかの問題につながる。しかし、実際に会場で調整しないと思ったとおりには行かない(マイクとかミキサーなどの設備にも影響される)ので、セッションのネタにするのは結構なリスクとなる)
* WiFiや有線LAN: 参加人数が多いと、特別に設計されたWiFiアンテナなどを備えた会場でないと、話にならない事態になります。私はあまりオンライン向きのネタを扱わないので良いのですが、最近だとクラウドアクセスをデモの前提にする必要があったりして、非常にやりにくいでしょうね。逆に、ネットワークの信頼性が高い事が前提にできるなら、クラウドだろうがYouTubeだろうが、セッションの子道具としてバリバリ使えます。
まあ、細かいところを挙げるとキリがないのでこのぐらいで。つまり(人にもよりますが)、セッションネタ一つ決めるのにも、こういう要素が絡んできます。なので、登壇する側は事前にこれらの要素が早く確定していれば、それだけ登壇者や参加者にとって、実りのある内容に詰めていける可能性があるわけです。
で、冒頭の話につながるのですが、今回は会場を日立ソリューションズさん(HISOLさん)にお借り出来たのですが、その前にもいくつか候補があって調整していました。全ての会場が完全に同一条件なら、「まあ確保できるところでやればいいよね」と、問題の一つが片付くのですが、現実はそうじゃないのでヤキモキします。
結局、検討していた会場は確保できなかったのでHISOLさんに打診したところ、快諾得られたので良かったのですが、確定までに2週間前までかかったこともあって、なかなか会場を公表できませんでした。登壇者のみなさんごめんなさい。
こういう点で、名古屋は非常に苦労するというのはなかなか理解してもらえないところでツライです。東京に近いところは楽そうだなと思うし、もっと地方ではそもそも会場になる場所さえ無く、勉強会というものを想像するのも難しいと言うのが現実でしょう。
で、問題は上記の会場環境の話に繋がります。HISOLさんの会場では、残念ながらパブリックなWiFi設備を借りる事が出来ません(もちろん有線LANも)。すると例えば、クラウドベースのデモとかかなり厳しい(デモの悪魔に取り憑かれる可能性が高い)わけです。
言わずもがな、YouTubeを参照したりなど出来ず、オンラインで遠隔会場と連携しながらビデオチャットでセッションを進行するという、海の向こうでは割とポピュラーな手法も取れず… これはイベントの一体感もあるので、ある程度の規模のイベントではやりたくなることの一つです。
実際、もしかしたらHanselmanさんとTeamsで完全オンラインでの相互コミュニケーション、というのも検討の一つとしてありましたが、まあ会場的に無理なので、実現するとなったら有償で会場を確保するかということも考えなければなりません。
(そうすると参加費500円とかでは無理ですし、そもそもそんなギリギリで会場を予約できるか怪しいし、堅苦しい契約書をかわさなければならないですよ、個人で。請求や領収、今だと税金をどうするかみたいな話も出てくるかも)
なので、主催が本当に小規模な勉強会を小規模な会場でやる分には良いんですが、ちょっとでも規模が大きくなり始めると、非常に辛くなります。そこを踏ん張ってやるからには、それを超える動機づけが必要になるでしょう。私の場合は自分の技術的な知見をシェアする、まあ淡良くば技術ポートフォリオとして誰かの目に止まるかどうか、ぐらいで、これで食っていく気は全く無い(食える気がしない)ので、必然的に掛けられる労力もそのぐらいになります。
さて、そういうわけで、様々な軸での考えがあるため、これらをどこにバランスさせて、セッションのネタにするのか、というのは、真面目に考えるととんでもなく難しいです。今回のネタとして、実は以下のような移り変わりがありました:
ごく初期
.NET Confの開催より後に開くことを前提に、.NET ConfでMSHQで公開されるビデオをネタに同じような感じでローカライズバージョンをやればいいかな(鼻ホジ)
環境リッチな会場で開催できるか
.NET Confを拾い上げるにしても、様々なセッションから何をネタにするのかは、上で挙げたような要素が、特に会場確保によって大きく変わるので、まずはどこの会場が使えるのかが最大の課題。
第一としていた候補はダメ。あと2~3考えていたが、それらはどれも環境的に厳し目なため(WiFiが無いとか、ちょっと会場の母体の趣旨と合わないとか)、この時点でセッション内容についてはかなり幅が狭くなる。
Hanselmanさんがビデオメッセージを送ってくれる(あるいはリアルタイムで!)かも??という打診
すごい話だけど、運営側としては、完全に確定だからあとはやれるように組む、というのと違い、不確定だとどう動けば良いのかわからずツライ(それもギョムの合間を縫って行動する必要があるので)。早く決まって欲しい… 早く… 早く…
別の会場を打診
アテの一つは早々に辞退(上記の後者側)、もう一つを打診。
自分の登壇ネタを検討する
.NET Confのセッションを拾い上げるという案は、会場の自由度があるから考えられる手法であって、もうそれは無理なので、結局自分でネタをひねり出すしか無い。非同期の話をしたいから、まあ2枠って事になるかな。
で、問題はもうほかの登壇者さんの募集とか打診とかして枠が埋まりつつ合ったので、もしHanselmanさんの話が現実化する場合、どこの枠(時間帯)をその話にするのかを考える必要がある。内容がキーノート的なものなら、時間的にはやっぱり最初に喋って欲しいけど、そうでないならべつの時間帯でも良いわけだけど、果たしてオンラインで喋るとすれば、本当にJST(日本時間)に合わせてくれるの?(いや、そもそも無理ちゃうの?)
WiFiすら使えない環境でどうやって実現するの? 安定性は? Hanselmanの生の話が聞けるなら、みたいな期待で参加者が押し寄せて、出来ませんでしたテヘッ、みたいな事態を想定しなきゃいかんのか、とか…
非常にツライ…
正直なところは、予定が決まらなかったら、こちらから辞退することも視野に入れていました。自分のネタを考えているはずが、全体の進行まで気になり始めて、それどころじゃない感じ。全然集中できない…
気を取り直してネタ考案
最悪、キャンセルになって自分で全部仕切る(つまり2枠考えて喋る)ということを想定して準備。なんか色々頑張っても無駄に終わりそうで、それもつらい。 最初の方は、.NET Confのキーノートを読み込んで概要にまとめて、面白そうなトピックを実演を交えて喋る、みたいに構成するしかないかな(もはやキャパオーバーだけど、主催自分だから仕方ない)。
3日前の夜に、Hanselmanさんのビデオが送られてきた!!
もうこの時点では、8割方断る方向で心中決まっていて(でないと間に合わない)、手間が空いたときに断りのメッセージを送るしか無いか、と、散々たる気持ちでいたのですが、こっちからメッセージを送る前に向こうから来た。しかも、いきなりビデオが来た… マジか… もうこれで構成するしか無い(非同期のセッションをほぼ書き終えていたので、首の皮一枚つながった感じ)
ということで、20分のメッセージをまずはAzure Video
Indexerで字幕データを作り、それを補正(わりと全自動では駄目な感じの字幕なので、手修正する)して、ffmpegで合成して英語版字幕付きビデオを作る(成果物はここ、但しビデオそのものは含まれていません。時間の関係で、訳を直したりタイムラインを調整したりと言ったところはまだ細部が荒いです。関係者はエンハンスして欲しいです、是非に)。
2日前
ビデオの内容を読み込み、字幕がアレだったことから日本語字幕化する事を考え始めた。でも、SRTファイルをそのままGoogle Translatorにかけるとフォーマットが壊れてしまうのと、センテンスがつながっていないのが原因でダメな翻訳になってしまうこともあって考えあぐねていた(Azure Video Indexerで日本語訳出せばいいじゃん、と思うかもしれません。機能的にはありますが、まあ、察してください…)
それと同時に、セッションをどう進行するかを考えていたけど、ビデオ流しながら補足を入れつつ、(50分枠なので)後半は小さいコードをライブで何かデモするか、そうだねぇ、あんまりどこにも話題にかかっていないgRPCとか良いかもしれない、と考えて、概要を調べる。
その後、字幕の調整のために、ぼーっとSRTファイルの中身を見てたら、これ、フォーマット簡単だよね? もしや自分でパース出来るのでは?と思いつく。そこで、あえてビデオを流さず、いきなりライブコーディングでパーサーを書き、Google Translator APIを使って日本語に翻訳(4G経由の通信なので、ここにリスクはあるが)して日本語字幕ファイルを出力するツールを書き、ffmpegで合成して、日本語字幕のついたビデオをその場でみんなに見てもらう、というのは、かなりエキサイティングじゃないか?
というのを思いついたので、パーサーを書き始める。パーサーは簡単だった。しかもここに非同期イテレーターを使っているので、.NET Core 3としてもふさわしい。
そして、Google Translator APIのメチャクチャ簡単で使いやすいこと!! しかも.NET向けのNuGetパッケージもあって、面倒くさそうなアカウントキーもどこからサインアップしてGetすればいいのか、わかりやすいドキュメント… なんてことだ!15分ぐらいで実際に翻訳出来た!! ええ、なんでGoogle API使っているのかって、自問してましたよ…
しかしここで字幕特有の難しさにブチ当たる。それは、1センテンス(日本語なら読点まで)が必ず1画面に収まるわけではなく、分割されたセンテンスに推測不能(一定時間ではない)時間タグがついて分割されている、ということなのです。
“My name is (ここで分割されている) Kouji Matsui.”
“私の名前は松井幸治です。”
果たしてどこで分割する? System.Stringで英文の割合で発生する分割点と同じ割合の文字で切るか? 例えば、46/54なら、「は」の後ろで丁度切れるかもしれない。しかし、こんなにうまくフィットするわけがなくて、普通は非常に読みにくい位置で分割されてしまう…
では、形態素解析するか?形態素解析すれば、助詞とか句読点位置を検出してそこで区切って、自然な感じの字幕に出来るのでは? えーやったこと無いぞ、今からは無理では… .NET実装はあるのか?と考えて検索したら、あった: .NET形態素解析エンジンNMeCab (SourceForge.jp)
NMeCabで検索すると、割と紹介記事があるのだが… ライブラリ更新されてない… net20とか古すぎる。そうか、じゃあNMeCabをベースにチャッチャと移植して、これはこれで別の機会にネタとしてまとめよう、と思いついて移植を始める。
1日前
NMeCabの.NET Coreへの移植が出来た… アンセーフブロック使ってたり古いリソース(Settingsとか)して、ちょっとハマる点があったけど、そのあたりを軽く手を入れ、net40, net45, netstandard1.3, netstandard2.0, netstandard2.1対応のNuGetパッケージ、しかも標準のIPADIC同梱でありながら、自分の辞書を使う事も出来るように構成可能にして公開しました。
まあ、気がつくともう翌日が本番なのに何やってるんだろう、みたいな…
で、日本語字幕を付けるコードの続きを書き始めたのですが、日本語字幕センテンスを割合で再分割してSRTのフレームにする部分が思いの外面倒で、疲れ切った頭では正しいコードをひねり出せず… もう寝る時間が無くなって本番の運営に支障をきたしそうなので、無念だけどここでピボットする事に。
MeCab.DotNetのことと日本語字幕ツールの話は、また後日のネタにする事にして、当日はHanselmanの英語字幕付きビデオを流してコメントを入れつつ、その後にHanselmanのデモと同じことを私が再現して、多分言い足りない部分を補う感じにすれば、丁度50分に収まるだろうと考えました。
(今回のセッションではなく)不特定の人に英語技術ビデオを見た後に感想を聞くと、なんか腑に落ちない顔をしていることがあります。英語や英語の字幕のせいでピンときていないのかも知れないし、ビデオでは簡単にやって見せているけど、周到に準備してるからじゃないの?というような疑念があるんじゃないかと思っているので、同じことを目の前でやって見せることで払拭したかったのです。
(Hanselmanさんのデモ自体は、上記のような不安要素は殆どなくて、押さえるべきところが押さえられていて流石だなと思っています。)
ポイントはそんなに多くなくて、実際やって見せればシンプルな話だと思っていて、目の前で動いているプロセスの状態を見たりとか、今まさにWindows側でビルドしたコードが、WSLのubuntu上でそのまま動きましたよね(間違いなく)、みたいなことじゃないかなと。
そういうわけで、これで50分のセッションを構成することにしました。この内容の利点は、資料が一切不要なこと。自分の喋りと進行をその場で工夫して乗り切ればOKだ。この時点でもう23時なので、他の手段は取れそうにない…
妄想
ということで、今回のイベントの裏がどうなっていたのかが何となくわかっていただけたかと思います。半分は運営全体の話、半分は個人的な事情によるものですが、こうしてみるとやっぱり運営に割ける時間が足りない、運営に手間を取られすぎる、ということが大きかったと思います。
コミュニティへの貢献は色んな方法が考えられます。私が一番して欲しいと思っていることは、ぜひ、自分の時事ネタでも興味のあることや知見でもなんでも良いので、発表・シェアしてほしいです。元々そういう場なので。
そして、コミュニティに物理的な(生々しい話をするなら金銭的な)貢献をして頂ける場合は、運営の裏舞台、特に発表とは関係のない諸々の作業(これは私の場合ですが、それぞれのコミュニティの事情を読み取って)の負担を軽減してもらえて、結果的に時間を削減出来ると、本当に助かります。時間を確保出来るようになれば、発表する内容をより吟味したり、面白く楽しい内容に出来るようになり、より良いコミュニティイベントを開催・継続できることにつながると思います。
(あえて挙げるとすれば、名古屋の場合はやっぱり会場ですかね。リッチな環境が整備された会場が提供されると、悩みの半分は解決します。場合によっては7割ぐらい楽になる感じ。今や募集とかはconnpassのようなサービスで出来るし、あとは当日そこに行って発表する事を考えるだけなので。いつも会場提供して頂ける団体や組織には、本当に感謝しています :)