fnwiya's quine

自分自身を出力するブログ

node学園祭2016行ってきた

大きなConference系は久しぶり。
node界隈というかJS界隈は幅が広くて動きが活発でとても聴き応えがあった。
一番印象的だったので@t_wada氏のpower-assertへの依存をなくした話。
ロックインをなくしてtool化していく姿勢は本当に尊敬します。
サイボウズのKAIZENNはちょうど悩んでいたろころでぴったりだし、
気になっていたサーバサイドレンダリング、web-assemby周りも知れた、
何より最前線を走っている方々の熱量を感じられたのが良かったです。(after partyも豪華だった)

発表者・運営の方々に感謝です。
来年はLT立ちたいな。

以下メモ

Building Interactive npm Command Line Modules

@Irina Shestak

  • CLIのコマンドのオプションの意味わからなくないですか?という問題提起
  • CLIAppとは? プログラムと対話する
  • optionいっぱいよりinteractiveにするとUser friendly
  • https://github.com/yargs/yargs/ が引数の処理におすすめ
  • ↑default設定、ロングオプション、ショートオプション等の設定が楽
  • .help()でdescriptionがでる
  • catコマンド(猫の飼える数の表示)実装してみたよ(15分ぐらいでできたらしい)

Debugging Node.js Performance Issues in Production

@Thomas Watson

  • パフォーマンスモニタリング
  • 本番のパフォーマンス測定は難しい。影響を与えたくない。
  • premature optimization = 早すぎる最適化はよくない。
  • console.time('hoge'); hoge(); console.timeEnd('hone');で測定できる。
  • 遅くなる(Stop The World)原因:
    • single thread
    • CPU intensive code
    • Slow I/O
    • Event Loop saturation
    • Running out of memory
    • Garbage Collection
  • CPU Intensive Code
    • Sync I/O fs.*Sync
    • JSON parse
    • RegExp
    • Crypto
    • Templates

サイボウズの開発を支えるKAIZEN文化

@Teppei Sato http://www.slideshare.net/teppeis/kaizen-68803503

  • VP of Engineering
  • 技術的負債との戦い
    • あとで時間のあるときにやろう!=>そんな時こない
    • KAIZENN DAY(丸一日KAIZENNする日)。呼び方も変える
    • 1日で終わらない。非エンジニアの共感。割り込み業務 => 改善合宿(関係者に発表)
    • チーム横断なもの => 改善会議(スーパリセットしちゃお) http://pepabo-ceo.jugem.jp/?eid=40
  • 新規技術
  • リモートワーク
    • 採用戦略
    • QoL => ウルトラワーク(総労働時間の10%は好きなところで働いてよい制度)
    • 最初はつらさもあった(つながらない問題) => 全員がリモートワーカー。全員練習する CiscoのSystem
    • 質問責任と説明責任
    • すべての情報はオンラインに
    • 分報(ピープル)
  • 理想の共有/共感

The Seif Project

@Douglas Crockford

  • Upgrade Web => seif project
  • https://github.com/paypal/seifnode
  • https://github.com/paypal/seif-protocol
  • Full duplexなプロトコル
  • Seif resource management
  • Seif Apps
    • HTML-free Javascript-based application delivery build on NodeJS and Qt
    • Logic: Node, Display: Qtをjson-channnelでつなぐ。
  • Trust Management
  • Seif Helper App
  • Transion Plan
    • 一つのブラウザに組み込むよう説得する(Mozilla?MS?)
    • secureなサイトにユーザーにそのブラウザを使うようにしてもらう
    • penguinの原理でほかもついてくるようになる
    • 他のブラウザも対応するようになる
    • 既存のものと並行するとは思うが、新しいものはseifで作られるようになる

Why to Standardize your READMEs

@Richard Littauer

  • READMEはドキュメントより先に見る
  • npmには35万のパッケージがある

Vue.js 2.0 サーバサイドレンダリング

@Kazuya Kawaguchi https://speakerdeck.com/kazupon/vue-dot-js-2-dot-0-server-side-rendering

  • プログレッシブフレームワーク
  • コンパイル template => AST
  • VirtualDOM
    • diff算出コストがかかる => 二段階処理 = 静的なノードの検出 + 静的なノードツリーの検出
    • snabbdomベース
  • サーバーサイドレンダリング
    • レンダラ
      • renderToStream
    • ハイドレーション(水分補給)=>状態補給
    • コンテキスト
    • バンドリング
  • 参照透過性をたもったレンダリングを実装しましょう

