YDiary

メモ的な

MSのドキュメントにフィードバックをしたら最悪の対応をされた件とその技術的考察

MastodonTwitterに投稿してたこの件の詳細です.

issueがcloseされてから特に音沙汰がないので,一回記事にまとめようと思います.

何が起きたか

何が起きたのかについて,時系列に順を追って説明します. Azureに関するMSの公式ドキュメントを見ていたら,たまたま404になるリンクを見つけたので,そのまま該当するGitHubリポジトリにこのようなissueを立てました.

github.com


YDKK commented 15 days ago
Marketplace links are broken.
ex) https://azuremarketplace.microsoft.com/marketplace/apps?page=1&search=Email

私「このリンクが切れてるよ」


LisandroSu commented 14 days ago
Hello, @YDKK We truly appreciate your comment and we strive to improve your experience in docs.microsoft.com. However, the marketplace link seem to be working fine (see screenshot below). Can you please provide more detailed information and clarify your comment?

MSの人「フィードバックありがとう!でも見た感じリンク生きてそうだけど?」


YDKK commented 14 days ago
When I saw these links, a 404 error was occour, but now these links are working well for me too. I think there was a something temporary problem and now resolved.
So, I'll close this issue. Thank you for your response.

私「あれ,本当だ.なんか一時的な問題があったのかな.じゃぁissueをcloseするね.」


この時,自分でもう一度確認してみたところ,確かに404ではなくちゃんとしたページが表示されていました.そこで,何か一時的な問題が発生していたのだろうと思い,一旦issueをcloseしました.

後になって気が付くのですが,実はこの時発生していたのは一時的な問題などではなく,閲覧環境に起因する問題だったのです. 最初に404が表示された際と違う環境から確認していたため,問題が解決したように見えたのでした.

その後,最初と同じ環境でページを見たところ,再び404が発生しました.ここで,初めて閲覧環境の違いによって404が発生するのではないか,と気が付きます.

実際に問題が発生する環境で確認してみたところ,Chromeでは404になるものの,Edgeでは正常に閲覧することができました.ただし,Chromeだからと言って問題が発生するわけではなく,正常に閲覧できる環境ではChromeでもEdgeでも問題なく閲覧することが可能でした.

そこで,404になる場合と正常に閲覧できる場合とで,ブラウザから送出されるHTTPヘッダの値を調べました. その結果,どうやら Accept-Language ヘッダが ja-JP ではなく, ja のような短い形式の場合に404が発生すると突き止めました.どうも,日本語を使用している国(地域)は一般的に日本しかないので,国部分が省略されてしまう場合があるようです.

そこで,再びissueをopenし,どうやら Accept-Language ヘッダによる言語別ページへのリダイレクトがうまく動いていないようだ,と画像付きでコメントします.

f:id:YDKK:20181129112716p:plain

これに対して,MS側からのレスポンスが次のものです.


CeciAc commented 7 days ago
Hello, @YDKK We checked the issue in several browsers and everything looks like is working fine. Can you check if this still repros on your side?

MS「いくつかのブラウザで確認してみたけど,特に問題ないように見えるよ.そちら側でもまだ再現するか確認してくれない?」


この時点で,「あれ?」というような違和感を覚えます.そりゃ英語圏じゃ en-USen-GBen と略したりはしない*1でしょうから,いくらブラウザで確認したところで問題が再現するとは思えません.

そこで,問題が Accept-Language ヘッダだけによって発生していることを示し,確実に相手側の環境でも再現できるように,curlコマンドを用いた例を示しました.


YDKK commented 5 days ago
Yes, the issue is still existing. I can reproduce this with a simple curl command.
curl "https://azuremarketplace.microsoft.com/marketplace/apps?page=1&search=Email" -H "Accept-Language: ja" -o nul -w '%{http_code}\n' -s f:id:YDKK:20181129114058p:plain
It seems if the browser sent Accept-Language header in short form, the page returns 404.


