GitBucket 4.36.0をリリースしました

Scalaで実装されたオープンソースのGitサーバ、GitBucket 4.36.0をリリースしました。

https://github.com/takezoe/gitbucket/releases/tag/4.36.0

リポジトリビューアでのタグ選択

リポジトリビューアのブランチ選択用プルダウンでタグを選択することもできるようになりました。

f:id:takezoe:20210717231624p:plain

リポジトリのIssue/Pull Requestへのリンク

これまでもマークダウン内での#123のような記述はリポジトリ内のIssue/Pull Requestへのリンクとしてレンダリングされていましたが、これに加えてuser/repo#123のような記述で別リポジトリのIssue/Pull Requestへのリンクを生成できるようになりました。

f:id:takezoe:20210717231641p:plain

差分ビューのファイル、行へのリンク

差分ビューで各ファイル、行にリンク用の識別子が生成されるようになりました。以下のようにしてリンクすることができます。

f:id:takezoe:20210717231654p:plain

f:id:takezoe:20210717231713p:plain

XSSプロテクション無効化オプションを追加

リポジトリビューアではXSS防止のため特定の種類のファイルは描画しないようになっていますが、この挙動をリポジトリのオプションで変更できるようになりました。このオプションはGitリポジトリに格納されているこれらのファイルをHTML等に貼り付けたい場合に利用できますが、公開リポジトリでは有効にしないよう注意してください。

f:id:takezoe:20210717231733p:plain

今回のバージョンではこの他にも様々な改善やバグフィックスを行っています。詳細についてはIssueの一覧をご覧ください。

trino-client-ruby 1.0.0をリリースしました

トレジャーデータが公開しているOSSの1つにpresto-client-rubyというRuby用のPrestoクライアントライブラリがあり、最近色々と弄る機会が増えてきたのでメンテナにしていただいたのですが、PrestoSQLがTrinoのリブランディングされ通信の仕様も若干変わったため、Trino対応させるとともにtrino-client-rubyに改名し、バージョンも1.0.0としてリリースし直しました。

github.com

PrestoはレスポンスのJSONの形式がバージョンによって若干異なるため、presto-client-rubyではmodel_versionというオプションで使用するPrestoのモデルを指定できるようになっているのですが、このオプションで351以前のバージョンを指定するとPrestoモードで動作するようになっています。デフォルトではTrinoモードで動作します。

client = Trino::Client.new(
  server: "localhost:8880",
  ssl: {verify: false},
  catalog: "native",
  schema: "default",
  ...
  model_version: "316" # Works in Presto mode
)

ただ、model_versionオプションは必ずしも対象のPrestoのバージョンをそのまま指定すればよいというわけではなく、ちょっとわかりにくい部分もあるのでクライアントのインスタンス生成時にPresto/Trinoのバージョンを確認しに行って自動で判定するようにしてもいいかもしれないと思っています。

今後も改善できる点があれば引き続きメンテしていきたいと思います。

Programming in Scala Fifth Edition

以前アーリーアクセスで購入して手をつけていなかったScala3対応のProgramming in Scala Fifth Edition、ようやく完成したようなので最近発売されたForth Editionの日本語版と見比べながらざっと目を通してみました。

Scala言語の入門書としては以前よりもだいぶ整理されて真っ当な作りになっていると思います。すでに標準ライブラリから外れて久しいXML、パーサコンビネーター、Swingはもちろん、いまいち謎だった最後のスプレッドシートの章もまるっと削除されていますし、既存の章の順番も見直されています。元々Programming in Scalaの構成はだいぶ謎な気がしていたので、今回Scala3へのアップデートにあわせて一新されたのはよかったのではないかと思います。

個人的にはJavaとの相互運用やFutureの章が削除されてしまったのは残念かなと思うのと、この書籍の出自を考えると仕方ない気もするのですが、assertはともかくテストについては要らないんじゃないかなぁとは思いました。それまで全くsbtに触れてないのに突然sbtの設定とか出てくるし…。

個人的に気になったのが、サンプルコードが全編Scala3で新たに導入されたインデント構文(quiet syntax)になっており、Scala2と一切互換性がないという点です。また、Scala3の新機能は一応それとわかるように書かれているのですが、逆にScala3で廃止された機能については特に明記されていません。つまり、本書はScala3から新たにScalaを始める人向けの書籍であるということです。

すでにScala2をバリバリ使いこなしている人はこの本を読まなくてもScala3に追従するためのリソースはオンラインで入手できると思うのでいいとして、これからScalaを学習するという人のうち、このタイミングでScala3で学習し始めて、Scala2は一切触らないという人が一体どれだけいるのか…。数年後、Scala業界の大半がScala3に移行した後であればよいと思うのですが、今入門書として読むのは結構微妙かもという気がしました。

世の中的にScala3への移行はなかなか一筋縄ではいかなそうな気がしていますし、正直脱落する個人や企業も出てくるのではと思っているのですが、特に新規参入者の方がこの本で混乱してしまわないことを祈るばかりです。

