Blogaomu

WEBアプリケーション開発とその周辺のメモをゆるふわに書いていきます。

プロフィールページを整えた

ひそかに自分のプロフィールページを用意しているのですが、2013年に雑に作ったまま魔放置していて味気ない感じになっていたので多少整備することにしました。

https://takayukiatkwsk.github.io

Pure

purecss.io

Yahooが公開しているPureというCSSライブラリがあって、レスポンシブなレイアウトを構成するのに必要なものが最低限用意されています。また、ファイルサイズの小ささ(公式によると3.7KB)というのが特徴です。1〜2年前から良さげと思って注目していながら使えずにいたのですが、2016年末にようやく使う機会が訪れました。

グリッド

まずグリッドを使ってレイアウトを整えました。手軽にグリッド使えるのいいですね。グリッド用のクラス pure-g とユニット(グリッド内の個々のコンテンツを格納するもの)用のクラス pure-u-* が用意されています。ユニットの幅は pure-u-** で指定することができて、 pure-u-1-2 であれば全体の1/2、pure-u-3-5 ならば3/5という風な命名規則となっていて分かりやすいです。

また、レスポンシブにすることも可能で、grids-responsive-min.css を追加で読み込みメディアクエリ用のクラスを指定します。下の例で言うと pure-u-md-2-5 というのが横幅 768px 以上のときに適用されてグリッド内で2/5の幅を使います。横幅が768pxより小さい場合は pure-u-1 が適用されてグリッド全体を占めるように表示されます。md の他にも幅を表すキーが用意されているのでメディアによって柔軟な表現をすることもできそうです。

以下にAbout meセクションのhtmlを挙げました。PCなんかで見た場合アイコン画像と文章が横並びで表示されますが、スマホから見た場合は縦並びで表示されます。

<div class="pure-g">
  <div class="pure-u-1 pure-u-md-2-5">
    <div class="inner-box">
      <img src="images/icon2.png" class="pure-img icon">
    </div>
  </div>
  <div class="pure-u-1 pure-u-md-3-5">
    <div class="inner-box">
      <p>TAKAyukiatkwsk(たかゆきあっとかわさき)です。にぼしという名前でも活動しています。</p>
      <p>1984年生まれ、金沢出身、東京在住のち金沢に戻ってきました。Webプログラマ、Scalaを主に使っています。Infrastructure as Code/数学が気になってます。</p>
      <p>ビール好き、猫を眺めていたい。フロンターレとツエーゲンとベガルタレディースを主に応援しています。</p>
    </div>
  </div>
</div>

Pureのグリッドシステムについて詳しくはこちらを参照してください。 purecss.io

メニュー

外部リンクのリストをどうしようかと思っていたのですが、Pureでメニューモジュールが用意されていたので使ってみることにしました。メニューが適切なのか?という話はあるかもしれませんが、使ってみたかったんや!ということで。pure-menu pure-menu-list pure-menu-item pure-menu-link というメニュー用のクラスが用意されています。これらのクラスを外側からよしなに指定してあげるとメニューができあがります。以下例です。menu-width クラスは自分で用意したもので、display: inline-block をひもづけています。メニューの幅をli要素内の文字列の幅に抑えるために指定しています。

<div class="pure-menu menu-width">
  <ul class="pure-menu-list">
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://blogaomu21.blog91.fc2.com">Old blog</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="https://twitter.com/TAKAyuki_atkwsk">Twitter (@TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="https://github.com/TAKAyukiatkwsk">GitHub (@TAKAyukiatkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://qiita.com/TAKAyuki_atkwsk">Qiita (TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://b.hatena.ne.jp/TAKAyuki_atkwsk/">はてなブックマーク (TAKAyuki_atkwsk)</a></li>
    <li class="pure-menu-item"><a class="pure-menu-link" href="http://amzn.asia/ewqSBdx">ほしい物リスト</a></li>
  </ul>
</div>

Pureのメニューについて詳しくはこちらを参照してください。 purecss.io

終わりに

今回はPureを使ってプロフィールページの表示を整えました。お手軽にグリッドを使いたいならばBootstrapよりもいいなあという気持ちです。修正前のページで計測するのを忘れていたので比較できないのですが、モバイルフレンドリーになっていました。 f:id:TAKAyuki_atkwsk:20161224140137p:plain