これに対して,相手側の応答がこちらです.

CeciAc commented 2 days ago
Hi @YDKK The link is working both in Firefox and Chrome, even in the short form
f:id:YDKK:20181129114753p:plain Since this may be an issue with the command being run, and since the issue does not repro on our end, we will need to close this issue. Thanks for understanding.

MS「リンクはFirefoxでもChromeでもちゃんと動作してるよ.しかも短い形式でも(ここでなぜかURLを ja と書き換える).どうやら実行してるコマンドの問題っぽいし,こっち側で再現しないからこのissueを閉じるね.ご理解ありがとう.」 f:id:YDKK:20181129134100p:plain


おまえは何を言っているんだ」(図略)

ブラウザで見れなかったって言ってるでしょーに.この時点で,どうやら相手にHTTPなどのWeb技術に関する知識がなさそうであることを悟ります.まぁ,もともとドキュメントのメンテやローカライズ担当の方っぽいので,そのこと自体には何の問題もありません.むしろ仕方のないことでしょう.

許せないのは,ここでissueが即closeされていることです.なーにが Thanks for understanding. じゃ.こっちは別にこのリンク切れが原因でAzureが顧客を逃そうと全く関係ないのですが,丁寧に再現条件まで書いたのにまともに検証もせずに「こっちの環境じゃ起こらないから」の一言でcloseされてるのが納得いきません.

明らかに自分の知識や担当範囲を超えているのですから,わかる人や技術サイドにエスカレーションすれば良いにもかかわらず,なぜその場でissueを閉じてしまうのでしょうか.

ちなみにその後,投稿を見た人たちに確認してもらったところ,日本語環境のIEやEdge, Chrome, Firefoxなどで再現する場合があるようです.

技術的な考察

では,そもそもなぜこのような事象が発生するのでしょうか.
Accept-Language ヘッダの値が短い形式の場合に問題が発生するというのは先述の通りですが,この値が短い形式になる条件は何でしょうか.
同じブラウザでも表示できる場合があることから,単純にOSの言語設定やブラウザの実装による違いというわけではなさそうです. 軽く調べたところ,こうした問題は以前からたびたび発生しているようですが,どういう条件で短くなるのかまでは分かりませんでした.

確かそうなのは,これが日本語のように「主に一つの国(地域)でしかその言語を使用していない」という状況でないと発生しなさそうであるという点です. 先にも述べましたが,英語の場合,省略してしまうと en-US なのか en-GB なのか,はたまたその他なのか区別できなくなってしまうからです.

そのため,Azure Marketplaceを実装していた英語圏?のエンジニアはこの問題を見落としてしまったのではないかと考えられます.

そもそも,この問題がAzure Marketplace側の問題なのか,はたまたCDNやロードバランサなどのインフラ側の問題なのかは確かではありませんが,いろいろな言語での対応・検証などを考えると,何かと対応が大変そうな気がします.

*1:区別できなくなるから

Splatoon2の最新のウデマエ(Xパワー)を取得するやつを作った

はじめに

まずはじめに,この記事で紹介するものは stat.ink というSplatoonの戦績を記録するサービスに登録していることが前提です(そこからデータを取得します).

まだ登録してない人は,この機会に登録して戦績を記録しちゃいましょう.

無印時代では戦績の記録にキャプチャボードが必要でしたが,2になってイカリング2からデータを取得する方法が確立されているので,だいぶ導入までの敷居が下がりました.適当なキーワードで検索すれば,導入方法を解説した記事がたくさん引っかかると思います.

作ったもの

f:id:YDKK:20181128233715p:plain

こんな感じで,その時点での最新のウデマエ情報を取得して表示することが可能です.

spl.0ko.me で動いてます.

使い方は簡単で,画面に従って stat.ink のユーザ名を入力するだけです.戦績が正しく記録されていれば,最新のウデマエが表示されるはずです.