その他のScala3対応書籍

オライリーのProgramming ScalaもScala3対応にアップデートされているようなのですが、こちらはどんな感じなのでしょうか。目次を見ると一応Scala2からScala3へのマイグレーションについての記述があるようですし、型クラスについてもScala2とScala3双方での解説があるようなので、Scala2とScala3を両方触るのであればこちらの方がいいかもしれません。

日本語でのScala入門書

さて、日本では先日Forth Editionの翻訳版が発売されました。何気なく書籍情報を眺めていたら監訳者に前職の同僚氏が!これはお布施せねば!ということで早速クリックしました。こちらはScala 2.13対応ですが、まだまだ現場では当面Scala2が主流で使われると思われるので、今Scalaを学習するのであればこちらもオススメです。

日本語だと技評さんの実践Scala入門も実用的でいいですね。

Trino/Prestoの互換性調査補助ツールを作った

Trino/Prestoをバージョンアップする際には事前に動作の互換性検証などを行なっているのですが、検証作業自体は以前Presto Conference Tokyo 2020でも紹介させていただいたquery-simulatorという内製のツールを使って自動化されているものの、実際に非互換の挙動を発見した後の原因調査(原因のコミットを特定してバグかどうかの判断をする)については引き続き地道な作業が必要な状態でした。

Trino/Pretsoは開発が非常にアクティブで、1回のリリースに数百のコミットが含まれます。1年程度バージョンアップを怠っているだけでも変更が巨大すぎてコードの変更履歴から原因を特定するのは非常に困難になります。そこで、まずは複数バージョンのTrino/Prestoでクエリの実行結果を比較することで変更が導入されたバージョンを特定し、その後、そのバージョンのコミットの中から原因となったコミットを調査するという作業を行なうことが多いのですが、このうちバージョンを特定する部分の作業は自動化できそうということでツールを作ってみました。

github.com

まだ、きちんとしたインターフェースを作っていないのでScalaコードを書いて実行する必要があるのですが、以下のようなコードで指定した範囲のバージョンのTrino/Prestoをdockerで起動し、クエリの実行結果を比較しつつ二分探索で変更が導入されたバージョンを自動的に検出してくれます。

import io.github.takezoe.trino.checker._

val checker = new BinaryVersionChecker(new DockerQueryRunner())
val results = checker.check(Range.inclusive(317, 350), "SELECT null GROUP BY 1, 1")
printResults(results)

実行結果はこんな感じになります。このケースでは339が変更が導入されたバージョンということになります。

