JFR の jdk.ExecutionSample では、STATE_RUNNABLE な Thread しか見れない。
必要であれば、async-profiler とかで見たほうが良いよ、と。 逆にいうと、STATE_RUNNABLE だけをとってるから、待ちになりがちな web system の場合、容量少なくプロファイリングできるということだな。
必要であれば、async-profiler とかで見たほうが良いよ、と。 逆にいうと、STATE_RUNNABLE だけをとってるから、待ちになりがちな web system の場合、容量少なくプロファイリングできるということだな。
https://github.com/tokuhirom/jfrdemo
JFR のイベントってどんなんあるんかなーと思ってもドキュメントとかが見当たらないし、確認の方法がよくわからないわけだが、、 実データを見るのが一番良さそうなのだが、実データ見るのがめんどくさいので、ある程度データを見れるように整理したというわけ。
Sep 27 23:41:00 dev3 docker[56810]: 2021-09-27 23:41:00.043 WARN 1 --- [nio-8080-exec-1] o.a.c.util.SessionIdGeneratorBase : Creation
of SecureRandom instance for session ID generation using [SHA1PRNG] took [140,998] milliseconds.
というようなエラーが起きるときがある(VPS などで /dev/random の entropy が十分ではない場合)。
これは FAQ で、 Java の起動オプションに -Djava.security.egd=file:/dev/./urandom
とつければよい。
spring boot のデフォルトは /dev/urandom を読む実装でいいと思うけれど。
昔はブログを MySQL ベースで運用していたのだが、、MySQL ベースでやってると運用がちょっとめんどくさくて、お金をかけずに自前でブログを運用するとなると、ファイルベースで管理したほうがなにかと楽だったというような歴史的経緯があり、ファイルベースでやっていたのだが、Digital Ocean の managed mysql が思ったより使い勝手が良いので、これを使うことにした。$15/Month ぐらい。 MySQL ベースのほうが、プログラミング言語を変える、とかもやりやすい。気がする(今のブログシステムは、なぜか最近全然使ってない Ruby で書かれていて、メンテがちょっとしんどい)。
何かの作業するとき用に VPS をなんとなく契約しているのだけど、すごい昔の centos で色々めんどくさくなったのでふっとばして ubuntu 20.04 に変更したよ。
test {
useJUnitPlatform()
testLogging {
// Make sure output from standard out or error is shown in Gradle output.
showStandardStreams true
showExceptions true
showCauses true
showStackTraces true
exceptionFormat TestExceptionFormat.FULL
}
}
とかする。github actions とかの場合は設定しておくと便利。
New-ScheduledTaskTrigger -Weekly -At $At -DaysOfWeek @("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
PowerShell 力が低くて難しかったけど、これで動いてそう。
caps2ctrl で remap していたが、なんか動かなくてぐぐってみると、microsoft が出している powertoys なら動くとのこと。 実際 powertoys を使ったらちゃんと動いた。 https://github.com/microsoft/PowerToys
lettuce-timer のスレッドとかが残ってうまくプロセスがシャットダウンでき無いとき。
Lettuce の場合 StatefulRedisClusterConnection
などのコネクションオブジェクトと RedisClusterClient
の他に ClientResources
も shutdown しないと、うまくプロセスが終わらないので要注意。
見逃しがち。
https://github.com/tokuhirom/jawiki-kana-kanji-dict
SKK-JISYO.L が最近、メンテナンスされてなくて れいわ /令和/
が入ってなかったりして困ってしまう。
そこで、neologd から辞書を生成してみた。 https://github.com/tokuhirom/skk-jisyo-neologd/ しかし、neologd は、形態素解析用の辞書としてはいいと思うのですが、かな漢字変換用として無理矢理使おうとすると誤変換になってしまうケースが多かった。
なので、直接 wikipedia からデータを抽出することにしてみた python で適当に抽出するスクリプトを書いて、github actions で設定した。これで、何もしなくても自動的に辞書がアップデートされていくはず。
pytest.ini に以下のように記述すればよい。
[pytest]
disable_test_id_escaping_and_forfeit_all_rights_to_community_support = true
Linux を server, Mac を client として synergy を使おうとした。
[2019-03-13T22:16:56] DEBUG: can't get the active group, use the first group instead
とかなんとか言われて、うまく動かない場合。
MacOS 側に "U.S." キーボードレイアウトがないと日本語入力できないらしい!これはわからん!!
Settings の "Keyboard" -> "Input Sources" から U.S. を追加すればOK。Google IME だけ、とかにしてると使えないのだった。
hirose31 san におしえてもらって解決しました!!!
なんかよくわからんが fakeroot の下だと file コマンドがうごかないのでなぞだった。
https://aur.archlinux.org/packages/mecab-ipadic-neologd-git/
なんかそれっぽく直した。
品質向上のために Spark クエリのユニットテストを実施したいという場合、JVM 言語で開発している場合には、Spark/hive をライブラリとしてロードできるから、容易に実装することができる。
dependencies {
implementation 'org.apache.spark:spark-core_2.12:3.0.0'
implementation 'org.apache.spark:spark-sql_2.12:3.0.0'
}
のように、関連するモジュールを依存に追加する。
以下のような、テストに利用するデータを json 形式などで用意する(spark は CSV, TSV などの形式も利用可能だから、好きなものを使えばよい)
{"name": "Nick", "age":35, "extra_fields": "{\"interests\":[\"car\", \"golf\"]}"}
{"name": "John", "age":23}
{"name":"Cathy", "age":44, "extra_fields":"{\"interests\":[\"cooking\"]}"}
あとは、実際に spark session を作成し、local モードで spark を起動させれば良い。
import org.apache.spark.sql.Dataset
import org.apache.spark.sql.Row
import org.apache.spark.sql.SparkSession
// test without
class SimpleTest {
fun run() {
val spark: SparkSession = SparkSession
.builder()
.appName("Java Spark SQL basic example") // your application name
.config("spark.master", "local") // run on local machine, single thread.
.config("spark.ui.enabled", false)
.getOrCreate()
val resourcePath = javaClass.classLoader.getResource("test-data/people.json")!!.toString()
println("++++ read csv from: $resourcePath")
val df = spark.read()
.json(resourcePath)
df.show()
df.printSchema()
println("++++ create table")
df.createTempView("people")
println("++++ select")
val sqlDF: Dataset<Row> = spark.sql("SELECT * FROM people")
sqlDF.show(false)
println("++++ select 2nd")
val sqlDF2: Dataset<Row> = spark.sql("SELECT name, get_json_object(extra_fields, '$.interests') interests FROM people")
sqlDF2.show()
println("++++ select 3rd")
val sqlDF3: Dataset<Row> = spark.sql("SELECT avg(age) avg_age FROM people")
sqlDF3.show()
}
}
fun main() {
SimpleTest().run()
}
実際に動かすクエリが select * from your_db_name.your_table
のようにDB 名を指定していて、そのクエリ自体を変えずにテストしたいという場合には、hive サポートを有効にする必要がある。
hive を使う場合、spark-hive を依存に追加する。
dependencies {
implementation 'org.apache.spark:spark-core_2.12:3.0.0'
implementation 'org.apache.spark:spark-sql_2.12:3.0.0'
implementation 'org.apache.spark:spark-hive_2.12:3.0.0'
}
あとは以下のように DB を作って入れるだけ。
import org.apache.spark.sql.Dataset
import org.apache.spark.sql.Row
import org.apache.spark.sql.SaveMode
import org.apache.spark.sql.SparkSession
class TestClass {
fun run() {
val warehouseLocation = createTempDir()
println("++++ warehouseLocation=$warehouseLocation")
val spark: SparkSession = SparkSession
.builder()
.appName("Java Spark SQL basic example") // your application name
.config("spark.master", "local") // run on local machine, single thread.
.config("spark.sql.warehouse.dir", warehouseLocation.toString())
.config("spark.ui.enabled", false)
.enableHiveSupport()
.getOrCreate()
val resourcePath = javaClass.classLoader.getResource("test-data/people.json")!!.toString()
println("++++ read csv from: $resourcePath")
val df = spark.read()
.json(resourcePath)
df.show()
df.printSchema()
println("++++ create table")
spark.sql("create database if not exists foo")
df.write().mode(SaveMode.Overwrite).saveAsTable("foo.people")
spark.sql("show tables").show()
spark.sql("show create table foo.people").show(false)
// If the type of data is the important thing, you need to write your schema by yourself.
// spark.sql("""drop table if exists `foo`.`people`""")
// spark.sql("""
// CREATE TABLE `foo`.`people` (
// `name` STRING,
// `age` long,
// `extra_fields` STRING)
// USING parquet""".trimIndent())
// df.write().insertInto("foo.people")
println("++++ select")
val sqlDF: Dataset<Row> = spark.sql("SELECT * FROM foo.people")
sqlDF.show(false)
println("++++ select 2nd")
val sqlDF2: Dataset<Row> = spark.sql("SELECT name, get_json_object(extra_fields, '$.interests') interests FROM foo.people")
sqlDF2.show()
println("++++ select 3rd")
val sqlDF3: Dataset<Row> = spark.sql("SELECT avg(age) avg_age FROM foo.people")
sqlDF3.show()
}
}
fun main() {
TestClass().run()
}
クエリを変更しなくていいというメリットがある一方で、hive にアクセスするので依存も増えるし、実行もめちゃくちゃ遅くなります。
df.write().mode(SaveMode.Overwrite).saveAsTable("foo.people")
のようにすると、df 側の型をみていい感じにテーブル定義してくれて便利だが、明示的に create table したいときは以下のようにしたほうがいいかも。
spark.sql("""drop table if exists `foo`.`people`""")
spark.sql("""
CREATE TABLE `foo`.`people` (
`name` STRING,
`age` long,
`extra_fields` STRING)
USING parquet""".trimIndent())
df.write().insertInto("foo.people")
hive を利用しない場合、上記コードは 4.427 sec 程度で終わりますが、hive を利用する場合は 19.676 sec 程度かかるようになります。 プロダクションコードのテストをする場合はこの差はそこそこでかいかも。
-s, --silent
Silent or quiet mode. Don't show progress meter or error messages. Makes Curl mute.
で silence できるが、これを入れると、error message も抑制されてしまう。
-S, --show-error
When used with -s it makes curl show an error message if it fails.
-S を追加で入れると、エラーは stderr に出るようになるのでちょうどいい感じになる。
https://github.com/stefanbirkner/system-rules
stdout/stderr の出力をキャプチャするのに systemrules が便利だが、junit5 対応はしていない。 junit5 に対応するためには system-labmda を使う。
https://github.com/stefanbirkner/system-lambda
インターフェースも junit に密結合していなくて、きれい。
生JDBCで適当にデータ出してデバッグしたいって時につかうやつです。
protected void selectAndPrint(Connection connection, String query) {
log.info("======> dumpTable: {} <====", query);
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
try (ResultSet rs = preparedStatement.executeQuery()) {
ResultSetMetaData metaData = rs.getMetaData();
log.info("| {} |", IntStream.range(0, metaData.getColumnCount())
.mapToObj(i -> {
try {
return metaData.getColumnName(i + 1);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.joining(" | ")));
while (rs.next()) {
log.info("| {} |", IntStream.range(0, metaData.getColumnCount())
.mapToObj(i -> {
try {
return rs.getString(i + 1);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.joining(" | ")));
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
Data([0xDE, 0xAD, 0xBE, 0xEF])
こんな感じ。Data とか、一般的な名前すぎてググってもなんか見つけにくい。
http://archive.apache.org/dist/thrift/ からダウンロードする。
https://stackoverflow.com/questions/20068947/how-to-static-link-linux-software-that-uses-configure
sudo yum install glibc-static -y
./configure --enable-static --without-ruby --without-nodejs --without-php --without-python --without-c_glib --without-go --without-nodejs --without-lua CFLAGS="-static"
make -j9 LDFLAGS="-all-static"
osx では static build ができないので諦める。
brew install bison
export PATH="/usr/local/opt/bison/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/bison/lib"
./configure --without-ruby --without-nodejs --without-php --without-python --without-c_glib --without-go --without-nodejs --without-lua
make -j 9
https://stackoverflow.com/questions/623104/byte-to-hex-string
の通りにやればいい。
byte[] data = { 1, 2, 4, 8, 16, 32 };
string hex = BitConverter.ToString(data);
// Result: 01-02-04-08-10-20
標準ライブラリでこういう表現できるのは便利だなーという感想。