kanazawa.rb meetup #52 に参加しました #kzrb

早いもので今年最後のkanazawa.rbです。今回は締めくくりとしてLT大会が行われました。

Meetup #52 - Kanazawarb

お試し Bitbucket Pipelines

docs.google.com

今年の夏ぐらい(?)からBitbucket内でCIサービスが使えるようになりました。ビルド環境がDockerコンテナというのも今っぽいです。Bitbucket上でポチポチ触ってたらビルドが始まるのはグッとくるものがありますね。LT内でBitbucket上からPipelinesを有効にして最初のビルドを行うというデモをしたのですが、おおっという反応がありました。

最近のお仕事でBitbucket Pipelinesを使ってCI環境を整えるというものがあって、ここ1ヶ月ぐらいで初めて知っていろいろ調査していました。もう少し突っ込んだ話は別途ブログで書けたらなあと思ってます。

全体的な感想

12月ということもあって今年を振り返るLTが多かったですね。どの話も、私はこう思ったとかこういう気持ちになったとかいう主観が現れていて、聞いていて面白かったです。昨今のコピペ記事だったりエアインタビューあるいはコタツ記事だったりそういったものが蔓延っている風潮で辟易していたわけですが、自分で手を動かして体験してそれを噛み砕いて伝えるというのは、受け取り側としてはリアリティがあって面白みとか感じ方とか増幅するような感じがあります。そういうお話がおよそ20本あってこれはもう最高だな、と思ったのでした。私もそんなコンテンツを出し続けていきたいです。

その雰囲気を作っていた会場のDMM.com Labo 南町オフィス、いい環境でした。4枚分のディスプレイ(何インチになるのかな)で遠くからでも見やすいし、オープンスペースも広くて快適です。ここで仕事したーいと言ってた人も何人かいましたw

あとピザよいですね。ドミノピザのGPS DRIVER TRACKERという配達状況をGoogleMapにマッピングして可視化してくれるサービスがあって、これをピザが来るまでスクリーンに映してみんなで待ってたのはエンターテイメント性あって面白かったです。

kzrb でピザ祭り

来年もよろしくお願いします。

kanazawa.rb meetup #51 に参加しました #kzrb

Meetup #51 - Kanazawarb

kzrb.doorkeeper.jp

今回は参加者が多く(初参加の方もいた)、バックグラウンドも様々な人たちが集まっていました。基板持ってきて光や音を出したり、RubyやGoやElectron触ってたり、勉強してたりなど全体的に幅広いジャンルでもくもくしていました。 そんな中私はお仕事してたんですが(汗)諸々のパッケージをインストールする必要があったため社内共有用の手順をまとめる作業をしていました。

LTもいくつかあって、雑にまとめるとこんな感じ。

vim-adventures.com

RPG形式でVimの操作方法を学べるやつ。

gadget.renesas.com

mrubyでLチカや温度センサーの値を読むデモを行ってました。雑にばーっとコード書いて物理的なものが動くっていうのは取っ掛かりとしてはいいなあと思った。

github.com

yamlで書いたタスクリストを読み込んでGitHub Issueにしてくれるツール。それとともに勉強会等のイベントにおけるタスクの共有(フォークできると便利そう)だったり、運営の敷居を下げたいという気持ちの話が印象的だった。

k.swd.cc

上記のVim Adventuresに対抗して(?)、Gitのブランチについて学べるやつ。

yhatt.github.io

Markdown記法でスライドを作れるデスクトップアプリケーション。Electron製らしい。

次回はLT大会ですってよ!!なにしゃべろうかな( 'ω')

fluentd の filter_record_transformer プラグイン便利っぽい

fluentd使っていて、入力データの特定フィールドの値をごにょごにょして出力したい(次の工程に渡したい)っていう需要がありました。それでどうやるんだろうとググっていたら filter_record_transformer というプラグインが使えそうだ、ということで使ってみました。fluentdバージョンは 0.12.x です。

record_transformer Filter Plugin | Fluentd

fluentd に内包されているのでプラグインのインストールは必要ありません😄

書き方はこのようになります。 <record> ディレクティブの中にフィールド名とその値を書きます。NEW_FIELD と言っていますが、入力に同名のフィールドがあればその値が NEW_VALUE にマップされる動作になっています。

<filter foo.bar>
  @type record_transformer
  <record>
    NEW_FIELD NEW_VALUE
  </record>