作った理由

最新のウデマエXのXパワーを確認するために作りました.ウデマエがS+9までの間はゲーム内やイカリング2で常にウデマエが確認できるので特に困ることは無いのですが,ウデマエXになってからだとなぜか殆どの場所でXとしか表示されません.

f:id:YDKK:20181128235004p:plain

Xパワー1900でも,2500でも,同じXです.

正規の方法でXパワーを確認しようと思うと,そのガチルールが開催されている時間にゲーム内で確認するか,イカリング2の戦績をさかのぼって調べるしかありません.さかのぼるにしても,イカリング2では最新の50戦までの戦績しか残らないので,流れていたりするとそもそも確認することができません.

ゲームデザイン的には「開催中のルール以外のXパワーはそれほど気にしなくて良い」というような考えなのでしょうが,他人に伝えたり次のルールに向けてモチベを高めたりしようとしたときに,サッと確認できる手段があるに越したことはありません.

画像を生成して出力できるようにすれば,ブログパーツ的な感じでも使えるのかなーと思ったのですが,ちょっと面倒くさそうだったのでまだ手を付けてません.もしも誰かがいい感じのテンプレート画像を作ってくれたりしたら頑張るかもしれません.

実装について

ソースコードはこちらです.

github.com

ASP.NET Core 2 の Razor Pages です.Razor Pages を使ってみたかっただけなので,デザイン周りとかは 手抜き 一切手を付けてないです.パッサパサです.

stat.ink からの戦績データの取得にはAPIを使いたかったのですが,あいにくAPI経由でのフィルタ条件の指定に対応していなかった*1ので,ページをスクレイピングしてます.APIでのフィルタ条件の指定に対応したら実装し直そうと思います.stat.ink 側に迷惑がかかるといけないので,一度取得したデータは5分間ぐらいは自前でキャッシュするようにしてます.

おわりに

完全に自分用で作ってたのですが,せっかくなので誰でも使えるようにしました.どこかに少しぐらいは需要があるんじゃないかなーと思うので,よければ自由に使ってください.

*1:ガチホコバトルのみやガチヤグラのみといった指定ができないので,それらの記録が見つかるまでひたすら戦績を取得し続ける必要がある

Mastodonのお一人様インスタンスを立てた

Twitterは死んだ

タイトルの通りです.Twitterが死んだのでMastodonのお一人様インスタンスを立てて移住しました.

まだまだ全然フォローが少なくてTLが寂しいので,良ければフォローしてやってください.

social.0ko.me

古のインスタンス

実はかなり前,Mastodonが最初に流行りだしたころにもmstdn.cf*1というドメインインスタンスを立ててたことがありました.
ただ,mstdn.cfはどちらかというと,流行ってたMastodonをとりあえず体験してみたいという目的で適当に立ててしまったため,そこまでまじめに管理しておらず色々あった末に蒸発*2してしまいました.

今回はそうした反省を生かし,何かあった際の移行やメンテナンス性を高めるために,Dockerを活用してMastodonなどをコンテナ化して運用することにしました.

新生インスタンス

例のごとくおうちクラウド自宅サーバでの運用です.

OSには,軽量のDockerホストOSであるBarge OSを採用してみました.

github.com

構成としては,最初にhttps-portalでアクセスを受け,そこからMastodonを含むいくつかのホストにアクセスを振り分けています.

https-portalはnginxを用いたリバースプロキシであり,Let’s Encryptを用いた証明書の取得や更新などを全自動でやってくれるとても便利なDockerコンテナです.

github.com

また,Mastodonは通常のWebとストリーミングAPIでアクセス先のコンテナが違うため,それを束ねるためにもう一段nginxのリバースプロキシをかませています.
二段nginxみたいな構成になってしまっていますが,リバースプロキシやTLSに関してと,Mastodonに関してできっちり分かれてた方が管理が楽かなぁと思いこんな構成にしてみました.

