alwaysLUNCHで幸せを感じるには、修行が必要そう

alwaysLUNCHに1ヶ月だけ登録した感想。

一言でいうと、「毎日こんな食事してたら体壊しそう」

なんで登録した?

1月に、あらためて家計簿つけてみたら、若干赤字だった。何を間違ったか食費を削ってみようと思った。

ただ、いくら安くてもマクドを毎日食うような生活は絶対したくなく、とはいえ弁当を毎日作る気力もない。

マキイ弁当648円x16日(ときどき在宅で勤務してるので、ランチ代が必要になるのはこのくらい)よりも安く、そこまで質を下げないものであればアリかも?とおもい、物は試しでalwaysLUNCHに登録してみた。

f:id:YusukeIwaki:20200215230714p:plain

月額 5980円 (税抜) なので、実際には 6578円/月。16日利用するなら、1日あたり411円。逆に、10日利用しないと、マキイ弁当で十分という計算。

結構いいお店も多い

おかゆや、パニックバーガー

f:id:YusukeIwaki:20200215231107p:plain

とり田の担々麺(今はもうない)

これが14:00以降限定という鬼畜仕様だったけど、それでも3回くらい食べた気はする。

釜喜利うどん

f:id:YusukeIwaki:20200215233650p:plain

ベトナムビストロasiatico

f:id:YusukeIwaki:20200215233731p:plain

糸島の新鮮な野菜がおかわり自由、ドレッシングも自家製、というのがだいぶよかった。

alwaysLUNCHの使い勝手がだいぶイマイチ

alwaysDRINKと同じだろうって思っていたんだけど、実際使ってみたらLUNCH特有で相当に使い勝手がイマイチだった。

地図で選べないお店がある

一番最初にランチ使ったときに、

こういう問題があった。たぶん未だに直っていないだろう。

ほぼ毎日使う身としてはとても困ったので、自分用にパス表示するアプリを適当に作って解決していた。

サイトが重く、注文完了するまでにめちゃくちゃ時間がかかる

初めて使ったときに、あまりにもサイトが重くて、注文するのに3分以上かかった。

解約前日でもこれは改善されていなくて、注文に5分くらいかかった。

毎日こうだというわけでもなく、おそらく利用時間帯の集中とかによる。そうはいっても、「ランチ」という特性上、腹が減ってるのは必然であり3分も注文で待たされるのは流石に耐えられない。

LUNCHっていうくらいなのでDRINKよりもお昼に集中するのは今後も変わらない。DRINKとLUNCHはだいぶシステムの共通化をしてしまっているっぽいので、おそらくLUNCHだけを考慮したサーバーの増強とかそういうのは当面されないだろう。

パスが表示されないことが多い

これはDRINKもそうなんだけど、店舗のalwaysLUNCHのQRコードを読み取ってランチを使おうとするとパス表示がされない。なんのためのQRコードやねん。

地域選択が東京になっているとかそんな理由なんだと思うけど、死ぬほど不便なので、選択エリア外のお店もURL直リンクで来たときはパス表示してくれよ?

結局やめた

理由はいくつかある。

値上げ

3月から値上がりするらしく、8800円/月くらいになる。(東京進出の弊害だろうなー...)

16日利用する計算で、1日あたり550円。逆に14日利用しないとマキイ弁当(648円/)で十分ということになる。

外食するなら、ランチパスポート500円とかもあるし、alwaysLUNCHだけが選択肢ではなくなってしまった。

使い勝手がいまいち

先に述べたとおり。息抜きのランチで変なストレスを感じたくない。

毎日食べるにはしんどい

これが一番大きな理由。

天神の東の方だと、ランチ候補になる店舗は4つくらいしか無い。ヘビーローテ不可避である。メルチャリ使って少し遠出したとしても、alwaysLUNCHが使えるお店は全体的に味が濃すぎたり、脂分が多すぎたりで、毎日食べるには自分の体がもっと強靭でないといけないことがわかった。