</filter>

また enable_ruby というオプションを有効にすると Ruby 式の評価結果を値にできるようです。計算処理や文字列操作なんかで使えそうな感じですね。便利。

自分のやりたかったこととしては、以下のように値に含まれる特定の文字列を取り除きたかったので、 gsub メソッドを使いました。

<filter foo.bar>
  @type record_transformer
  enable_ruby
  <record>
    hoge ${record["hoge"].gsub("P-", "")}
  </record>
</filter>
{"hoge":"P-1234A567890"}

このような入力があると、出力は以下になります。map関数を適用した感じになって便利だなあと思ったのでした。

{"hoge":"1234A567890"}

Akka Streams ドキュメントを何回かに分けてちらちら見てみる(2)

Akka Streams ドキュメントを何回かに分けてちらちら見てみる(1)の続き。

バックプレッシャー

Back-pressure explained

  • Akka Streamsの利用者はバックプレッシャーをハンドリングするコードを書く必要がない。
    • ライブラリ側でいい感じに処理してくれる
  • 下流のSubscriberが受け取ることのできるそしてバッファすることのできる要素数(demand)という観点でバックプレッシャープロトコルが定義されている。
  • データソース(Reactive StrteamsではPublisher, Akka StreamsではSource)は与えられるどのSubscriberのdemandの総数よりも多くの要素を出さないことを保証する。

遅いPublisher、速いSubscriber

  • このケースではPublisherを遅くする必要がない。
    • たしかにもともと下流の方が要素をより多く受け取れるので詰まることがなく調整しなくてよい。
  • しかし、signaling rates(?)はめったに一定ではないし、任意の時点で変わりうる、最終的にはSubscriberがPublisherよりも遅い状況に至る。
    • リソースの状況によってはPublisher, Subscriberの処理速度が変わるということを言ってるのだろうか?
  • これらの状況から保護するためにバックプレッシャープロトコルは有効なままにしておく必要がある。でもこれを有効のままにしておくことによる影響を受けたくはない。
  • Reactive Streamsプロトコルは、SubscriberからPublisherに Request(n:Long) *1の信号を非同期に送ることでこの問題を解決している。
  • このプロトコルは、送られてきたdemandよりも多い要素をPublisherが送らないことを保証している。

速いPublisher、遅いSubscriber

  • Publisherをバックプレッシャーするのが必須なケースである。
  • Publisherは以下の戦略の一つを適用してバックプレッシャーに従う必要がある。
    • 生成速度をコントロールできるならば、要素を生成しない
    • より多くのdemandが通知されるまで、bounded(?)な方法で要素をバッファリングする
    • より多くのdemandが通知されるまで、要素を使わない(破棄する?)
    • 上記の戦略を適用できない場合、ストリームを取り壊す

Stream Materialization

Stream Materialization

  • MaterializationはAkka Streamsにおいてはアクターの起動、ファイルオープン、ソケット接続などを意味する。
    • 必要なリソースに依存した処理を行う。
  • run()runWith()runForeach(el => ...) というメソッドでmaterializationが始まる。
    • runForeach(el => ...)runWith(Sink.foreach(el => ...))シンタックスシュガーである
  • Materializationはmaterializeしているスレッド(?)で同期的に行われる。
  • ストリーム処理はmaterializationの間に起動したアクターによって扱われる。
    • これらアクターは ActorMaterializer の作成時に MaterializationSettings でセットされるディスパッチャーで設定されたスレッドプールを使う。
    • 今までの例だと ActorMaterializer() で特に設定を渡していないのでデフォルトのディスパッチャーが使われている。

Operator Fusion

  • Fusing
  • asyncBoundary
  • ストリーム処理のステージを融合して、同期的に計算する方が早い場合は効率化できるっていうイメージなのか?

Combining materialized values

  • materializeされた値の合成
    • run したあと(materializeしたあと)に得られる値を RunnableGraph生成時に指定できる
  • Keep.right Keep.both
  • materializeされた値をmapできる
  • GraphDSL という便利DSLが使える

GraphDSLの例(抜粋)。

// An source that can be signalled explicitly from the outside
val source: Source[Int, Promise[Option[Int]]] = Source.maybe[Int]
 