Portainerで見るとこんな感じです. f:id:YDKK:20180827155045p:plain

ホストマシンのCPUはi3-2120とそれほど強力ではありませんが,お一人様なのもあってか特にレスポンスが悪かったりもせずに快適に使えています.
RAMに関しては,最初は2GBで動かしていたのですが,Elasticsearchが思いのほかメモリを食うようで,3GBにしたうえで -Xms-Xmx を256MBにして*3様子を見てます.

スマホアプリ

せっかく移住したので,当然ストリーミングAPIに対応したスマホアプリが使いたくなります.

いくつか試した中では,SubwayTooterがストリーミングAPIに対応しており,機能面や使い勝手でもなかなか良さそうな感じです.

デザインに関してはTwidereがなかなか良さそうな感じがしたのですが,残念ながらまだMastodonのストリーミングAPIには対応していないようです.

instances.social

instances.socialという,稼働しているMastodonインスタンスのリストを公開しているサイトがあります.新しく立てたsocial.0ko.meも登録してみました.

instances.socialでは,インスタンス一覧にHTTPSやObservatory by Mozillaなどのセキュリティに関する評価も表示されます.
いざリストアップされると,どうしても一緒に表示される評価が気になるので,両方ともA+になるように設定しました. f:id:YDKK:20180827160731p:plain

IPv6に関しては,まだ対応できていませんがそのうち対応したいと思います.

フォローボタン

Mastodonのフォローボタンをこのブログに付けてみました.左サイドバーのプロフィール下に見えてると思います.
特に公式のフォローボタンは無いようなので,こちらの素敵なフォローボタンを使わせていただきました.

blog.miyacorata.net

おわりに

しばらくMastodonを使ってみた感想ですが,とても快適です.何というか,古き良きインターネットと言うと一気にインターネット老人会な感じが出てしまうのですが,そんな感じです.
Twitterで有名な人たちも意外とたくさん居ますよ.こういうSNSなんかは,移行するならみんなで一気に移った方が楽しいと思うので,自動更新されないTLや差し込まれ続けるプロモーションツイートにうんざりしている方は,移行を検討してみてはいかがでしょうか.

ちまちま作ってたTwitterクライアントなんかも,今後Mastodonに対応させてみようと思います.

最後に,個人的なおすすめインスタンスを張っておきます.

mstdn.maud.io

それでは,Mastodonで会えるのを楽しみにしています.

*1:cfは中央アフリカTLD

*2:データは残ってるけど復旧が面倒くさくて放置

*3:どころでプロセスのコマンドライン引数を見てみると-Xmsとかが二回指定されてる感じなんですがちゃんと認識してるんですかね

UserStream廃止に寄せて

何かみんなポエム書いてるの見てたら自分も書きたくなったので書く.

あまり広く公開してこなかったが,自分もいくつかUserStreamを使ったTwitterクライアントを作っていた.

そもそも自分がTwitterに登録したのは2009年の8月ごろで,そこから数えて丸9年間Twitterを続けてきたことになる.
Twitterに登録したきっかけは,JokerRacerというラジコンをブラウザから遠隔操作して遊べるサービスがあり,そのサービスに連携として登録するためだった気がする.*1

9年間もTwitterを続けてきたのは,ひとえにUserStreamのおかげだったと言っても過言ではないと思う.Twitterで1000人ぐらい以上をフォローしててUserStreamを使ったことのある人なら分かると思うが,あの何もしなくてもどんどん情報が流れ込んでくる感じ.それこそ見ようと思えば一日中でもTLを見ていられそうな,あの感覚があるからこそTwitterをここまで続けてきたんだと思う.そしてそれは,間違いなくUserStreamによってもたらされていたものだ.

最初のTwitterクライアント

自分が最初に作ったTwitterクライアントはWindows Formsを使ったもので,コミットログとかを見ると2012年とかそれ以前から作っていたみたいだ.