alwaysDRINKはハニー珈琲が使える限り大丈夫なんだけど、alwaysLUNCHで毎日ランチ食べていると、どこかしら体壊しそう。

というわけで、2月上旬からもうしんどくなってきたので、解約を決意。

やめたけど、応援はしているよ

自分がそこまで体が強くないから、食べ物にもわりと気をつけているという事情もあって、alwaysLUNCH解約に至った。

値上げとかなんとかで色々大変なサービスなんだとは思うけど、すごく革新的なことをスピード感もってやってるなぁーとも実感できるので、応援はしている。

PuppeteerをRubyから直接触れるGemを作ろうとして挫折した

まえおき

(追記: 開発再開してます→ やっぱりPuppeteerをRubyから使えないと困るので、puppeteer-rubyを作ることにした - YusukeIwakiのブログ )

github.com

Puppeteerはすごい。「自動化はSeleniumで十分じゃね?」と思ってた自分だが、Puppeteerには完全に魅了されてしまった。

puppeteerはJavaScriptで書かれているライブラリなんだけど、Dartで動くようにしてるすごい人がいる。C#とかPythonで動くようにしている人もいる。

「・・・あれ、Ruby版は?」

そう、ないのだ。

Rubyは日頃の業務で使ってるからPuppeteer使えたら何か便利になるんじゃね?」と安易な気持ちでpuppeteer-rubyを作り始めた。

github.com

あらかじめ書いておくと、この記事を書いている2020/01/31時点では未完成。たぶん1年以内に完成されることはないだろう。

とりあえず、挫折したなりに、勉強になったこととか苦労させられたところとかは共有しておこうと思う。

WebSocketをRubyで使う

多くの言語では標準でWebSocketを使うライブラリがあるが、Rubyには無い。

2019年末時点で、現実的なライブラリとしては

あたりだろう。

ソースコードが読みやすいのは圧倒的に async-websocket なんだけど、async-websocketは asyncっていうライブラリに依存していて、こいつがなかなかに難読だ。いっぽうwebsocket-driverはソースコードこそ若干いまいちながら、ベースは歴史あるEventMachineだ。

chrome-remoteっていうCDPクライアントのGemがwebsocket-driverを使っていたこともあり、今回はwebsocket-driverを使った。

async/awaitを攻略する

Puppeteerはasync/awaitをとてもヘビーに使っている。API仕様書 を見てもわかるように、ほとんどの主要なAPIはasync functionでPromiseを返すものだ。

いっぽうでRubyはというと、言わずもがな、並列処理の仕組みはそんなにリッチではない。

たとえば、browser.launchくらいなら、他に並列でやりたいことは無いのでRubyでも普通に def launch(...) で同期な関数定義してしまえばいい。

ただ、困ったのが、WebSocketのメッセージを受けて動くところだ。ブラウザの準備完了を待ちつつ、タイムアウトを設定しつつ、みたいなのをPromiseを使いまくっているのがPuppeteerの元のコードだ。

自分の実装力低さゆえ、ページの読み込み完了を待ちつつ、いくつか準備のためのWebSocketメッセージをやり取りしないといけないところで、完全にデッドロック起こしてしまって死んだ。

puppeteer-ruby/lifecycle_watcher.rb at 80a848417faf312f66a55410613ff3058c8f7d2f · YusukeIwaki/puppeteer-ruby · GitHub

  # Alternative implementation of #lifecyclePromise.
  def wait_for_lifecycle
    @wait_for_lifecycle ||= (@wait_for_lifecycle_queue ||= Queue.new).pop
  end

十中八九、ここで Queueの popをしてスレッドをブロックしてしまってるのが原因。なんだけど、Async だったり concurrent-ruby だったりになんとなく頼ってしまうのも負けかなーなんておもって、結局身動き取れないまま、情熱が冷めて今に至る。