✅ 317: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 350: Left(java.sql.SQLException: Query failed (#20210526_154140_00004_yzz4q): Multiple entries with same key: @38f546e: null=expr and @38f546e: null=expr)
✅ 334: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 342: Left(java.sql.SQLException: Query failed (#20210526_154251_00003_2km75): Multiple entries with same key: @63f11e0f: null=expr and @63f11e0f: null=expr)
✅ 338: Right(37a6259cc0c1dae299a7866489dff0bd)
❌ 340: Left(java.sql.SQLException: Query failed (#20210526_154338_00002_2xtvz): Multiple entries with same key: @76615946: null=expr and @76615946: null=expr)
❌ 339: Left(java.sql.SQLException: Query failed (#20210526_154358_00002_jdnni): Multiple entries with same key: @4aca599d: null=expr and @4aca599d: null=expr)

本当はコミットを特定するところまで自動化できると楽なのですが、バージョンを絞り込めばコミット履歴からあたりがつくこともありますし、実際に動かして動作確認するにしてもTrino/Prestoをソースからビルドする必要があるのでIDE上で実行したほうが早いかなという感じです。ニッチなツールなのでさほど頻繁に利用する機会はないかもしれませんが、こういった簡単なツールでも作業の効率化に役立つので、もっと早く作っておけばよかったなぁと思っています。

ユニコーン企業のひみつ ―Spotifyで学んだソフトウェアづくりと働き方

話題のユニコーン企業本を早速読んでみました。分量もそれほどでもありませんし、日本語なので1日で読み切ることができました(翻訳ありがたい)。

内容については散々色んなところで書かれていますので今更ここで書くこともないかと思いますが、この本に書かれている内容はあくまで成功したテック企業のひとつの事例として捉える必要があるかと思います。

ソフトウェア開発プロジェクトの方法論であるアジャイルと比べ、エンジニア組織論はスコープが広く影響を及ぼす要素が多い割にサンプル数が少なく、本来はなかなか一般化して語ることの難しい領域だと思います。その割にこの書籍では(話をわかりやすくするために敢えてやっているのだと思いますが)大企業×スタートアップという二元論的な書き方や、「エンタープライズ」「ユニコーン」「テック企業」など言葉のチョイスからして煽り気味なところもあり、読者層によっては誤った受け止められ方をされ兼ねないと感じました。

エンジニア組織の話については思うところが多々あるのですが、ありすぎてこれ以上の感想をここで書くことはできそうにありません。また、こういった話題からは当面距離を置いてソフトウェアエンジニアリングに集中したいという個人的なモチベーションもあり、今のタイミングでこの本を読んだのは失敗だったかもしれないという気持ちもあります。良い本だとは思うのですが、残念ながら自分はピュアな気持ちで読むことができなかったです。

仕事ではじめる機械学習 第2版

トレジャーデータでの同僚である@chezouさんが著者に名を連ね、名著と名高い「仕事ではじめる機械学習」。恥ずかしながら第1版は読んでいなかったのですが改訂版が出たとのことでGW休暇中に読んでみました。

仕事ではじめる機械学習 第2版

仕事ではじめる機械学習 第2版

噂通りの名著というか怪著ですw タイトルの通り、機械学習アルゴリズムだけでなく、学習結果の評価方法やデータの集め方、システム構成やモニタリングなど運用にあたって留意すべきことなど「業務として」機械学習に取り組みにあたって留意すべき事項が書かれています。果ては機械学習の導入にあたっての立ち回り方など割と身も蓋もない(けれども実際のところ重要な)ことまで堂々と書かれていて、日本ならではの面もあるかもしれませんが、オライリーからこんな本が出せるのかと感動すら覚えてしまいました。

第1版は読んでいないので正確な差分はわからないのですが、この第2版ではML Ops機械学習モデルの検証、バンディットアルゴリズム、オンライン広告での機械学習といった章が新規に書き起こされているようです。ML Opsの章に関してはこの書籍でも書かれている通り、なかなかこれを使っておけばOKというものがなく(クラウドサービスが提供するサービスはガバナンス上の問題で使いにくかったり、OSSのものは既存インフラとの連携面で問題があったり等々…)内製してしまうパターンも多いのではないかと思いますが、今後この分野がどのように発展・定着していくかは興味深いところです。

全編通して著者の方々の知見に満ち溢れており、現場でのご苦労が偲ばれると共に読み物としても面白いので、業務で機械学習に関わりのないソフトウェアエンジニアの方が読んでも面白いのではないかと思います。今のところ日本語でしか読めない書籍ですので、日本人であることに感謝しつつ読ませていただきました。

NetflixがOSS化したScala/Spark用ノートブックPolynoteを試してみる

もう1年以上前の話になりますが、NetflixがSpark対応のScala用ノートブックPolynoteをOSS化したという話がありました。

netflixtechblog.com

既存のノートブックではScalaを使っていてもコード補完などがあまり効かないものが多く、まとまったコードを書くときは結局IDEを使うという感じになりがちなのですが、PolynoteはScala第一言語としてサポートする珍しいノートブックで、コード補完などの機能も充実しているようなので遅ればせながら試してみました。

インストール

Sparkを使う場合、まずは先にSparkをインストールしておく必要があります。とりあえずローカルモードで動かすだけであればSparkのリリースディストリビューションをダウンロードして適当なディレクトリに展開しておくだけでOKですが、Polynoteは内部的にspark-submitコマンドを実行するので、最低限の設定としてSPARK_HOME/binディレクトリを環境変数PATHに追加しておく必要があります。

続いてPolynoteのリリースページからpolynote-dist.tar.gzをダウンロードして適当なディレクトリに展開します。

github.com

必要なPythonライブラリをインストールしてからpolynote.pyを実行するとhttp://localhost:8192/でノートブックが起動します。

$ pip install -r requirements.txt
$ ./polynote.py

Sparkを使うにはノートブックの設定でspark.masterを設定しておく必要があります(設定の変更後は「Save」もしくは「Save & Restart」をクリックして設定を反映する必要があります)。

f:id:takezoe:20210503133722p:plain

使ってみる

ノートブックのセルにはMonaco Editorが使われており、確かにScalaのコード補完もばりばり効きますし、変数のインスペクションができたりと、Scala向けに作られているだけのことはあります。SparkのDataFrameだけでなくScalaのコレクションをプロットすることもできます。

f:id:takezoe:20210503134157p:plain

f:id:takezoe:20210503133802p:plain

これはSparkを使わなくてもちょっとしたScalaコードを動かしたりするのにいいかも…と思ったのですが、少し使っているとかなり編集がもっさりしてきてカーソルを動かすだけでも一瞬間が開いてしまう感じになってしまいました。

ローカルで動かしていたのでマシンスペックの問題もあるのかもしれませんが、ちょっとしたScalaコードを1セル内で編集しているだけでこのもっさり感だとちょっとPolynote上でScalaコードを編集するのは厳しいかもしれないという気がしました。機能的にはよさげなだけに勿体ないなぁという気持ちです。

Polynoteの実装について

PolynoteはScalaで書かれているようなので軽くコードも読んでみました。

まとめ

Polynote、もうちょっとサクサク動くようになってほしい!