Kroutonの睡眠を支えるほげほげ
この記事は whywaita Advent Calendar 2020 - Adventar 11日目の記事です
前回は kyontan の ICTSCのコンテストサイトを支えた技術 でした! 飛行機乗りたいけど免許も取りたいしそもそも机とかも欲しいので優先度ガタ落ちしてます!!!!ちなみにあんま元気じゃないです、kyontanさんは卒業できそうですか??
本筋
ところでみなさん睡眠してますか?してない方は成仏してくださいませ。僕は睡眠は好きなのですが、如何せん下手くそです。長く寝れないし寝付きもまともにできない...、車の中はもちろん、飛行機、新幹線や電車(グリーン車含む)でも寝れないし、旅行先の寝具が違う環境になるだけで寝れなくなります。
旅先
レム睡眠3割!!!旅行好きなのにホテルだと睡眠が大抵しんどいので困った...。大体悪夢見ますよね旅行先だと、前は歯が全部抜ける夢見ました。
自宅で普通に寝れた時
深い眠りが短く下手くそなのは今後の課題なのですが、それはそれとして前は自宅でも寝付くことができませんでした。
そんな自分が多少は寝付けるようになった色々を紹介していきたいと思います。
枕 ロフテーキューブ(羽毛) 4号*1
社会人になってから真っ先に買ったものです。肩幅デカい族なので4号が良い。
他のメーカーの枕をあまり試していないのですが、とりあえず横浜の実店舗に行って試せたのがめっちゃプラス。店員さんが布団の硬さや自分の骨格と好みに合わせて選んでくれるのでとても助かる。
加重毛布
これがとても良い。このように全てを破壊してしまくらい寝相悪いので朝起きたら毛布無いなんてザラ。
これ被せてから起きた時に毛布かぶってる率が80%くらいまで上がった。その代わり二度寝率も上がったけど。
メラトニン
はい、メラトニンのサプリメントです。多分19時とか20時くらいに飲むといい感じに眠くなるのですが、ゲームやコーディングしてるとすぐ飛んじゃうので結局それらが終わってからいつも飲んでます。
商品より送料のほうが高いし、60個入りのものを1つずつしか税関の都合上買えないのが難点。後述する薬を飲み始めるまではとても頼りにしていました。
リーゼ(クロチアゼパム) 5mg
ついに出てきました、精神科/心療内科などで処方されるお薬です。寝る前に飲んでいます。不眠とは別で通っているのですが、そこそこ催眠作用が強い割に依存性が強くないのでいいですね。前は朝にも別の薬と同時に服用してましたが本当に仕事にならないので止めました。
飲酒をしない
上2つのサプリメントと薬を服用し始めてからかなり減らしました。飲むにしても早い時間とか、入眠失敗してもいい日だけ飲むようにしてます。もっとお酒飲みたい〜〜〜〜〜〜〜
結び
睡眠は大事にしましょう、明日は id:nersonu さんの当番です!!!!
追記 (2020/12/11 16:06)
Kroutonの睡眠を支えるほげほげ - KRAZY感情STYLE枕良さそう.今使ってる枕なんか合ってない気がするので気になる.セニラン飲んでるのでだいたい仲間っぽい.ところで睡眠測定するアプリなんてやつですか
2020/12/11 11:41
Xiaomi の mi band 5 ってスマートウォッチをつけて寝てます!
*1:画像は公式サイトから引用
ISUCON10にTrust Rustチームとして参加して予選敗退しました
てがきはてなブログがリリースされた日に書いたんですけど誤操作で消しちゃって萎えてましたが再度書きました。一緒に出てくれてた id:dekokun と id:stefafafan には感謝です。僕は実装を読んでゴリゴリやる役目だったのに筋力が足りなくて全然出来ませんでした、来年はもっと強くなります。
チームメイトのエントリ
具体的に何したとかはチームメイトの奴を読んだほうが早いです
std::sync::mpsc::channelで少しハマったのでメモ
std::sync::mpsc - Rustの挙動についてちょっと知見を持ったので綴っていく。
やりたいこと
めっちゃ重たいタスクがN個あって、それぞれにスレッドを作ってmpsc::channel
経由でメインスレッドに値を返してもらう例を考える。
use std::thread; use std::sync::mpsc; let (tx, rx) = mpsc::channel(); for costly_task in costly_tasks.into_iter() { let tx = mpsc::Sender::clone(&tx); thread::spawn(move || { let val = costly_task(); tx.send(val).unwrap(); }); } for val in rx { dbg!(val); }
これだと実は下のfor文を抜けることは出来ない。実際にplaygroundでやると強制的にkillされていることが確認できる。
ではどうするのか?というと for文の前で drop(tx);
を呼んであげる必要がある。
for costly_task in costly_tasks.into_iter() { // ... } drop(tx); for val in rx { // ... }
僕みたいになぜ?となった方へこの問題をもう少し簡単にしてみる。ならなかった人はスター押してはてブ追加して頂ければ大丈夫です。
簡単にした例
use std::sync::mpsc; let (tx, rx) = mpsc::channel(); let tx1 = mpsc::Sender::clone(&tx); tx1.send(1).unwrap(); for val in rx { dbg!(val); }
これも同様にfor文を抜けることが出来ない。というわけで drop(tx); drop(tx1);
を追加してみると同様に抜けることができる。
どうやらfor _ in rx { ... }
はsenderが値が送りきるのを待つ挙動をしているようだ、とのことでドキュメント 1 を確認しに行く。
Returns an iterator that will block waiting for messages, but never panic!. It will return None when the channel has hung up.
うんうん、推測は当たっていたようだ。Sender::send
は &self
なので、1回値を送っただけではdropしない。なので、rx
はtx
達が生きていることが分かっているので明示的にdrop
してあげないとforから抜けれなかったわけか。
ということは
use std::thread; use std::sync::mpsc; // このtxは使ってないけど明示的にdropさせる必要がある let (tx, rx) = mpsc::channel(); for costly_task in costly_tasks.into_iter() { // ここの tx は for が回るたびにスコープから抜ける => drop する let tx = mpsc::Sender::clone(&tx); thread::spawn(move || { let val = costly_task(); tx.send(val).unwrap(); }); } // 明示的にdropしてあげる drop(tx); // 全部のSenderがdropしているのでこのforはちゃんと抜けられる for val in rx { dbg!(val); }
ってわけですね、少しハマったのでメモです
宣伝
今回の挙動を確認したりドキュメントを読んだりするのにrust-jpのSlackで質問を投げていました。活発なコミュニティで優しい方が多いので皆さん入りましょう!!
-
本当は
into_iter
なんだけどなかったしiter
でも同じでしょう↩
Derive macrosを使ってstructにBuilder Patternを生やしてくれるやつを書いてみた
こんばんは、id:Krouton です。ISUCON10にRustで参加した話をてがきはてなブログで書こうと思ったら消えたので萎えました。ISUCON11までには書きます。多分...。
本題
Derive macros使ってますか?serdeとか使うと出てくる #[derive(Serialize, Deserialize)]
の部分ですね。
Derive macrosでstructにBuilder Patternの実装を提供してくれる良さそうなライブラリ*1があって、練習のために実装の真似をしてました
use proc_builder_pattern::Builder; #[derive(Default, Builder)] struct Point { x: usize, y: usize, }
ってやったら
struct Point { x: usize, y: usize, } impl Point { fn x(self, val: usize) -> Self { Self { x: val, ..self } } } impl Point { fn y(self, val: usize) -> Self { Self { y: val, ..self } } } Point::default().x(1).y(2)
って感じに使うことができます。
最初は解説を書こうと思ったけど実装とドキュメント読めば自明じゃね!?って思ったので実装したリポジトリだけ置きます、参考にしたライブラリは初期化してないメンバを検知する機構があったり、Into
binutilsが入ってるとopamでswitch createした時のビルドに失敗するっぽい?
➜ ~ opam switch create 4.09.0 <><> Gathering sources ><><><><><><><><><><><><><><><><><><><><><><><><><><> 🐫 [ocaml-base-compiler.4.09.0] downloaded from cache at https://opam.ocaml.org/cache <><> Processing actions <><><><><><><><><><><><><><><><><><><><><><><><><><> 🐫 ∗ installed base-bigarray.base ∗ installed base-threads.base ∗ installed base-unix.base [ERROR] The compilation of ocaml-base-compiler failed at "/Users/krouton/.opam/opam-init/hooks/sandbox.sh build make -j15 world". #=== ERROR while compiling ocaml-base-compiler.4.09.0 =========================# # context 2.0.7 | macos/x86_64 | | https://opam.ocaml.org#0f1d4fba # path ~/.opam/4.09.0/.opam-switch/build/ocaml-base-compiler.4.09.0 # command ~/.opam/opam-init/hooks/sandbox.sh build make -j15 world # exit-code 2 # env-file ~/.opam/log/ocaml-base-compiler-4548-6cc03f.env # output-file ~/.opam/log/ocaml-base-compiler-4548-6cc03f.out ### output ### # ld: symbol(s) not found for architecture x86_64 # [...] # "_caml_weak_set", referenced from: # _caml_builtin_cprim in prims.o # "_main", referenced from: # implicit entry/start for main executable # ld: symbol(s) not found for architecture x86_64 # clang: error: linker command failed with exit code 1 (use -v to see invocation) # clang: error: linker command failed with exit code 1 (use -v to see invocation) # make[1]: *** [ocamlrund] Error 1 # make[1]: *** Waiting for unfinished jobs.... # make[1]: *** [ocamlruni] Error 1 # make: *** [coldstart] Error 2 <><> Error report <><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 🐫 ┌─ The following actions failed │ λ build ocaml-base-compiler 4.09.0 └─ ┌─ The following changes have been performed (the rest was aborted) │ ∗ install base-bigarray base │ ∗ install base-threads base │ ∗ install base-unix base └─ <><> ocaml-base-compiler.4.09.0 troubleshooting <><><><><><><><><><><><><><> 🐫 => A failure in the middle of the build may be caused by build parallelism (enabled by default). Please file a bug report at https://github.com/ocaml/ocaml/issues => You can try installing again including --jobs=1 to force a sequential build instead. Switch initialisation failed: clean up? ('n' will leave the switch partially installed) [Y/n] Y
特になぜとかは調べてないが、多分同様に詰まる人がいるかもしれないしまた詰まりそうなので自分用にメモを残します
ここではunlinkしているが、私の環境ではuninstallをしないと入らなかった。
github.com