React + Reduxを使った大規模商用サービスの開発

@Naohiro Yoshida

  • SSRしたあとはSPAとして動作pushStateをもちいたpjaxなアプリ
  • redux middleware: サーバーとクライアントの差分を吸収する
  • 失敗しないように注意するポイント
    • transition
      • onEnterではreplaceStateを使う。pushStateだめ
      • mountしてから分析ログを飛ばす
      • data fetchしてからRouterContexrのrenderをする
      • iPhone画面スワイプ問題(safariは回避策あり。chromeは無理)
    • webpack
      • 変更箇所意外のhashを変えずにブラウザキャッシュを最大限活用
      • めったに行かない画面のjsはgetComponentで動的に
    • partial renderingでもGoogle botに認識される。Fetch as Google

Introducing Now and Next.js

@nkzawa

The Evolution of Electron

@Cheng Zhao

  • Atomを作ったのがきっかけ
  • node-webkittは複数ウィンドウに対応していなかったのでforkしてatom-shellとして書き直し
  • node-webkitがまともに動かないとAtomが作れない」「じゃあ作者を雇おう」=> チェン=サンがgithubに雇われる
  • コントリビューターを惹き付けるために
    • issues, PRにはすぐに反応することが重要 -開発へのハードルを下げる

JavaScript による並列処理:共有メモリとロック

@Noritada Shimizu https://speakerdeck.com/chikoski/20161113-nodefest

  • Mozillaエヴァンジェリスト
  • メインスレッドという一つの時間軸の上で動いている
  • workerを使うとマルチスレッドが実現できる
  • メッセージ間のデータのやりとりではobjがコピーされる
  • ArrayBufferならポインタを移すだけなので効率的 => SharedArrayBifferならさらに共有可能
  • 食事する哲学者問題 => Atomics.wait
  • unityはHTMLを吐ける。
  • 1.5倍ぐらい早くなる?

WebAssemblyに欠けている大事なもの

@Yoshiki Shibukawa

  • C/C++: 言語自体はとても良くなっている
  • pkgマネージャーがない...rustはいいぞ
  • CMakeがデファクト
  • webassemblyはUIに絞っただけのほうがいいかもしれない

From Library to Tool - power-assert as a General Purpose Assertion Enhancement Tool

@Takuto Wada

  • Testing framework should evoleve slowly.
  • testコードはtestできない。書き直しは綱渡り
  • easy to write VS. easy to learn to write
  • No API is the best API
  • require('power-assert')ではなくrequire('assert')で動くようにした。power-assertに依存しない。From Library to Tool
  • assertはtestだけのためのものではない。契約プログラミングなど。unassertでproductionでもいける

How Do We Get Along With Static Types

@FUJI Goro https://speakerdeck.com/gfx/how-do-we-get-along-with-static-types

  • JSの資産を使うのが難しい
  • 型定義ファイルが無いとダメ
  • .d.tsを書けばできる。けどそれで生産性は上がってる?

RuntimeJS Playground

@Jacob Groundwater

http://runtimejs.org/ - OS等はすっ飛ばして直接ハードウェアを操作する。

haskellでバブルソート・マージソート・クイックソート

Haskellでソート3種実装してみました。
クイックソートのシンプルさが際立ちます。
これがパターンマッチの力。

バブルソート

bswap [x] = [x]
bswap (x:xs)
    | x > y     = y:x:ys
    | otherwise = x:y:ys
    where
        (y:ys) = bswap xs

bsort [] = []
bsort xs = y : bsort ys
    where
        (y:ys) = bswap xs

main = do
    print $ bsort [4, 3, 1, 5, 2, 7, 3]

マージソート

merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys)
    | x < y     = x : merge xs (y:ys)
    | otherwise = y : merge (x:xs) ys

msort []  = []
msort [x] = [x]
msort xs  = merge (msort (take h xs)) (msort (drop h xs))
    where
        h = (length xs) `div` 2

main = do
    print $ msort bsort [4, 3, 1, 5, 2, 7, 3]

クイックソート

qsort []     = []
qsort (n:xs) = qsort lt ++ [n] ++ qsort gteq
    where
        lt   = [x | x <- xs, x <  n]
        gteq = [x | x <- xs, x >= n]

main = do
    print $ qsort [4, 3, 1, 5, 2, 7, 3]

タイル型ウィンドウマネージャxmonad

現在ウィンドウマネージャにxmonadを使用しています。

