tokuhirom's blog

[js] List::Util::all みたいなのを js で

 List::Util::all みたいなものをJSで書くときってどう書くのがいいんだろ
lodash とかにありそうだけど
syohex [8:55 PM]
 Array.prototype.everyとは違うのでしたっけ ?
karupanerura [8:56 PM]
 それだ。some/everyが今はありますね(名前が思い出せなかった
https://qiita.com/Nossa/items/4a425e57ec4b7eedb7cb
Created: 2019-02-02 18:59:20 +0900
Updated: 2019-02-02 18:59:20 +0900

ivy が最近は良いらしい

https://twitter.com/typester/status/1089932791150592001

最近はhelmやめてivyつかってますよ! とのこと。僕も変えてみた。

Created: 2019-01-29 08:02:01 +0900
Updated: 2019-01-29 08:02:01 +0900

YAPC::Tokyo 2019 で keynote してきた

https://www.slideshare.net/tokuhirom/20190126-yapc-tokyo-keynote

keynote の準備に忙しかったりしてあまりトーク聞けなかったけど楽しかったです。

Created: 2019-01-28 16:02:20 +0900
Updated: 2019-01-28 16:02:20 +0900

bash で **/* とかしたい

shopt -s globstar で OK

Created: 2019-01-19 14:21:47 +0900
Updated: 2019-01-19 14:21:47 +0900

YAPC::Tokyo 2019 で keynote します

https://yapcjapan.org/2019tokyo/

キーノートというのをするのが初めてなのでどういう話をしたら良いのかよくわかってない部分もありますが、僕のキャリア・エンジニアリングに関する考え方などを紹介しようかなあと思います。

Created: 2019-01-07 11:13:39 +0900
Updated: 2019-01-07 11:13:39 +0900

spring の 4.3.15, 5.0.5 以後で mockmvc の json path のマッチングで matcher 使わなくてもよくなってる

mockmvc で jsonpath のマッチングを利用する場合、以下のようにする必要があった。

.andExpect(jsonPath("$.id", is(5963)))

これはこれでいいのだが、他の API と一貫性がなく、補完も効きづらく、hamcrest API ではなく assertj をメインで使ってる身としては辛かった。

また long の扱いが渋くて、辛かった。。 https://stackoverflow.com/questions/37996419/how-to-force-andexpectjsonpath-to-return-long-long-instead-int-for-int-num

SPR-16587 MockMvcResultMatchers.jsonPath(String).value() should have a matching method to declare the expected type で、問題が解決されて以下のような書き方ができるようになっている。

.andExpect(jsonPath("$.id").value(5963)))

MockMvc でテストを書いているときに部分一致をしたいケースは殆どないと思われるので、このスタイルで書くのが良いと私は思います。

Spring 4.3.15, 5.0.5 以後で使えるので、このスタイルで書いたほうが良い。

古いコードをコピペし続けているとこのような古い書き方に引きづられがちなので気をつけていきたい。

【追記】 null であることを保証したいときは hamcrest matcher でやらないと駄目。

Created: 2019-01-06 18:25:38 +0900
Updated: 2019-01-06 18:25:38 +0900

spring boot で ExceptionLoggingFilter が ERROR level でログ出まくってうざいってとき

spring-cloud-sleuth を依存にいれたら ERROR レベルでのログの出方がおかしくなった。

https://github.com/spring-cloud/spring-cloud-sleuth/blob/master/spring-cloud-sleuth-core/src/main/java/org/springframework/cloud/sleuth/instrument/web/ExceptionLoggingFilter.java

このクラスが例外をキャッチしてエラーログに書いて rethrow するという謎の挙動をしている。。

なんのためにいったいこのクラスが設定されているのか謎。だが。。

https://cloud.spring.io/spring-cloud-sleuth/multi/multi__integrations.html#_http_filter

この spring.sleuth.web.exception-throwing-filter-enabled プロパティを false に設定することですべてが解決する。

Created: 2018-11-30 13:42:35 +0900
Updated: 2018-11-30 13:42:35 +0900

spring boot で静的リソースの書き換えを即時反映させたいよってとき

bootRun {
    sourceResources sourceSets.main
}

https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#running-your-application-reloading-resources

この設定をすると、静的リソースが source directory から読まれるようになり開発が快適になる、とのこと。

Created: 2018-11-29 15:36:37 +0900
Updated: 2018-11-29 15:36:37 +0900

webflux で x-forwarded-for とかをケアする

以下の様にすれば良いっぽい。

https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-forwarded-headers

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.reactive.config.WebFluxConfigurer
import org.springframework.web.server.adapter.ForwardedHeaderTransformer


@Configuration
class WebConfiguration : WebFluxConfigurer {
    @Bean
    fun forwardedHeaderTransformer(): ForwardedHeaderTransformer {
        return ForwardedHeaderTransformer()
    }
}
Created: 2018-11-20 20:46:18 +0900
Updated: 2018-11-20 20:46:18 +0900

あるプロジェクトを Gradle kotlin DSL に移行した

お仕事プロジェクトの一つを gradle kotlin dsl に移行させてみた。 理由としては以下。

  • gradle kotlin dsl を利用すると、人によるブレが少ない
    • parenthesis の省略などができないので
  • gradle 5.0 がリリースされると kotlin dsl が正式版となる。
  • 実際に触ってみたい

といったところで、デメリットとしてはとりあえず以下がある。

  • git clone して ./gradlew build したときの速度が groovy 使ってる場合よりもやや遅いらしい

で、実際に触ってみた感じの感想は以下。

  • ドキュメントが少ない(公式ドキュメントは現状 groovy で書かれているし)
  • プラグインごとに github.com を検索して回らないと書き方がよくわからない

現状では無理して移行する理由はないかな。

Created: 2018-11-14 15:18:07 +0900
Updated: 2018-11-14 15:18:07 +0900

Java9 だとspotbugs で OBL_UNSATISFIED_OBLIGATION 警告がでるとき

https://github.com/spotbugs/spotbugs/issues/493

try-with-resources してるのに leak しているという警告が出るので謎ダナーと思ったら spotbugs のバグみたい。

Created: 2018-11-12 13:24:36 +0900
Updated: 2018-11-12 13:24:36 +0900

spring boot 2.1+(spring framework 5.1+) applies `samesite=Lax` attribute to session cookie by default

https://github.com/spring-projects/spring-session/pull/1132/commits/f9e6bc7a3e2abd6ce25b13da98fae4d1655462bd

After boot 2.1, DefaultCookieSerializer applies samesite=lax attribute by default. As a result, the security risk was decreased.

But in the OAuth2 authentication process, OAuth2 provider can pass the data by POST method. It can't work with samesite=lax attribute(A browser won't send cookie).

You can configure the default behavior by following bean definition.

    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        cookieSerializer.setSameSite(null);
        return cookieSerializer;
    }
Created: 2018-11-09 18:09:56 +0900
Updated: 2018-11-09 18:09:56 +0900

lombok 1.16.22+ と gradle 4.9+ の食い合わせが悪いイシュー

Created: 2018-11-08 14:24:47 +0900
Updated: 2018-11-08 14:24:47 +0900

spring boot 2 で micrometer 使ってるときに、latency の percentile 値を prometheus に送る方法

https://blog.ik.am/entries/448 https://matsumana.info/blog/2018/04/25/spring-boot-uri-latency/

management:
  metrics:
    distribution:
      percentiles:
        http.server.requests:
        - 0.5
        - 0.75
        - 0.95
        - 0.99

このへんの設定しておくと便利だってバーの常連の人が言ってたので今後は設定するようにしようと思う。

Created: 2018-11-01 13:13:58 +0900
Updated: 2018-11-01 13:13:58 +0900

gRPC-WEB がもたらす我々の生活への変化

gRPC-WEB が GA となった。これが我々の生活にどのような変化をもたらすのかについて考える。

従来の gRPC の課題

gRPC は google が公開している RPC 方式であり、java, golang などの言語で利用可能になっている。 gRPC は protocol buffers over HTTP/2 を基本としているため、通信が multiplexing されるし、schema 定義がきっちりされるのでクライアント側とのコミュニケーションがしやすい。

一方、protocol buffers はbinary であるためにbinaryの取扱が苦手な Browser JavaScript からのアクセスが難しいという問題があった。

grpc-gateway

grpc-gateway という実装があって、これを利用すれば Browser JavaScript からのアクセスも可能ではある。しかし、専用の gateway server を golang で生成して運用することになって煩雑である。

また、client library を protobuf 定義ファイルから生成することができないので、そういった意味では、gRPC の魅力を 100% 引き出すことができていないといえるかもしれない。 もちろん、Swagger の定義を生成することができるので、そこから codegen することはできる。

外部に向けて JSON API を提供する必要がある場合には grpc-gateway は引き続き有力な選択肢となるが、SPA web application のためのエンドポイントの場合には、grpc-web の方が今後は良い選択となると私は考える

また、grpc-gateway はコミュニティ実装であるから、公式ではない。

gRPC-WEB

gRPC-WEB のプロトコルは PROTOCOL-WEB.md で解説されている。

多くのブラウザで動作するように、base64で encode する方法などが protocol で設定されている。

gRPC-WEB の実装

現在のところ nginx module と envoy というプロキシサーバーによる実装、grpcwebproxy という go 実装が提供されている。

nginx module

https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway/nginx

nginx module も提供されている。

grpcweb

https://github.com/improbable-eng/grpc-web/tree/master/go/grpcweb

grpcweb は go のライブラリ実装。既存の golang で書かれた gRPC サーバー実装の中に組み込んで、 gRPC-web で export する機能を追加することができる。 便利。

grpcwebproxy

https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy

golang で実装されている grpc-web の実装。go で single binary で導入できるので、一番導入が簡単そう。

envoy

Envoy は C++ で書かれた proxy server です。拡張が容易になっていて、C++ で簡単に拡張できるようになっています。

Envoy の grpc-web の実装は envoy の repository の中にあります。C++ ですがコメントがたくさんあるのでわかりやすいですね。

Envoy の中に実装されているのは、Proxy layer でカバーできていればすべてのサーバー実装で使えるので、まずは proxy layer で実装したということのようだ。

Envoy は C++ で書かれているのでビルドがそこそこ面倒なので docker での運用が現実的と思われる。プリビルドバイナリも提供されているが、ubuntu と alpine のみなので centos 勢としては悲しい。

今後の grpc-web の roadmap

https://github.com/grpc/grpc-web/blob/master/ROADMAP.md

このドキュメントで今後の ROADMAP が述べられている。 いくつか気になったところを紹介する。

非バイナリフォーマット

Binary の protobuf を base64 などにエンコーディングする方式は CPU overhead/memory overhead が大きい。よって、gmail などで採用されている、text protocol だが高速に処理できるフォーマットを使うようにすれば良いのではないか、とのこと。

Local Proxies

各言語用のサーバーライブラリの側に、gRPC-WEB サポートを追加しようというプラン。 今は go だけあるっぽい。Java support が待ち遠しい。

TypeScript support

これはほしい。Protobuf から生成されたクライアントに型情報が付けば、IDE 上での作業が快適になることは間違いない。

Web UI Support

gRPC-WEB を実際に試せる web console を作りたい、とのこと。

長期的な展望

whatwg streams api が各ブラウザに実装されて普及すれば、native の gRPC protocol を利用可能になるのではなるとのこと。

Created: 2018-10-31 14:14:31 +0900
Updated: 2018-10-31 14:14:31 +0900

sbt の %% と % の違い

groupID %% artifactID % revisiongroupID % artifactID % revision の違い。

If you use groupID %% artifactID % revision instead of groupID % artifactID % revision (the difference is the double %% after the groupID), SBT will add your project’s Scala version to the artifact name.

https://stackoverflow.com/questions/17461453/build-scala-and-symbols-meaning

Created: 2018-08-14 19:00:02 +0900
Updated: 2018-08-14 19:00:02 +0900

spring 5.1 で webflux に samesite 対応が入る

https://github.com/spring-projects/spring-framework/commit/09d9450154be796349dabdc606ade57beae08724#diff-f9fb34c95c900bb40a67429584ebcde4 spring 5.1 から cookie の SameSite のさぽーとが入るっぽい https://github.com/spring-projects/spring-framework/wiki/What's-New-in-Spring-Framework-5.x#whats-new-in-version-50

つまり、boot 2.1 以後は spring 5.1 なので、webflux 使ってれば samesite 属性使える。

Created: 2018-07-31 10:44:58 +0900
Updated: 2018-07-31 10:44:58 +0900

Spring IO platform が deprecated だった。。 今後は spring-boot-dependencies を使おう!

久々に http://platform.spring.io/platform/ みたら、"End of Life" の文字が。。

The Platform will reach the end of its supported life on 9 April 2019. Maintenence releases of both the Brussels and Cairo lines will continue to be published up until that time.

とのこと。。

Users of the Platform are encourage to start using Spring Boot's dependency management directory, either by using spring-boot-starter-parent as their Maven project's parent, or by importing the spring-boot-dependencies bom.

というわけで、spring-boot-dependencies bom を利用したら良いっぽい。

https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/gradle-plugin/reference/html/#managing-dependencies-using-in-isolation

によれば、今後は以下のようにすれば良い。Boot のバージョンを上げれば依存ライブラリも互換性のあるいい感じのバージョンに上がっていって便利! って感じっぽい。

apply plugin: 'io.spring.dependency-management'

dependencyManagement {
    imports {
        mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
    }
}
Created: 2018-07-30 19:21:04 +0900
Updated: 2018-07-30 19:21:04 +0900

ant の exec task で status code が non-zero のときにビルド失敗させるには failonerror="true"

<exec executable="python" failonerror="true"> とかすれば良い

https://stackoverflow.com/questions/7799778/ant-conditional-failure-upon-executable-failure

Created: 2018-07-27 00:15:06 +0900
Updated: 2018-07-27 00:15:06 +0900

Re: Java 7 時代の String#split() 事情

http://blog.k11i.biz/2013/05/java-7-stringsplit.html http://d.hatena.ne.jp/chiheisen/20110801/1312119289

Java 7 以後では String#split(String) で、引数が1文字の場合は最適化が効いて、高速になるという話。 社内でなんか話題になってたので最近の JVM だとどうなのかなーと調べてみた(元エントリは5年前のもの)。 (Pattern#split にもいずれ同様の最適化が入る可能性はあるので、このベンチマークの傾向は今でも一緒なのかなーと気になったため)

https://travis-ci.org/tokuhirom/java-string-splitting-benchmark

元のコードは手でベンチマークコードを実装されたものだったが、最近では JMH で簡単に書けるので、JMH で簡単に書いてみた。 以下は travis-ci で openjdk11 を走らせた結果。相変わらず pattern 1 文字の場合の最適化は有効になっていることはわかる。

Benchmark                                           (raw)   Mode  Cnt        Score         Error  Units
StringSplittingBenchmark.patternSplit                      thrpt    5  1550191.136 ±  475915.190  ops/s
StringSplittingBenchmark.patternSplit                  \s  thrpt    5   986040.695 ±  217942.160  ops/s
StringSplittingBenchmark.patternSplit     [ \t\n\x0B\f\r]  thrpt    5  1491352.737 ± 1025015.919  ops/s
StringSplittingBenchmark.patternSplit   |\t|\n|\x0B|\f|\r  thrpt    5   931442.162 ±  108993.004  ops/s
StringSplittingBenchmark.stringSplit                       thrpt    5  1820229.132 ±  564445.853  ops/s
StringSplittingBenchmark.stringSplit                   \s  thrpt    5   817729.421 ±   71545.171  ops/s
StringSplittingBenchmark.stringSplit      [ \t\n\x0B\f\r]  thrpt    5   774425.988 ±  128507.763  ops/s
StringSplittingBenchmark.stringSplit    |\t|\n|\x0B|\f|\r  thrpt    5   384563.020 ±   81302.831  ops/s

実際に travis-ci でバーっと走らせたときの結果は travis のサイトで見ることができる。 (travis 側の負荷状況によって結果が変わるので、参考程度だけれど) https://travis-ci.org/tokuhirom/java-string-splitting-benchmark


ちなみに今回、初めて JMH で @Param などのアノテーションを利用した。

以下のように記述することができて超便利〜。複数のパラメータを利用したベンチマークの実装が驚くほど簡単にできるのだ〜

    @State(Scope.Benchmark)
    public static class BenchmarkState {
        @Param({" ", "\\s", "[ \\t\\n\\x0B\\f\\r]", " |\\t|\\n|\\x0B|\\f|\\r"})
        private String raw;
        private Pattern pattern;

        @Setup
        public void setup() {
            pattern = Pattern.compile(raw);
        }
    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    @Benchmark
    public static void patternSplit(BenchmarkState state) {
        state.pattern.split(text);
    }

    @SuppressWarnings("ResultOfMethodCallIgnored")
    @Benchmark
    public static void stringSplit(BenchmarkState state) {
        text.split(state.raw);
    }
Created: 2018-07-15 00:01:26 +0900
Updated: 2018-07-15 00:01:26 +0900

spring boot + jib を試す

https://github.com/tokuhirom/jib-docker-spring-boot-examples

https://cloudplatform.googleblog.com/2018/07/introducing-jib-build-java-docker-images-better.html jib を使うと java app を極めて簡単に docker image にすることができるというので試してみた。

tutorial 通りにやったらすんなり動いた。あっけない。 よくできている。

Created: 2018-07-10 23:24:14 +0900
Updated: 2018-07-10 23:24:14 +0900
Next page