気分転換に puppeteer_firefox-dartを作ることにした

Dartがやっぱり最高なので、puppeteer-firefoxDartに移植しようかなと思った。Firefoxでしか動かないレガシーなサービスが自分の身近にあるので、それをDartで自動操作するプログラム書けば、シングルバイナリで実行とかもできて便利だろうなー。そもそもDartだったら型がしっかりあるから書きやすいだろうなー。みたいなのを狙っている。

https://github.com/YusukeIwaki/puppeteer_firefox-dartgithub.com

とはいえ、そうこうしている間にMicrosoftplaywright とかいうOSSを出してきたり、Puppeteerが公式でFirefoxのサポートしたぞってアナウンスしていたり、

puppeteer-firefoxにとっては逆風なできごとがここ1ヶ月で結構起きています。近未来にDeprecatedにされそうな勢いです。

とはいえ、Firefoxでしか動かない謎システムは直近1年間では大きく変わらないでしょうから、なんだかんだで古くなっても自分はpuppeteer-firefoxを作って使って行くことになると思います。

(2020.12.02 追記 : add Firefox support by YusukeIwaki · Pull Request #125 · xvrh/puppeteer-dart · GitHub puppeteer-dart にPulll Request出しました)

 

まとめ

結局のところ、いかに情熱をキープできるかが大事だということ。

(追記: 開発再開してます→ やっぱりPuppeteerをRubyから使えないと困るので、puppeteer-rubyを作ることにした - YusukeIwakiのブログ )

(追記2: 調子に乗ってplaywrightもRubyから触れるようにしてみてますw→ ブラウザ自動操作のPlaywrightはRubyからでも使える? - YusukeIwakiのブログ

どうしてこうなった? ゆうちょダイレクトの酷いUI

久々に日常生活ネタ。中身は無い。

 

最近になってようやく初めてゆうちょダイレクトを使ったんだけど、これ過去最悪に絶句レベルのひどいUIしてる・・・

 

「利用停止してログアウト」のところは、詳細ページを見てみたんだけど

f:id:YusukeIwaki:20200125001533p:plain f:id:YusukeIwaki:20200125001557p:plain

・・・わからない!!

 

では、どうすればよかったのか?

勝手に考察してみる。

営業時間外のエラー

f:id:YusukeIwaki:20200125002616p:plain

Twitterにも書いていたが、サービス時間外のアクセスはエラーではない。だって、閉店間際のスーパーにお買い物に行って「営業時間外でした。エラーです」って言わないでしょ?

あと、そもそも夜中に10分だけサービス時間外になるんだったら、大半のユーザには影響はない。23:59締切で何か振込しないといけない人くらいしか困らない。

→ということで、淡々と「サービス時間外です」って伝えたらいいだけだ。

戻る/進むでエラー

f:id:YusukeIwaki:20200125003828p:plain

これも、エラーではない。ブラウザの戻る/進むは一般市民だれしもが行う操作だ。だって、スーパーで「野菜コーナーを通り過ぎたのに、戻ってきましたね。エラーです」ってならないでしょ?

99.999999%これはシステムの実装上の問題だ。なので、お客さんにはまず謝らないといけない。そして、お客さんにわかるように、丁寧に説明をしないといけない。だってお客さんは悪いことは何もしていないのだから。

利用停止してログアウト

f:id:YusukeIwaki:20200125012957p:plain

「利用停止してログアウト」は要らない。素直にログアウトできればいい。

出口と非常用出口があって「非常用出口がおすすめです」なんて言われても、一般市民は「は?」となるだけだ。素直に出られる出口が1個あればそれで十分なのだ。

というか、そもそもセキュリティ強化を謳うのであれば、まず二段階認証ログインを推奨してくれ。生体認証じゃなくて。

どうしてこうなった?

おそらく、どこかのSIerが要件ツギハギで作ったんでしょうね。しらんけど。

明日は我が身・・・