メリットとしては

  • 動作がかなり軽くなる
  • ほとんどの動作がキーボードで完結するようになる
  • 設定がHaskellでかけるのでプログラマブルで移植性や再現性が高い
  • Haskellの勉強になる

マウスによるウィンドウの操作やパネルの重なりも設定によっては可能なのでかなり柔軟性は高いです。
万人にはおすすめできませんが、
ubuntuの余計なアニメーションや装飾に嫌気が差した方などにはおすすめです。

設定ファイルはこちら

dotfiles/xmonad.hs at master · fnwiya/dotfiles · GitHub

-------------------------------------------------------------------------------
--                  __  ____  __                       _                     --
--                  \ \/ /  \/  | ___  _ __   __ _  __| |                    --
--                   \  /| |\/| |/ _ \| '_ \ / _` |/ _` |                    --
--                   /  \| |  | | (_) | | | | (_| | (_| |                    --
--                  /_/\_\_|  |_|\___/|_| |_|\__,_|\__,_|                    --
--                                                                           --
-------------------------------------------------------------------------------
-- Import modules                                                           {{{
-------------------------------------------------------------------------------

import System.IO                       -- for xmobar
import qualified Data.Map as M
import Control.Monad (liftM2)          -- myManageHookShift

import XMonad
import qualified XMonad.StackSet as W

import XMonad.Actions.CycleWS
import XMonad.Actions.FloatKeys
import XMonad.Actions.WindowGo
import qualified XMonad.Actions.FlexibleResize as Flex -- flexible resize

import XMonad.Hooks.DynamicLog         -- for xmobar
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.ManageDocks        -- avoid xmobar area
import XMonad.Hooks.ManageHelpers

import XMonad.Layout
import XMonad.Layout.Gaps
import XMonad.Layout.NoBorders         -- In Full mode, border is no use
import XMonad.Layout.PerWorkspace      -- Configure layouts on a per-workspace
import XMonad.Layout.ResizableTile     -- Resizable Horizontal border
import XMonad.Layout.Simplest
import XMonad.Layout.SimplestFloat
import XMonad.Layout.Spacing           -- this makes smart space around windows
import XMonad.Layout.ToggleLayouts     -- Full window at any time
import XMonad.Layout.MultiToggle
import XMonad.Layout.MultiToggle.Instances
import XMonad.Layout.Fullscreen (fullscreenFull)
import XMonad.Layout.Named
import XMonad.Layout.MouseResizableTile

import XMonad.Util.EZConfig            -- removeKeys, additionalKeys
import XMonad.Util.Run
import XMonad.Util.Run(spawnPipe)      -- spawnPipe, hPutStrLn
import XMonad.Util.SpawnOnce
import XMonad.Util.WorkspaceCompare

import XMonad.Config.Desktop (desktopLayoutModifiers)

--------------------------------------------------------------------------- }}}
-- vars                                                                     {{{
-------------------------------------------------------------------------------

modm = mod4Mask  -- Super
myWorkspaces = ["1", "2", "3", "4", "5", "6"]
myFloatWorkspace = "3"
myTerminal   = "gnome-terminal"
--myTerminal   = "urxvt"

-- Color Setting
colorBlue      = "#77A0D4"
colorGreen     = "#519CA5"
colorRed       = "#E15F67"
colorGray      = "#6E7E93"
colorWhite     = "#FDFDFE"
colorNormalbg  = "#333134"
colorfg        = "#D0CDD9"

-- Border width
borderwidth = 1

-- Border color
mynormalBorderColor  = colorGray
myfocusedBorderColor = colorRed

-- gapwidth
gapwidth  = 3
gwU = 0
gwD = 0
gwL = 0
gwR = 0

--------------------------------------------------------------------------- }}}
-- main                                                                     {{{
-------------------------------------------------------------------------------

main = do
    wsbar <- spawnPipe myWsBar
    xmonad $ ewmh defaultConfig
       {
         modMask            = modm
       , terminal           = myTerminal
       , workspaces         = myWorkspaces
       , borderWidth        = borderwidth
       , normalBorderColor  = mynormalBorderColor
       , focusedBorderColor = myfocusedBorderColor
       , mouseBindings      = myMouseBindings
       , startupHook        = myStartupHook
       , manageHook         = myManageHookShift <+>
                              myManageHookFloat <+>
                              manageDocks
       , layoutHook         = avoidStruts $ (
                                toggleLayouts (noBorders Full)
                                -- $ onWorkspace myFloatWorkspace simplestFloat
                                $ myLayout
                              )
       , logHook            = myLogHook wsbar
       }

       -------------------------------------------------------------------- }}}
       -- Keymap:                                                           {{{
       ------------------------------------------------------------------------
       -- xprop | grep WM_CLASS

        `additionalKeys`
        [
          ((modm, xK_e), runOrRaise "emacs" (className =? "Emacs"))
        , ((modm, xK_s), runOrRaise "gnome-terminal" (className =? "Gnome-terminal"))
        , ((modm, xK_c), runOrRaise "google-chrome" (className =? "google-chrome"))
        , ((modm, xK_t), runOrRaise "thg" (className =? "thg"))
        , ((modm,  xK_f),  sendMessage (XMonad.Layout.MultiToggle.Toggle FULL))
        ]
        `additionalKeysP`
        [
        -- ("M-l", moveTo Next NonEmptyWS)
        -- , ("M-h", moveTo Prev NonEmptyWS)
        -- , ("M-S-h", shiftTo Prev EmptyWS)
        ]
--------------------------------------------------------------------------- }}}
-- myMousebindings:          Bind mouse                                     {{{
-------------------------------------------------------------------------------
myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $
    [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w >> windows W.shiftMaster)) -- set the window to floating mode and move by dragging
    , ((modMask, button2), (\w -> focus w >> windows W.shiftMaster)) -- raise the window to the top of the stack
    , ((modMask, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) -- set the window to floating mode and resize by dragging
    ]
--------------------------------------------------------------------------- }}}
-- myLayout:          Handle Window behaveior                               {{{
-------------------------------------------------------------------------------

myLayout = spacing gapwidth $ gaps [(U, gwU),(D, gwD),(L, gwL),(R, gwR)]
  $ (ResizableTall 1 (1/55) (1/2) [])
  -- ||| mouseResizableTile { draggerType = FixedDragger { gapWidth = 0, draggerWidth = 2 }}
  ||| Simplest

--------------------------------------------------------------------------- }}}
-- myStartupHook:     Start up applications                                 {{{
-------------------------------------------------------------------------------

myStartupHook = do
        spawnOnce "gnome-settings-daemon"
        spawnOnce "gnome-volume-control-applet"
        spawnOnce "unity-settings-daemon"
        spawnOnce "xscreensaver -no-splash"
        spawnOnce "$HOME/.dropbox-dist/dropboxd"
        spawnOnce "stalonetray"
        spawnOnce "xmodmap $HOME/.Xmodmap"

--------------------------------------------------------------------------- }}}
-- myManageHookShift: some window must created there                        {{{
-------------------------------------------------------------------------------

myManageHookShift = composeAll
            -- if you want to know className, type "$ xprop|grep CLASS" on shell
            [ className =? "Thg"           --> mydoShift "5"
            , className =? "Emacs"         --> mydoShift "2"
            ]
             where mydoShift = doF . liftM2 (.) W.greedyView W.shift

--------------------------------------------------------------------------- }}}
-- myManageHookFloat: new window will created in Float mode                 {{{
-------------------------------------------------------------------------------

myManageHookFloat = composeAll
    [ className =? "Gimp"             --> doFloat
    , className =? "Shutter"          --> doFloat
    , className =? "Nautilus"         --> doFloat
    , isFullscreen                    --> doFullFloat
    ]

--------------------------------------------------------------------------- }}}
-- myLogHook:         loghock settings                                      {{{
-------------------------------------------------------------------------------

myLogHook h = dynamicLogWithPP $ wsPP {
  ppOutput = hPutStrLn h
  }

--------------------------------------------------------------------------- }}}
-- myWsBar:           xmobar setting                                        {{{
-------------------------------------------------------------------------------

myWsBar = "xmobar $HOME/.xmonad/xmobar.hs"

wsPP = xmobarPP { ppOrder           = \(ws:l:t:_)  -> [ws,t]
                , ppCurrent         = xmobarColor colorGreen colorNormalbg . \s -> "●"
                , ppUrgent          = xmobarColor colorfg    colorNormalbg . \s -> "●"
                , ppVisible         = xmobarColor colorGreen colorNormalbg . \s -> "⦿"
                , ppHidden          = xmobarColor colorfg    colorNormalbg . \s -> "●"
                , ppHiddenNoWindows = xmobarColor colorfg    colorNormalbg . \s -> "○"
                , ppTitle           = xmobarColor colorGreen colorNormalbg
                , ppOutput          = putStrLn
                , ppWsSep           = " "
                , ppSep             = "  "
                }

--------------------------------------------------------------------------- }}}

dotfiles/xmobar.hs at master · fnwiya/dotfiles · GitHub

Config {
         font = "xft:Sans-9:bold"
       , bgColor = "#333134"
       , fgColor = "#D0CDD9"
       , border = NoBorder
       , borderColor = "#D0CDD9"
       , position = TopW L 100
       , lowerOnStart = False
       , commands = [
                      Run Cpu [
                        "-L","3"
                        ,"-H","50"
                        ,"--normal","green"
                        ,"--high","red"
                        ] 10
                    , Run Memory [
                        "-t","Mem: <usedratio>%"
                        ] 10
                    , Run Swap [
                        ] 10
                    , Run Date "%a %b %_d %Y %H:%M:%S" "date" 10
                    , Run Battery [
                        "-t", " <acstatus> "
                        ,"-L", "20"
                        ,"-H","80"
                        ,"--low","#f44336"
                        ,"--normal","#ffffff"
                        ,"--",
                          "-o","<left>%(<timeleft>)"
                          ,"-O","Charging<left>%"
                          ,"-i","<left>%"
                        ] 50
                    , Run StdinReader
                    ]
       , sepChar = "%"
       , alignSep = "}{"
       , template = "%cpu% | %memory% | %swap% } %StdinReader% { %battery% | %date% "
       }

feedlyでqiitaとmediumの特定のタグだけ購読する

情報収集の手段としてキュレーションメディアの盛り上がりがすごい中ですが、
網羅性という意味ではまだまだRSSも負けていません。

しかしRSS人気記事などの括りで購読するとノイズが多いため、
自分はタグを指定してフィルタリングしています。

はてなやstack over flowでも同様にタグでフィルタリングできるようですが、
日本語と英語それぞれのソースとして今のところこの2つが十分でボリューム的にもちょうどいいところに落ち着いています。

高速grep the_silver_searcher

コードにコメントとして残した「TODO」や「FIXME」などを後から探すときに

grep -rn TODO

などどコマンドを打つことがあるかと思いますが、
いかんせんgrep -rは遅いです。

その遅さを解消したのがthe_silver_searcherです。

github.com

osxならインストールは

brew install the_silver_searcher

でできます。

使い方はgrep -rnをそのまま置き換えて、

ag TODO

とするだけです。

体感として数十倍は早くなるのでgrepとはおさらばしてagを使いましょう。

Ansible MeetUp簡易レポート

詳細レポはきっとどなたかが上げてくださると思うので早さ重視で。
全体として「明日から使える」感もあり夢も持てる素晴らしい会でした。
運営及び発表者のみなさんありがとうございます!

大きく話は2つ
1.Ansible2の話
2.Ansibleのツラいところをどうするか

1.Ansible2の話

  • 拡張性がかなり高まった
    DockerやOpenStackのモジュールも整備された。みんな色々作ってね。
  • withが便利
    OSの判定などをwhenでしなくてOK
  • sudoとかもう使わなくてOK
    どうやるかは聞き取れませんでした(英語)
  • エラーメッセージがわかりやすくなりました
  • 暗号化されたファイルの復元はAnsible-Vaultを使う。
    そのままだと遅いので高速化のためのツールをいれる。

今後はwinへの対応やnetwork部分まで含めて構成管理できるように進化していく予定(3~4ヶ月に一度リリースする)

2.Ansibleのツラいところをどうするか

  • Ansibleで全部やろうとすると無理がある
    →全部やろうとしなくていい。スクリプトなどと組み合わせる。
  • 秘伝のタレ化する
    →ドキュメントが大事
    1.ドキュメント上でAnsibleを実行する(Jupyterとの組み合わせ)
    2.Ansibleのplaybookからドキュメントを生成する(目下製作中。mdファイルにしてくれるっぽい)

シェル・端末・ターミナル・コマンドラインの違い

「新しいLinuxの教科書」を勉強していて
シェル・端末・ターミナルの違いが解説されていたので改めて。

標準出力を文字として表示したり、キーボード入力を取得したりするのが ターミナル(エミュレータ) 主にターミナルを介してコマンドを打ち込んでプログラムを実行するのが Unixシェル ターミナルにコマンドを打ち込む行が コマンドライン (そのまんま) Unix系OSでのターミナルエミュレータは 擬似端末 を通じてシェルとやりとりする

qiita.com