f:id:YDKK:20180814175718p:plain

当時は既にUserStream対応のクライアントがいくつも公開されており,自分はその中でもJanetterを使っていた.ただ,JanetterはUIに内臓ブラウザを使うタイプのクライアントだったので,当時使ってたEeePCのようなUMPCで使うには少々重くてストレスがあった.そこで,Windows Formsを使って軽量でサクサク動くクライアントを作ろうと思って作ったのが上のクライアントである.
思えばこの頃から,自分はUserStreamの持つ魅力に魅せらていたのだと思う.はなから自分用として使うことしか考えてなかったので,自分の使う必要最低限の機能しか実装していなかったが,UserStreamによって絶え間なく流れる情報をくみ取るためにはそれで十分だった.

UserStream機能を持ったTwitterクライアントというものは,プログラミング初学者にとっての入門用の題材として,これ以上に適しているものは無いように思う.最低限TLのテキストが流れるところから始められ,そこから好きな機能をいくらでも実装して拡張していくことが出来るからだ.自分はこのクライアントを作るために初めてまともにC#に触れたし,そこでオブジェクト指向とかUIの作り方とか,データ処理とかイベント処理とかを文字通り一つずつ学びながら作っていった.このTwitterクライアントを作ることが無かったら,自分はC#をここまで好きになることは無かっただろうし,それこそ全く触れていなかったかもしれない.そんな感慨深いクライアントである.

二つ目のTwitterクライアント

二つ目のTwitterクライアントはModern UI(当初はMetro UIと呼ばれていた)を使ったもので,要はWindows 8以降で導入されたストアアプリタイプのものである.こちらは2014年頃に作り始めてからメンテし続け,後にUWP(Universal Windows Platform)を使って作り直し,なんと今日8月14日現在まで使い続けている.

f:id:YDKK:20180814183420p:plain

PCを買い替えたのでスペック問題は無くなり,もうちょっとリッチなTwitterクライアントが欲しくなったのである.ちょうどWindows 8になって新しいストアアプリという仕組みができ,これでTwitterクライアントを作って画面の端にスナップ表示させたら,えらく捗るんじゃないだろうか,というようなことを考えていた.そんな中でWindowsストアで見つけたのが,雪猫さんのMevyである.
当時はまだWindowsストアのアプリが充実しておらず,それこそTwitterクライアントなんて全くと言っていいほど無かった.そんな中で公開されたMevyは,スナップ表示してながら見するという目的ではとても洗練されていて,ひときわ輝いて見えた.もちろん自分もすぐにインストールし,しばらくメインのTwitterクライアントとして使っていた.
しかし一方で,Twitterクライアントを自作した経験も影響して,UIの細かい部分の改善だったり,自分で使いたい機能を実装したりしたクライアントを作りたいと強く思うようになった.そうして生まれたのが,この二つ目のTwitterクライアントである.

そのような経緯もあって,当初はMevyを目標として一通りの機能を実装しており,いわばMevyクローンのようなクライアントになっていった.基本機能が一通り実装できたあたりから,動画再生とか画像のコピペや4枚投稿*2とかActivity表示機能*3といった自分が使いたい機能をどんどん実装していった.今思えばUI面とかでもうちょっと独自色を出して行けたような気もするけど,標準のScrollViewerとかで素直に実装していったら見た目までそっくりになってしまって少し申し訳なく思っている.

これも,それまで触れたことのなかったXAMLとかデータバインディングとかMVVMとかを一つずつ学びながらコツコツ作っていったクライアントである.今となっては,同じUWPアプリでももっと高機能なTwitterクライアントがいくつもあるように思うけど,自分で作った愛着とか自分向けに細かくカスタマイズした点とかが気に入っており,今でも使い続けている.

実はこのTwitterクライアントは一時期Windowsストアでも公開していた.

f:id:YDKK:20180814201507p:plain