// A flow that internally throttles elements to 1/second, and returns a Cancellable
// which can be used to shut down the stream
val flow: Flow[Int, Int, Cancellable] = throttler
 
// A sink that returns the first element of a stream in the returned Future
val sink: Sink[Int, Future[Int]] = Sink.head[Int]

// The result of r11 can be also achieved by using the Graph API
val r12: RunnableGraph[(Promise[Option[Int]], Cancellable, Future[Int])] =
  RunnableGraph.fromGraph(GraphDSL.create(source, flow, sink)((_, _, _)) { implicit builder => (src, f, dst) =>
    import GraphDSL.Implicits._
    src ~> f ~> dst
    ClosedShape
  })

Stream ordering

  • Akka Streamsではほぼ全ての計算ステージで要素の入力順序を保持する
  • mapAsync のような非同期操作でもこれは維持される(mapAsyncUnorderdという順序を保証しない版のメソッドもある)
  • ただ、複数の入力を扱うもの(Mergeなど)では出力順は定義されていない。
  • Zip では出力順は保証されている。
  • ファン・インの場合に出力順をコントロールしたい場合は、 MergePreferred または GraphStage を使う

所感

  • バックプレッシャーをライブラリ側でいい感じにやってくれるのは非常にありがたい
  • boudaryの概念がまだつかめていない。
    • 文字通り境界を表すのだろうけども...

*1:ドキュメントでは引数の型がIntになっているがソースコードではLongになっている https://github.com/akka/akka/blob/v2.4.10/akka-stream/src/main/scala/akka/stream/actor/ActorPublisher.scala#L48

Akka Streams ドキュメントを何回かに分けてちらちら見てみる(1)

最近、業務でAkka Streamsを使った処理に触れることがあって、詳しく知りたいなあと思ったのでドキュメントを読みながら触ってみようと思う。 一度には読み切れないのでいい感じに区切りながら進めていきたい。

Basics and working with Flows — Akka Documentation

主要なコンセプト

Core concepts

用語が定義されてるので雑に訳してみる。

  • Stream
    • データの移動、変形を含むアクティブなプロセス
  • Element
    • ストリームの処理単位。すべての処理は要素を変形して上流から下流に流す。
    • Buffer sizeのくだりはよく分からず...
  • Back-pressure
    • フロー制御の手段
    • コンシューマーが可用性についてプロデューサーに通知する方法
    • 消費のスピードに一致するように上流のデータ生産を遅らせる
    • Akka streamの文脈ではノンブロッキング・非同期として理解される(謎)
  • Non-Blocking
    • ある操作が完了まで長い時間がかかっても呼び出し元のスレッドの進行を妨げない、ということ
  • Graph
    • ストリームが実行されているときに要素が流れるべき経路を定義する
    • ストリーム処理topologyとは...
  • Processing Stage
    • グラフを構築するブロックの共通する一般名称(?)
    • 例: map, filter, カスタムGraphStage, MergeやBloadcastのようなグラフ接続

ストリームの定義と実行

Defining and running streams の項を見て基礎的なところを押さえておく。

Source, Flow, Sink という各段階があって、Sourceは1つの出力、Flowは1つの入出力、Sinkは1つの入力を持ってる。 これらSourceSinkFlowの前後に付けたものをRunnableGraphと言っている。 データが上流から途中で処理を通りながら下流まで流れていくというイメージだろうか。

サンプルコードを実行しようと思うとimport文など足りないので補足しています。

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Keep, RunnableGraph, Sink, Source}

import scala.concurrent.Future

implicit val system = ActorSystem("basic")
implicit val materializer = ActorMaterializer()

val source = Source(1 to 10)
val sink = Sink.fold[Int, Int](0)(_ + _)
 
// connect the Source to the Sink, obtaining a RunnableGraph
val runnable: RunnableGraph[Future[Int]] = source.toMat(sink)(Keep.right)
 
// materialize the flow and get the value of the FoldSink
val sum: Future[Int] = runnable.run()

解説によると、SourceとSinkを接続してRunnableGraphを作成したあとでもmaterializedするまではデータは流れないとのこと。 ふむふむ。上記のコードでいうと source.toMat(sink)(Keep.right) するとパイプラインはできたけどデータの放流はまだっすよ、というイメージだろうか。 run() することでmaterializeされ実行結果(Future[Int]型の値)が得られる。 Materializeは、グラフで表した計算を実行するのに必要なすべてのリソースを割り当てるプロセスと解説しています。なるほど。

