発見があった取り組み: nand2tetris, データ指向アプリケーションデザイン + pingcap/talent-plan
ぼちぼちやってたやつです。
nand2tetris
コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方
- 作者:Noam Nisan,Shimon Schocken
- 発売日: 2015/03/25
- メディア: 単行本(ソフトカバー)
CPU 設計から OS 開発までやろうぜ、って内容です。以前書いたやつ。 rohki.hatenablog.com
一回挫折して次に書くやつに浮気しながらなんとか仕上げました。長かった...
割と大学時代に履修したことが多く「今でもできるよな、俺...」て再確認の意味が強かったです。
なので一回、10 章 LL パーザをかくところで挫折したときはガチで凹みました。「できなくなってるのか俺」て。
とはいえ頭冷やしてベタに書き直せば 2 日でできて安心した次第。良かった、ほんとに。
データ指向アプリケーションデザイン + pingcap/talent-plan
データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理
- 作者:Martin Kleppmann
- 発売日: 2019/07/18
- メディア: 単行本(ソフトカバー)
talent-plan/README.md at master · pingcap/talent-plan · GitHub
こっちの方が学びは多かったです。歴史の話とか、関係性の話とか、ネットワーク遅延の難しさとか CAP 定理の話とか。
意図してやったわけではなかったんですが、pingcap/talent-plan の TP 201: Practical Networked Applications in Rust.
時間をおかず始めて知識を実体験できたのがさらに良かったです。
途中で Stateless が Stateful になり、そのあと Multi-thread になる際に実装で軽く「ここ RWLock じゃあなくて Mutex にしたら」て思考した瞬間にスループットと整合性の話を実感したりしました。
テストコードがあるのがありがたかったです。通らねーなーなんだろう、てゴールがあるのは大学時代の実習を思い出しました。
次
オブジェクト指向入門した(つもり)
ほんまにたつんかーい
— rohki (@r_ohki) 2020年5月16日
しかし流し読みでもツラカッタ pic.twitter.com/eXVlp5QddN
モチベーション
買った時は オブジェクト指向 #とは
を源流を知りたくてかった、はずでした。
実際に届いたら厚さにビビったり、仕事でコード書く頻度が下がったりで長い間積読に。
最近本読めてねーなーから一念発起。最後の方は流し読みでもいいからまず読み切ろうって感じでした。
(咀嚼しきれてないけど) 感想ぽいもの
- separate てなんか Future ぽい
- 解決したい課題は同じで、非同期の箇所を型やなにがしらで明確化したいってところだろうか
- 拡張型と参照型の区別をしない言語ってどうやって対応するんだろ
- コンカレントエンジニアリングのクラスタって、境界付けられたコンテキストとかそういうのと似た印象
- 故、めっちゃ難しいとおもってる
- 継承なげーなーとおもうけど、長さに納得する内容。こんな自分の足を容易に撃てるもんつかってたのおれ?
- 過去のやらかしが脳裏をよぎる
- クラス不変表明勘違いしてた。んで、本に書かれてる定義にすげー納得できた
- 業務知識をどこに持たせるといいのだろう、は今後の研鑽
- 電子書籍版が欲しい。マジでほしい
- 体力的にも精神的にもきつい
- 検索機能とかこれなんだっけって目次ジャンプとか
- 今まで学んだこととか実践したこととかを想起しながら読めたりした
- Rust の Iterator trait とか
おわりに
たぶん要所要所でよみなおすんだろうなー
rusoto が async/.await 対応したのをきっかけにさわってみた雑感
タイムラインに ↓ が流れてきたのでこれはやらねば async/.await 対応 してみての雑感です。
rusoto 0.43.0-beta.1 is available now with async/.await support, please help test! 💜
— iliana destroyer of worlds 🏳️⚧️ (@ilianathewitch) 2020年2月7日
here's a blog post about the near-term future of rusoto https://t.co/fmZkbH7pys #rustlang
雑感
- 感触はよさげ。
.await?
でResult
型もむけたりする .await
忘れが罠臭い。コンパイルできるし起動できるがスルーされるOption::unwap_or_else
とかがちょっとつらそう? 回避はできるし、まだわかりきってない可能性ありStream
trait の実装はあきらめた。Pin
とかUnpin
とかPoll
をわかってないと分かったのでいつか再チャレンジ
Stream を crate でどうにかしてもらった
Stream の様変わりがすごくて再実装できず、結局↓を使った https://t.co/5omvcsbCe1
— rohki (@r_ohki) 2020年2月11日
Kinesis Stream って名前である以上どうしても Stream
にしたかったので、調べたら async-stream を見つけられました。
実際には以下のよう使いました。
pub fn stream(mut self) -> impl Stream<Item = Result<GetRecordsOutput, Error>> { try_stream! { loop { if let Some(current) = &self.token { let r = self.get_records(current).await?; self.token = r.next_shard_iterator.clone(); yield r; } else { let next = self.get_iterator_token().await?; self.token = Some(next); continue; } } } }
k-iter/kinesis.rs at 94c79facb6e2459eedf3ce85a40dab034007f129 · ROki1988/k-iter · GitHub
私がつかめてない Stream
と async/.await
の関係性のところにするっと入ってくれました。
個人的には前よりもすっきりした印象を持ってます。
つづく
まだ 0.43.0-beta.1
なので注視しつつ、折を見て master に merge してきます。
ここ最近コード書いてなくてさび付いてるかなーとおもったんすが、まだ何とかなってました。
何とかなるぐらい Rust のコンパイルエラーとか fmt とか clippy が優秀ってのもある。ありがたし。
Rust.tokyo に参加した
遅ればせながら感想を。*1
まずは、スタッフや登壇者のみなさん、本当にありがとうございました。
セッションや Networking Time で非常によい刺激を受けられました。
セッション一覧で Servo や TiKV by PingCAP が見られたので、努めてそちらを聞きに行きました。
英語で翻訳なしでしたがまぁそこは頑張ってみようと。
特に印象に残っている感想を以下で書いてきます。
Lifetimes: A Survival Guide
そうそう! とうなづいてました。
データがどう入れ子になってていって、いつまで活きてて、あこのデータは一人歩き出来なきゃだから Clone しようとか。
Rust に惹かれた lifetime や Ownership の考えが視覚化されててよかったです。
まとめの画像、よいすよなー。
The Hitchhiker’s Guide to Servo Contributor
Servo をいじってみたことがあったのでこちらに。
こちらも W3C の標準化の話やブラウザベンダーとの関連、実際のコントリビュートのやり取りなど、幅広くも実際にやられたことが書かれてて、すげーなーと感じ入っておりました。
個人的な挑戦として初めて英語で質問しました。何とか伝わってよかった。
ちゃんと聞きたいことが先にあってでしたよ。「Servo のフルビルド、結構待ち時間いるけど、ローカルでの開発どうしてます?」ってやつです。
でこれでしたw
Q. ローカルでServoビルドするの大変なんだけど A. わたしのマシンで40分かかった。でもChromiumビルドは1日かかった。Servoのビルドははやいよ! #rust_tokyo_b #rust_tokyo
— Satoshi Kojima (@skoji) 2019年10月26日
ww
真面目な回答としては、インクリメンタルビルドもしっかりしてるし、今はそれかな、だったはず。
Contributing to Rust
いーろいろ感じるものがありました。時差の話とか、一日のコントリビュートにかける時間の話とか。
ちゃんと咀嚼してからなんか書きたいです。
聞けて良かった内容でした。
Networking Time
かつてないぐらいしゃべってた気がします。うるさくてすいません。
Networking Time の意義にそった行動はとれてたかなー。よかたよかた。
おわりに
最近コード書く機会を捻出できてきてるので、さらーにモチベーションが得られました。
ゆるく、やってきます。
*1:風邪ひいて頭痛で倒れてでした。やっと回復
AWS Kinesis ひたすら読みにいく k-iter の複数 shard 対応(と、Rust の Future/Stream/Tokio 話)
AWS Kinesis Stream Subscriber USAGE: k-iter [FLAGS] [OPTIONS] --region <NAME> --stream-name <NAME> FLAGS: -h, --help Prints help information -V, --version Prints version information --verbose Enable verbose mode. OPTIONS: --data-format <TYPE> Set data output-format. [default: UTF8_STRING] [possible values: RAW_BYTES, RAW_STRING, UTF8_STRING] -t, --iterator-type <TYPE> Sets iterator type. [default: LATEST] [possible values: LATEST, AT_SEQUENCE_NUMBER, AFTER_SEQUENCE_NUMBER, AT_TIMESTAMP, TRIM_HORIZON] -r, --region <NAME> Sets a region name. [possible values: ap-northeast-1, ap-northeast-2, ap-south-1, ap- southeast-1, ap-southeast-2, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu- west-3, sa-east-1, us-east-1, us-east-2, us-west-1, us-west-2, us-gov-west-1, cn- north-1, cn-northwest-1] --sequence-number <NUM> Set Sequence number when Iterator Type is AT_SEQUENCE_NUMBER or AFTER_SEQUENCE_NUMBER. -s, --shard-id <ID1 ID2>... Set shard ids. If you don't set, iterate all shards -n, --stream-name <NAME> Sets a stream name. --timestamp <TIMESTAMP> Set timestamp(UNIX Epoch milliseconds) when Iterator Type is AT_TIMESTAMP.
-s, --shard-id
... Set shard ids. If you don't set, iterate all shards
でけたー。できましたよ。細々とやっとりました。
何も指定しなければ全 shard をにらみにいきますし、当然指定もできます。
複数の shard id も指定できます。あ、sequence-number も複数の方がいいかな? 確認大変そう。また今度にしよう。
つまったところ
futures::stream::Stream の実装
impl Stream for KinesisShardIterator { type Item = GetRecordsOutput; type Error = Error; fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> { if let Some(current) = &self.token { let r = GetRecordsInput { shard_iterator: current.clone(), ..Default::default() }; self.client .get_records(r) .map(|r| { self.token = r.next_shard_iterator.clone(); Async::Ready(Some(r)) }) .map_err(Into::into) .wait() } else { self.get_iterator_token() .map(|next| { self.token = Some(next); Async::NotReady }) .map_err(Into::into) } } }
このあたり ですな。
wait
じゃあなくて poll
つかって動かなかったり、map_or_else
つかって型が合わなかったり、Iterator だけでいいんじゃあ…とあきらめかけたり、いろいろやってました。
というか、wait
まわりはまだちゃんとわかってないです。動いたーで喜んで今書いてます。
Stream でかつ、Async::Ready(None)
を返さなければひたすら動き続ける(という理解な)ので、呼び出し先で こう 書けます。
let it = match iter_type { IteratorType::LATEST | IteratorType::TRIM_HORIZON => { KinesisShardIterator::new(na, ia, ta, ra) } IteratorType::AT_SEQUENCE_NUMBER | IteratorType::AFTER_SEQUENCE_NUMBER => { let seq = value_t_or_exit!(matches.value_of("sequence-number"), String); KinesisShardIterator::new_with_sequence_number(na, ia, ta, seq.as_str(), ra) } IteratorType::AT_TIMESTAMP => { let timestamp = value_t_or_exit!(matches.value_of("timestamp"), f64); KinesisShardIterator::new_with_timestamp(na, ia, ta, timestamp, ra) } }; tokio::spawn({ Interval::new_interval(Duration::from_millis(1000)) .map_err(|e| eprintln!("timer failed; err={:?}", e)) .zip(it.map_err(|e| eprintln!("subscribe error = err{:?}", e))) .map(|(_, r)| r) .forward( tx.clone() .sink_map_err(|e| eprintln!("send error = err{:?}", e)), ) .and_then(|_| Ok(())) }); }
Interval も Stream を実装しています。
zip
で KinesisShardIterator
と並べることで、1 秒ずつ Kinesis の record を確認しに行くようになりました。
0.5 秒とかにすると Rate Limit Exceed とかって出ました。知ってる。
tokio::sync::mpsc の取り扱い
これは動くようになったところを 1 段階目とすると、今は 3 段階目です。
最初は 1 record 毎に Sender を複製して send を呼んでいました。だせーと思いながら動かすために目をつむってかいたのが、1 段階目。
2 段階目は try_send が &mut self
なのに気づいて、毎度複製するよかましかーと書き換えたやつ。
3 段階目が、send_all とか forward をみて、mut なしでいけるのではと気付いて書き換えた今のやつです。
課題
Verbose mode での shard-id 表示
ほしくない?
ローカルでのテスト
いい加減 localstack つかったテストかけるようにしよう。これもこれで大変です。
しめ
あー、やっと一山超えれた気がする。もうちょっと。ツールの方に適用していって。
— rohki (@r_ohki) 2019年5月30日
適用できたぜい。なんちゃってでも Future と Stream、Tokio が扱えたのはでかいです。
もうちょっと待てば async/await を含んだ release がでます。けどいけそうっておもって書かずにはってかんじでした。
出たら書き直します。
Rust での Iterator 返し + from_fn + Self
自分が作りたいもののためにメモ。きっと忘れて見返す。
こんな書き方できるんですねー。 ちょっと前までコンパイルエラーで落ちてた記憶がうっすらとあります。
#[derive(Debug)] struct SpanIdentity { trace_id: String, span_id: String, } #[derive(Debug)] struct SpanContext<'a> { id: SpanIdentity, parent_span: Option<&'a Self>, } impl<'a> SpanContext<'a> { fn context_iter(&'a self) -> impl Iterator<Item = &'a SpanContext<'a>> { let mut acc = self; std::iter::from_fn(move ||{ let r = acc.parent_span; acc = r.unwrap_or(acc); r }) } } fn main() { let a_a = SpanContext{id: SpanIdentity {trace_id: "a".to_owned(), span_id:"a".to_owned(),}, parent_span: None}; let a_b = SpanContext{id: SpanIdentity {trace_id: "a".to_owned(), span_id:"b".to_owned(),}, parent_span: Some(&a_a)}; let a_c = SpanContext{id: SpanIdentity {trace_id: "a".to_owned(), span_id:"c".to_owned(),}, parent_span: Some(&a_b)}; for x in a_c.context_iter() { println!("{:?}", x); } }
OpenCensus meetup vol.1 に参加してきました!! #opencensusjp
参加してきました
https://opencensus.connpass.com/event/123885/
いやー面白かった。
自分が気になって見積もりに時間かけてるところがやっぱりネックになっていて、みんな気にしてるという同じ認識を持てたのもよかったです。
京都からきてよかった。
資料リンクだけ並べてるので、感想は後ほど。 -> 書いた!
なぜに京都から???
rohki.hatenablog.com
前に調べたり、Scala 関西で @grimrose さんの話きいたりしてました。僕にとって今一番面白いところだからです。
面白さの背景を書くと、Managed Service を使っていてメトリクスやログがとりやすくても追跡はひたすらしんどいってのを何度か味わってるからです。
ロードバランサーのエラーコードの発生個所や遅延の発生、HTTP のアクセスログ、アプリケーションログ、サーバーのリソース消化具合、DB のクエリの遅延やトランザクションの待ち、キャッシュのヒット率、Disk IO、Disk Queue、などなどなど。
AWS の Managed を使ってるとこの辺りは取れます。取れますが、これらを組み合わせてサービスを構築しているのは自分たちで、各メトリクス・ログの因果関係を追っていく必要があります。
僕は CloudWatch/Elaticsearch を使って追ってます。追っていますが、ひっっっっっっじょうに疲れるんです。
インフラ構成を脳裏に置きながら、みんなで仮説を立てて、関連するメトリクスを洗い出し、同じグラフに描画して、まず相関があるかを確認する。
これ繰り返すだけでお腹が一杯になってしまって、原因らしきものを特定したときにはすでにグロッキーなのです。
この特定までの負荷を安くして、一次対応とか根本対応どうするにもっと時間をかけたい、ってのがきっかけです。
本編
イベント主旨説明 / Opening / @ymotongpoo
資料 URL: https://bit.ly/20190403-oc-intro-update
アンケート見ながら、やっぱり StackDriver つよいなーという。場の問題? それはあり得るw
書きながら改めてみると Zipkin や Jaeger が少ないのも面白いです。やはりこの辺りを自前でやるのはつらいというこうとでしょうか。
運用の運用で奔走させられそうな雰囲気を感じます。
Session 1: OpenCensus Intro and Status Update / @ymotongpoo
資料 URL: https://bit.ly/20190403-oc-intro-update
会場の雰囲気としては、Service への期待が大きかった気がしてます。というか僕が期待してます。
Reverse Proxy や Service Mesh に tracing 機能もこちらによるか、ないしは連携できると色々はかどるのかなぁと思ったりしてます。
OpenTracing とのマージの話は後にも出てきますが、うん。ちょっとごまかそう。うん。
Session 2: OpenCensusを実際に使ってみて、便利なところと、困ってるところ / @sinmetal
資料 URL: https://docs.google.com/presentation/d/1J0fh9_C-Juhy1N3EB1G9PqR8NRWgwJjb0VCy7VfRbXI/
趣味のゲーム https://github.com/metal-tile
まさしく聞きたかったお話でした。Sampilng rate と追跡性のお話。
低すぎると取りこぼしがでて、高いと負荷とお値段があれで、じゃあ一時的に全取得ってやってみたら Buffer full で捨てられて…
特に最後かなぁ。全取得が難しいケースもあると分かったのはとても大きいです。この辺りは実装と設定によりそう。
Session 3: Distributed Tracing with OpenCensus at Wantedly / @munisystem
資料 URL: https://speakerdeck.com/munisystem/distributed-tracing-with-opencensus-at-wantedly-inc
Wantedly さんで投入されたお話。
これも聞きたかった話ですねー、Sampling rate とか性能問題とかAWS X-ray と比べてのところとか。
X-ray の導入で悩ましいのが、AWS 色が強すぎるところなんですよね。
OpenCensus の Partners & Contributors でも Google と Microsoft は入っていて AWS は入ってないというところがあります。
Library の話は強い!!という感想。場合によってはそういうこともありますよね。うーむ。
あと、バックエンドへの最適化が話に上がっていて、抽象度あげたいから OpenCensus を入れたけど痒いところに手が届かないという、バランスの難しさもわかりました。
ここでも OpenCensus Service の話題。期待たかいっすよね。
Session 4: OpenCensus Javaで始めるOpenCensus / @grimrose
資料 URL: https://docs.google.com/presentation/d/1i3LYjz26lz8WWuIqcwBpc8d0I-8_kTu7hnDWvdnOZEE/edit#slide=id.p
Java 実装 Android で動くんかい!! 元クライアントエンジニアとして確かに知りたいときはある。あるものの、どうやって送るんだそれ???
通信負荷考えると Sampling rate もっと考えなきゃ云々。
閑話休題
Java は Exporter のサポートが厚めですよね。対応状況も Beta ですし。
Spring Cloud は知らなかった…調べてみよう。
ちょいちょい Scala 実装の話があって個人的に非常にありがたいw
try with resource の話がちょっと盛り上がっていたかも? golang の defer の話が上がっていたからかもです。
LT1: JavaのCustom Exporterを書いてみた / Writing custom exporter for Java / @r_rudi
資料 URL: https://docs.google.com/presentation/d/e/2PACX-1vRMNdvFdqwHlyfgj8fAQA-sU391UooWegR2s87rpUD9RzOsPzxnycoH3LkZDt12v48kxmphq68qa-Y_/pub?start=false&loop=false&delayms=3000&slide=id.p
https://github.com/shirou/opencensus-exporter-trace-xray
Session 4 と関連が強い、ということで順番をいれかえて LT トップバッターへ。
そうそうこれこれ。X-ray との話。というか強い。
スライド 11 にある対応表とかめっちゃありがたいです。なるほどなぁ。
LT2: TracingとLoggingの連携 / Tracing and logging correlation / @ladicle
資料 URL: https://speakerdeck.com/ladicle/integration-with-tracing-and-logging
https://github.com/Ladicle/opencensus-and-jaeger
gopher くんの好みの話でざわっとなって途中から気になるところが変わってしまいましたw
そうか、ニンジンがすきで魚が嫌いなのか… デモもそれにそってやられてて思わず笑ってしまいました
それはさておき。
Tracing と Metrics と Logging の関係図よいすよね。この図を念頭に置いて設計してきたい
OpenTracing との話は、うん。
LT3: OpenCensus Stats で PaaS のメトリクスを補完する / Interpolate PaaS metrics with OpenCensus Stats / @apstdnb
資料 URL: https://docs.google.com/presentation/d/17E5TqNuq46_8B62beMOg_1bHY_jDVBTdmzSJYrqKLgs/edit
自己紹介が強すぎるw
当然ながら GCP は本家本元に近いので連携が強いですよね。資料も豊富だ。
悩ましい…
LT4 : Ruby実装についてひと言 / Ruby implementation / @kawasy
資料 URL: https://speakerdeck.com/kawasy/current-status-of-opencensus-ruby-number-opencensusjp
良かった。なぜかいまいちな Ruby 対応に関してひとことでした。お、Feature MatrixにRuby足されとるやん https://t.co/niNphzvgxe #opencensusjp
— progrhyme@技術書典6「か59」 (@progrhyme) 2019年4月4日
というより Erlang/Elixir の強さが何でそんなに強いのという。Beta にはいってますやん。
やっていく宣言はかっこいい!!
LT5 : ウェブフロントエンドからサーバーまでの一気通貫のトレーシングに挑戦してみる / Try consistent tracing from web frontend to backend servers / @shibukawa
資料 URL: https://docs.google.com/presentation/d/145vr-ouZFxlLub5dGyl3TkJmxqWqPMvmuZObUMgRzEg/edit
https://github.com/shibukawa/opencensus-sample
これもこれで面白いですやつ。僕個人の話でいうと、フロントエンド周りの知識がよわいんですよね。
確かにここきっかけでリクエストとか描画のタイミングが追えるようになるかも? 性能問題が出ないように気を付けながらですが。
Observablility は港区用語。港区用語とは…(関西在住 エンジニアの感想)
Real っては確かによい表現。その時の Real が知りたいのです。
おわりに
雰囲気よかったです。
なんとなくみんなの興味の根っこが同じでありつつ、いろんなアプローチがされていました。
vol. 2 も参加できるかな?