あるときメタデータの不備*4を指摘されてストアから取り下げられ,ちょうどその時期忙しかったのもあって対応できずにずっと放置してしまった.
いい機会なのでダッシュボードで確認してみたところ,どうやら184人ものユーザにダウンロードしていただいたようで,嬉しい限りである.

おわりに

一応上に挙げたようなこれまでの資産があるし,ログイン認証で使っていたりもするので英作文して開発者アカウントの維持はしてみた.でも新APIじゃクライアントを作って公開するには制限が厳しすぎるし,UserStreamも無くなったしで今のところTwitterで新しく何かを作ろうって気にはならないかなぁ….そりゃFilterStreamを上手く使えば疑似UserStreamみたいなことは出来るかもしれないけど,それじゃ自分しか使えないし,今まで自分と同じようにTwitterとUserStream使ってきた人たちが少なからず居なくなることを考えると,プラットフォームとしての魅力も半減してしまうのではないかと思う.
UserStreamみたいな大規模なインフラを維持していくことは並大抵のことじゃないだろうし,それを今まで無料で提供し続けてきたことを考えればとてもTwitter社を責めることは出来ないが,せめてもう少し別の方法もあったんじゃないかと思うと残念でならない.

最後に,これまでの自分に大きな影響を与えくれたTwitterとUserStream,並びにそれらを簡単に扱えるようにしてくれたライブラリ各種に大きな感謝を伝えて結びにしたい.

いままでありがとう.

*1:流石に記憶があやふやなので,ひょっとしたら逆だったりするかもしれない

*2:この辺の機能はMevyでもアップデートで対応しており,ひょっとしたら自分の方が後発かもしれない

*3:TweetDeckとかにある他人がファボったツイートが流れてくるやつ.非公開API

*4:恐らくスクリーンショットを更新していなかったこと

InkTestWpf(手書きノートアプリのデモ)を公開しました

InkTestWpf(という名前の手書きノートアプリのデモ)を公開しました.
f:id:YDKK:20180628160517p:plain 学部2年の頃に授業の一環として作ったものです.

github.com

技術デモという側面が強いのであまり実用向きではありませんが,我ながら,なかなか良く出来てるんじゃないかなーと思います.
こんな感じで,手書きした文字が認識され,同じ場所にテキストとして配置されます.
感覚としては「ぼくのかんがえたさいきょうのOneNote」という感じです.

www.youtube.com

www.youtube.com

これだけ見るとなんかすごいことやってそうな気がしますが,ストロークの文字認識などはWindowsの認識エンジンに丸投げしてるので,認識部分のコードはとてもシンプルです.工夫してる点はInkCanvas芸で頑張ってるところでしょうか.

4年前のコードを引っ張り出してきたものなので,手元では確認してませんが頑張ればビルドできるはずです.
Windows Vista™ および .NET Framework 3.0 ランタイム コンポーネント用 Microsoft® Windows® Software Development Kit を見つけるのが一番大変なんじゃないかなー.たぶん.

File2BMPを公開しました

任意のバイナリファイルを有効なビットマップファイルに変換するツール,File2BMPを公開しました!

f:id:YDKK:20180614024112p:plain github.com

こちらは,以前にビットマップファイルに対応しているAmazonプライムフォトに任意のデータをアップロードするために作成したツールです.*1 ydkk.hateblo.jp

ファイルサイズが4.3GB*2よりも大きい場合は,Bitmapファイルヘッダの bfReserved1bfReserved2 も使用することによって,最大9.2EB!*3までのファイルサイズに対応します.*4

また,特にデータを加工しないため,高速に動作することも特徴です.

*1:同様の目的でこのツールを使用する場合は,自己責任でお願いします.2018年現在でも使えるかどうか検証していませんし,BANされたりしても知りません.

*2:uint.MaxValue

*3:Streamの最大サイズ

*4:この場合は,合法なビットマップにはなりません