source.toMat(sink)(Keep.right) でmaterializeした値しかもSinkの値だけほしい(Keep.right)と表しています。しかし、Sourceをmaterializeした値が欲しい場面ってどんなときなんだろうか? 上記の例は runWith() で置き換えられて source.runWith(sink) とかけます。

複数回materializeできて、それぞれで計算される。結果としては異なる値となる。 (実際に例のコード実行するとFuture[Int]型の値が返ってきて別のhashcodeを持っている。valueは55で等しい)

Defining sources, sinks and flows

SourceやSinkのさまざまな定義方法や、これらをつなぎ合わせる方法がいくつかあるようです。 こういうふうに役割が別れてることでパーツ化できてうれしいんだろうなという気がする。

Illegal stream elements

あとは要素として null を渡すことが許可されてないというのはおもしろい。普段Scalaで実装していて null を使うことは極力避けてる(Option型使うなど)ので当たり前な感じもするが大事なことなのであろう。

雑感

半分くらいの理解だけど、こんなもんかーと思って進めていきたい。 今回のサンプルコードだとあんまり良さがわからないけど、バックプレッシャーというのがきっといいんだろうなという気がする。

kanazawa.rb meetup #48 に参加しました #kzrb

金沢に戻ってきてかねてから行ってみたかったkanazawa.rbに参加してきました。

kanazawa.rb meetup #48 - kanazawa.rb | Doorkeeper Meetup #48 - Kanazawarb

この回は「祝4周年LT大会」ということで、参加者は1人1本以上LTを発表するという縛りがありました。私は初参加だったので自己紹介も兼ねて2本発表しました。

『長めの自己紹介』

Rubyとの関わりや影響を受けたShibuya.rbの紹介、最近の興味などについて話しました。順番としてはまずこれを発表して次にリモートワークの話ができればスムーズだったのですが、shuffleの結果自己紹介LTが後になってしまいましたw 他のコミュニティに参加する機会はそれほど多くないと思うので、Shibuya.rbの話はみなさん興味を持ってくれた印象がありました。

『リモートワーク1ヶ月経った』

もう一本はリモートワークについて1ヶ月やってみた感想を話しました。会社や組織によってもリモートワークの形態や考え方は異なると思うので、あまり一般的な話というよりかは個人の感想として話しました。意識してやってることのチャットに現れたりWIPでもPRを出すっていうのは、リモートでも「いる感」を出すっていうのに繋がってるのかなと思いました。

また、会議のくだりはいい感じに集音できるマイクだったり安定した回線が必要だろうなあと思っています。教育については私一人ではどうにもならないっていうところはあるんで組織全体でどうしていくのか考えないといけないなと資料を作ってて思いました。オンライン上でうまくやる方法を見つけるのか、一定の期間人のいるところで力をつけてリモートなり実践に送り込むのか、方法はいろいろあると思うんで何か最適なものを見つけられたら良いです。

あとはオフィスで常勤しているメンバーとリモートワークしてるメンバーがN:1の関係性になるので、もう少しリモートワークするメンバーが増えてくるとチームの考え方も変わるのかなあとうっすら思いました。

その他感想

今回初めて Google slides でスライドの作成からそのまま公開までやってみたんですが、なかなか便利でした。Webブラウザがあればどの端末でも編集できるし、公開するのもボタンポチッとすればいいだけ(アップロードしないので即公開できる)なんで楽ちんですね。SlideShareやSpeakerDeckのように、特定のユーザーのスライドリストみたいのはなさそう(用途がちがう)なんで、その辺はどうするのがいいか悩ましいところはありますね。

LT祭りということで他の人のLTもたくさん聞いたわけですが、皆さんそれぞれ興味のある分野が異なってて面白かったです。参加者だったりコミュニティのベースにあるものとしてはRubyなんだと思いますが。それだけに捕らわれないところも良いなあと思いました。

4周年ということでkanazawa.rb手ぬぐいを頂きました!

#kzrb 手ぬぐいもろた

まだ余っていそうだったので、次回のmeetupに来たらもしかしたら貰えるのでは?(宣伝)次回は9/11日曜日開催とのことです。

懇親会

火鍋でした。ひたすら肉食べてた気がするw

火鍋ー