サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
衆院選
eagletmt.hateblo.jp
Rust には bindgen というツール、あるいはライブラリがあって binding を書くときに非常に重宝する。 https://rust-lang.github.io/rust-bindgen/ これを濫用すると C のヘッダファイルを解析してマクロの定数値を読み取ったり構造体のサイズを調べたりといったことが手軽に可能そう。 たとえば errno の名前と値とメッセージの一覧を知りたいとき、こんなかんじで errno.h の中身から定義を取り出すことができた。 lazy_static::lazy_static! { static ref MACROS: std::sync::Mutex<std::cell::RefCell<Vec<(String, i32)>>> = Default::default(); } #[derive(Debug, Default)] struct Ma
ISUCON10 に続き今回の ISUCON11 でも初期実装の Rust 移植を担当したのでそのへんの話を書いてみます。 ISUCON とのかかわり ISUCON4 から ISUCON7 までは選手として参加していて、何度か本選にも出場しました。ISUCON8 以降に参加しなくなった理由はいくつかあるんですが、Web のインフラやバックエンド界隈を盛り上げて学生の興味を惹く素晴らしいイベントだと思っています。そんなわけで ISUCON からはしばらく離れていたんですが、ISUCON10 では同僚が作問するということと新たな試みとして初期実装に Rust を加えると聞いて、Rust 移植担当に応募して採用されました。そして今回の ISUCON11 でも Rust か Ruby の移植に応募し Rust の移植を担当しました。 言語移植を担当するモチベーション 自分の場合は ISUCON が
プライベートでよく PostgreSQL を使っている人の MySQL 不便シリーズ。 ActiveRecord のような高機能な ORM あるいはクエリビルダを使っていると bulk insert するクエリをライブラリがいいかんじに組み立ててくれるが、そんな高級なライブラリを使わずにもっとシンプルなもので済ませたいことがある。 そんなときに bulk insert をしたくなった場合、クエリを組み立てて変数を bind して…… というのを自分でやるのは結構面倒である。 PostgreSQL だと配列型があり unnest() で配列を行に変換できるので、これと insert into select を組み合わせると bulk insert するクエリを簡単に組み立てられる。 eagletmt=> select unnest(array[1,2,3]) as x, unnest(arr
envchain とは macOS の keychain または Linux の D-Bus secret service に API キーのような秘密の情報を安全に保存し、環境変数として取り出せる CLI ツールである。 https://github.com/sorah/envchain 僕は envchain の大ファンで、当初 macOS 向けに書かれていた envchain に Linux サポートを加えたりしていた。 そんな envchain をずっと愛用していたのだけど、Windows を使うようになってから WSL2 内で使いにくいことが気になっていた。 Linux 向けには D-Bus secret service (ほぼ実質 gnome-keyring) を使っているため、WSL2 内で D-Bus を起動したり X サーバを起動したりする必要がある。 無理ではないんだけ
ssh-agent のように daemon として起動し秘密の情報を保持しつつ別プロセスと通信するようなプログラムを書きたくて、ssh-agent はどう実装しているのかざっくり調べた。 https://github.com/openssh/openssh-portable 通信方法 これは普通に ssh-agent を使っていてもすぐ気付くことだけど、ssh-agent は UNIX domain socket を使って通信している。 eval $(ssh-agent) のように実行すると SSH_AUTH_SOCK と SSH_AGENT_PID の2つの環境変数がセットされ、SSH_AUTH_SOCK は UNIX domain socket のパスを、SSH_AGENT_PID は daemon 化した ssh-agent の pid を指している。 SSH_AUTH_SOCK は
まとめ netlify_lambda を使う Lambda の Docker イメージサポートを利用する aws-lambda-rie-gateway を使う この構成で Slack の interactive message や block kit で遊んだサンプルがこれ https://github.com/eagletmt/misc/tree/master/rust/slack-slash-command-sample Rust 向けの Lambda Runtime lambda-runtime という準(?)公式の crate がある https://github.com/awslabs/aws-lambda-rust-runtime が、リリースが滞っている。 現在リリースされている中での最新版では async/await の対応すら入っておらず、現在の Rust では正直使い物
switch_point を4年ぶりにリリースした。このリリースは主に ActiveRecord v6.1 以降をサポートしない意志を表明するためのものである。 github.com switch_point は6年前に仕事で困ったことを解決するために書いた gem である。経緯は https://eagletmt.hateblo.jp/entry/2014/09/22/203819 を参照。この記事にある「Rails の激しい変更についていきやすい設計・実装」は成功したと思っていて、バージョンや respond_to? による分岐を一切せずに ActiveRecord v3.2 から v6.0 までサポートすることに成功している。 しかしまもなくリリースされるであろう ActiveRecord v6.1 では ActiveRecord::ConnectionAdapters::Conne
自分は音楽の購入・管理サービスとして Google Play Music を使っていた。楽曲だけでなく、ドラマ CD だったり音声作品だったりにも Google Play Music を使っていた。しかし Google Play Music がサービスクローズになり、YouTube Music へと移行せざるをえなくなった。ストア機能が失われることに不満を感じつつも他に選択肢も無いので YouTube Music に移行したところ、音楽の再生に関する機能も若干使いづらい上に (Google ではなく) YouTube のアカウントと紐付いてしまって破滅したりアップロード機能が致命的に機能不足だったりと最悪の体験だった。あまりに最悪すぎて Apple Music へと徐々に移行していっているところなんだけど、そのへんの話を書いてみる。 音楽の購入・管理サービスの種別 自分にとって大きく分けて
皆さんは財布を紛失したことはありますか? 私はあります。 紛失してからいつのまにか2年以上経過していたので、当時の思い出を書いてみる。 紛失したとき 自分の場合は電車で出掛けた先の某ゲームセンターで財布がなくなっていることに気付いた。自宅から出たときにはたしかに持っていたはずだけど、Suica やゲーセン用の小銭は別に持っていたので、自宅から最寄り駅までの間で紛失したのか、電車内で紛失したのか、降りた駅からゲーセンまでの間で紛失したのか、ゲーセン内で紛失したのか分からなかった。ゲーセン内の心当たりある場所を探しても見つからず、店員に落とし物のことを聞いても見つからず、この時点で紛失したと判断した。 紛失した財布の中にはクレジットカードが入っていたため、自分の場合はまずクレカの無効化と再発行を電話で依頼した。そして近くの交番へ行って遺失届を出した。たぶん先に遺失届を出すほうが正解だった。その
給付金や中止になった色々なイベントの返金で気が大きくなった結果、Ryzen 9 3900X を使った新しいメインデスクトップマシンを組んでいた。構成はこんなかんじ。 CPU: AMD Ryzen 9 3900X 3950X も考えたけど、コスパ重視で 3900X のほうを選んだ AMD の CPU を買うのは今回が初めて GPU: NVIDIA GeForce GTX 1660 Super (GG-GTX1660SP-E6GB/DF) せっかく Windows をメインマシンにするならということで快適にゲームできそうなところを選んだ 正直知見が薄いので GTX 1660Super に決めた後は適当に買いやすいのを選んだ RTX はまぁ要らんやろ…… MB: ASRock X570 Extreme4 自分の趣味により基本 ASRock 余分な M.2 の口とかが欲しい前提で Steel Le
自分の中でなんとなく納得がいっただけでとくに結論は無い。 そして今年ここに全くエントリを書いてなかったことにいま気付いた。 ふとしたきっかけで発表するのを好む人の気持ちが気になった。その人は発表スライドだけ見ても話の内容が十分に伝わらず、その場のトークと資料が合わさって初めて成り立つような発表をするタイプのように僕には見えた。その人に限らず、こういうタイプの人はまぁ普通によくいると思う。 一方僕は真逆のタイプで、スライドだけを見てもそれなりに伝わるものを作りがちだ。スライドを読み上げてるだけじゃんという意見も目にしたことがあるけど、実際その通りで口頭で発表するよりドキュメントやブログ記事を書いて公開したほうが良いと思っていて、発表というのはまぁ宣伝効果があるとかそれくらいにしか思っていないところはある。 で、なんで自分はそう思ってるんだろうと考えてみると、受け手側が参照するコストをできるだ
ISUCON7 予選に†空中庭園†《ガーデンプレイス》として @ryot_a_rai、@mozamimy と参加して2日目1位で通過することができた http://isucon.net/archives/50956331.html 。 リポジトリは https://github.com/ryotarai/isucon7q 当日まで 例年 Ruby で参加していたけど、今年は発表された初期実装に Ruby が含まれていなかったこと (※後から追加された) もあり、@ryot_a_rai から Go で参加したいという話が出て Go を選択した。 僕と @mozamimy は Go はまぁまぁ書いたことはあるくらいの状態だったので、事前に一度 Go で練習したり pprof の使い方を教えてもらったりしていた。 Go は個人的にはあんまり好きになれなかった言語ではあるんだけど、ISUCON で
params の中身のように入っているオブジェクトのクラスが事前に分からないものに対して空っぽい文字列の場合と存在しない場合を区別したくないときに限って blank? を使うのは分かるけど、 nil チェックをするために blank? を使ったり、配列が空かどうかをチェックしたいだけなのに blank? を使ったりすると、 blank? の挙動を正確に理解して nil と空配列を区別したくないから使っているのか、それとも nil がくるかどうか分からないので適当に防御的に blank? を使っているのか、 あるいは blank? しか知らないのかが読みとれずにめんどくさいと思うことがよくある。 かわりに empty? を使っていれば empty? を持っているオブジェクトは blank? を持っているオブジェクトより少ないので読み手に伝わる情報量が大きくなるし、 かわりに nil? を使っ
前提知識 Rails アプリにおいて、テーブルの追加やカラムの追加は簡単なものの、カラムの削除やリネームは慎重に行う必要がある。たとえアプリからそのカラムを参照してないとしても、いきなりカラムを削除するとエラーになる可能性が大いにある。 というのも Rails にはスキーマキャッシュというものがあり、テーブルのカラム情報をモデルがキャッシュしているからだ。このキャッシュはたとえばいわゆる N+1 クエリ問題を避けるために includes (eager_load) するときに参照される。 SELECT 句で t0_r0 のような機械的に別名が振られるようなクエリを見たことがある Rails エンジニアは多いと思う。 機械的に全カラムを取得するためにスキーマキャッシュを利用しているため、このようなクエリが実行されてる中でカラムを削除したりリネームしたりすると、スキーマキャッシュをもとに並べら
Docker は iptables を前提として書かれており、nftables を使っている環境ではそのままだと動かない。 issue は既にあったんだけど nftables を使っている環境はまだまだ少なそうだし進まなそう https://github.com/moby/moby/issues/26824 。 とはいえ iptables でやってることは少ないので、ちょっと設定を足せば動かせる。 とりあえず dockerd に iptables を触らせないようにして、 # /etc/systemd/system/docker.service.d/override.conf [Service] ExecStart= ExecStart=/usr/bin/dockerd -H fd:// --iptables=false あとは nftables の設定で masquerade を足せばい
itamae と比較して mitamae のメリットをシングルバイナリ以外にも作りたいなと思って mitamae の高速化を進めている。 高速化の方針は「できるだけ Ruby (mruby) のプロセス内で実行する」というもの。 itamae と mitamae の差の一つに SSH サポートや Docker サポートがあって、itamae は SSH 越しに実行したり Docker コンテナに対して実行したりできるが、mitamae はローカルのみをサポートしている。 mitamae では未実装なだけかと思ったが、既に一部の実装がローカル実行前提のようだったので、だったらその前提で外部コマンドを使わずに Ruby でファイルの存在などをチェックすることで高速化できるだろうと考えた。 実は itamae のときにも同じことをやろうとしていて実際に ちょっとだけ作ってみていた んだけど、うま
構成管理ツールを使う上で悩ましい問題として秘匿値の管理があり、それに対する解決策の一つとして itamae 向けには itamae-secrets というものがあった。 自分も秘匿値の管理にこの itamae-secrets を使っていたが、この度 mitamae に移行してみようと思い、mitamae で使える itamae-secrets として mitamae-secrets というものを書いた。 https://github.com/eagletmt/mitamae-secrets mitamae-secrets の暗号化・復号を実装するためには OpenSSL が必要だが、mruby 向けの OpenSSL バインディングはまだ存在していないようだったので、必要な部分だけ OpenSSL の関数を使いながら C で実装する形にした。 EVP という高レベルの API をそのまま使
IPv6 のアドレスが1つしかない状況で、ネットワークが分離されたコンテナから IPv6 で通信しようとすると IPv6 だろうと NAT が必要になる。 このへん Docker がどう扱うのかよくわかってなくて、結局 Docker の外側で docker0 とか ip6tables を管理することで動いた…… まず docker0 に使うレンジを決める。ここでは fdbb:3f26:ceda::/48 と 10.11.0.0/16 とする。 docker0 を systemd-networkd で作る。 % cat /etc/systemd/network/docker0.netdev [NetDev] Name=docker0 Kind=bridge % cat /etc/systemd/network/docker0.network [Match] Name=docker0 [Net
https://gist.github.com/eagletmt/3e064fcbe2935a8356bc8658c8e472c1 require_relative '../infer_type' RSpec.configure do |config| config.before(:suite) { @infer_type = InferType.new; @infer_type.start } config.after(:suite) { @infer_type.finish } end たとえば上記のように RSpec のフックに仕掛けて INFER_TYPE_TARGET=YourAwesomeApp:: bundle exec rspec とかやるとテストから適当に推測されたクラスが表示される。 とりあえず nullable かどうかと、TrueClass と FalseClass
これまで tmux は文字幅を得るために独自のテーブルを持っていて、その独自テーブルでは East Asian Ambiguous Width というものを一切考慮していないので、CJK な環境ではパッチをあてて使うことがよく行われていた (tmux cjk patch とかでググるといろいろ出てくると思う)。 tmux 2.2 からは wcwidth(1) を使うようになり、独自テーブルをやめてロケールの情報から文字幅を得るようになった https://github.com/tmux/tmux/commit/26945d7956bf1f160fba72677082e1a9c6968e0c 。 が、このコミットをよく見ると setlocale(LC_CTYPE, "en_US.UTF-8") で固定されており、LC_ALL や LC_CTYPE に関係なく en_US.UTF-8 が使われ
たとえば変なレコードが混じってしまったせいで何度リトライしてもバッファのフラッシュに失敗するようなときに、バッファファイル (buffer_type file で作られるやつ) を使っていれば、そのファイルをいじることで応急処置ができる。 バッファファイルは [tag, time, record] という三つ組の列を msgpack でシリアライズした形式になっていて、v0.12.x と v0.14.x で time の型が違う *1 けど、どちらのバージョンでも以下のようなコードでバッファファイルを読み書きできそう。 なお v0.12.x において Fluent::Engine.msgpack_factory が追加されたのは v0.12.17 から なので注意。 require 'fluent/engine' in_path = '/path/to/some-buffer.q01234
学生や新卒の人と話したりするときに、これまでエンジニア的にどうやって今の状態になったかみたいな話を何度もする機会があって、 その度に色々思い出しながら話してたんだけど、自分用に整理したかったのでついでにオンラインでアクセスできる場所に置くことにする。 なにか新たに思い出したり思い出補正が発覚したりしたら適宜修正していく。 小学生くらい (- 2002) 学校に自由に使える PC があって、卒業するくらいの時期には古いやつと新しいやつの2つがあって、新しいやつのほうに入っていたタイピングゲームで主に友人の K 君と遊んでいた記憶がある。 もう全然覚えてないけど、時期的には古いほうが Windows 95 で新しいほうが Windows 98 だろうか。 自宅にも PC があって、麻雀ソリティアで遊んでいた記憶がある。 PC に初めて触れたのはこのくらい。タイピングゲームに熱中したおかげで、タ
--net=host でコンテナを起動すれば、network namespace が分離されないので net.core.somaxconn の値はホスト側と一致する。 % cat /proc/sys/net/core/somaxconn 1024 % docker run --net=host ubuntu:16.04 cat /proc/sys/net/core/somaxconn 1024 けど普通に docker run すると、ホスト側の値にかかわらず、コンテナ内ではデフォルトの128になる。 % cat /proc/sys/net/core/somaxconn 1024 % docker run ubuntu:16.04 cat /proc/sys/net/core/somaxconn 128 で、コンテナ内でこの値を変えようとしても、デフォルトでは許可されていない。 % doc
5年半くらい前に http://d.hatena.ne.jp/eagletmt/20100905/1283686004 というのを書いたけど、そこから今どう変わっているのか。 こう列挙してみると2016年になっても Linux デスクトップは… みたいな気持ちも無いわけじゃないけど、色んなコンポーネントを好きなように設定できたり入れ替えることができたり、場合によってはパッチをあてることもできて、そのへんが好きで使っている。 もちろん、仕事では Linux で動作するようなコードばかり書いたり読んだりしているので、そのへんの知識を手元でも使えたり手元とサーバの違いではまったりしにくいから、というのもあるけど。 ディストリビューション 相変わらずずっと Arch Linux を使っている。 パッケージの更新が早かったり、最小限のデフォルトしか設定されていないのでディストリビューションが勝手に設
ちょっと前までは machinectl pull-dkr というコマンドがあったんだけど、Docker の考えるコンテナと systemd-nspawn の考えるコンテナの差が大きいこともあって消されている。 とはいえ、Docker コンテナも systemd-nspawn (machinectl) で扱うコンテナも本質的に違うものではないので、Docker で作ったコンテナを systemd-nspawn で動かせないこともない。 以下、mysql:5.6 を例に使った作業メモ。 イメージのままだと export できないので、適当に起動してコンテナを作ってから export して、適当なディレクトリに展開しておく。 % docker run --detach mysql:5.6 false 9872d546b6d1f245f25b895ef4c05725d3fdba30d604c118
ホスト側から見てなんか挙動が怪しいプロセスがいてその PID が分かったときに、どの Docker コンテナで動いているプロセスなのか知りたいことがある。 docker ps -q | xargs -n1 docker top で全ての container id と PID の対応をリストアップして探すことでも達成できるけど、Docker はコンテナを起動するときに cgroup を作ってそのパスに container id を使っているので、/proc/$PID/cgroup を見れば一発で container id がわかることに気付いた。 % cat /proc/29823/cgroup 9:freezer:/docker/e9e7fa08af0c5478ac379ca587ad2850ffd2a0b72b97b05201d45f3337f4750e 8:cpu,cpuacct:/d
しゃかいじんじゅうねんめ 去年は https://eagletmt.hateblo.jp/entry/2022/12/31/165730 仕事 今年は会社の状況が大きく変わった年だった。退職勧奨やレイオフ、その変化による自主的な退職でとにかく人が減った。それによって自分の仕事にも当然変化があり、今年の後半はイギリスにいるメンバーとコミュニケーションをとる機会が増えた。その関係で一週間ほどイギリスに滞在する機会もあった。海外に行くのは2019年のシアトル以来で、シアトルもなかなか遠かったがイギリスは更に遠い。イギリスは楽しめたが14時間のフライトは拷問以外の何物でもない。 イギリスにいるメンバーとコミュニケーションをとる機会が増えたということは英語でコミュニケーションをとる機会が増えたということで、これが自分にとっては大変だった。Slack や GitHub で英語話者とコミュニケーションを
systemd というと unit ファイルを書いてデーモンを起動して、というイメージが強いかもしれないけど、systemd-run を使うと単発のコマンドを systemd の管理下で実行できる。 こうすることで、CPUQuota=50% とか MemoryLimit=10M とか BlockIOWeight=10 のようにリソースを制限でき、しかも実行中に変更することもできる。 たとえば http://hb.matsumoto-r.jp/entry/2015/12/02/133448 にあるような CPU 使用率を制限しながら yes を実行する例だと、 % sudo systemd-run --scope --uid=eagletmt -p CPUQuota=10% yes > /dev/null Running scope as unit run-rcab5dc0a5f8e4620
Unicorn 5.0.0 がリリースされていて、most boring major release と自称している中、新機能として sd_listen_fds(3) emulation がある http://bogomips.org/unicorn-public/20151101-unicorn-5.0.0-rele@sed/t/ 。 sd_listen_fds(3) は systemd の socket activation という機能に対応するための単純な関数で、socket activation は簡単に言うと systemd が listen してその fd を service unit のプロセスに渡す機能。 この機能の詳細やモチベーションを説明するのは面倒なので作者のブログ記事などを読んでほしい http://0pointer.de/blog/projects/socket-
次のページ
このページを最初にブックマークしてみませんか?
『eagletmt's blog』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く