0
長いの  @emasaka
自己紹介●   @emasaka●   本名:高橋正和●   40代 フリーター●   ブログ    「本を読む」http://emasaka.blog65.fc2.com/●   ja.wikipedia.orgで「Locator/Ident...
twitterでオヤジギャグを流す人           ※それはシュレーディンガーです
Twitter
togetterとか●   t.coだらけになっちゃう●   t.coを展開するとbit.lyだったり
汎用展開のWeb API
Untiny●   多段展開してくれるけどURLは1つのみ
Long URL Please.com●   複数のURLを1リクエストで展開してくれるけ    ど1段のみ
なければ作る
nagaino●   複数URLを多段展開するWeb APIサービス
使い方% curl http://nagaino.herokuapp.com/api/v0/expand?format=json_simple&q=http%3A%2F%2Ft.co%2F2XTGcnPZ&q=http%3A%2F%2Ft.co...
特性・要件●   参照透過性    ●   同じ入力からは常に同じ出力●   並行性    ●   複数のURLを同時に展開●   PaaSで動作    ●   マルチコア(たぶん)のサーバーを無料で、自分で        管理せずに
Clojure
Heroku便利●   Clojure対応してるPaaS
Herokuを使うのに用意するもの●   Leiningen    ●   Leiningenは、Rails 3でいうと、railsコマンドと        bundlerとrakeとrvmを足したようなもの●   git●   Herokuの...
あとは●   ringアプリを作る    ●   ringは、RackとかWSGIとかPlackとかClackとか        みたいな層    ●   ringじゃなくてもいいかもしれないけど未調査    ●   ちなみに、ringの作者の...
Herokuの使い方
プロジェクトを作る% lein new nagaino% cd nagaino
gitのローカルリポジトリを作る% git init% git add .% git commit ­m initial commit
アプリを書く(defroutes main­routes  (GET "/" [] "<h1>Hello World Wide Web!</h1>")  (route/resources "/")  (route/not­found "Page...
Procfileを1行書く% > Procfile <<<web: lein run% git add Procfile% git commit ­m Procfile
Heroku上にアプリを新規作成する% heroku create ­­stack cedar nagaino
git pushでデプロイ% git push heroku master
これだけでWebアプリが   動く
ちなみに、“lein”が“ライン”で“lain”が“レイン”なのは、なんとなく納得いかない気がするけど(ローマ字的に)、まあどうでもいいですね
実装
やることのイメージ("http://t.co/AAA" "http://t.co/BBB" "http://t.co/CCC" )       ↓("http://bit.ly/XXX" "http://tinyurl.com/YYY" "ht...
全体の流れ        ※figures by blockdiag
(defn api­expand [params]  (­>> params       query­>longurl       (transform­result (params "format"))       (res (:format...
処理本体
(defn expand­urls [sq]  (­>> sq       distinct       (map #(­> %                 string­>nagaino­url                 updat...
展開本体
展開本体
(defn expand­nagaino­urls­1 [table n­urls]  (let [n­urls­2 (expand­from­cache n­urls)   table2 (update­table table n­urls­...
HTTPリクエストして変換テーブルを作る
(defn update­table [table sq]  (­>> sq       (filter #(­> % :done? not))       (map #(­> % :long_url_path first))       di...
キャッシュ●   問い合わせは、fetchの:$inで、1フェーズ1クエリで    ●   SQLのSELECTのIN相当●   保存は、mass-insert!で、1リクエスト1クエリで    ●   SQLのbulk insert相当●  ...
TODO●   APIのドキュメントを書く●   コードをGitHubに上げる    ●   ブログ記事のコードスニペットをコピペして改造している箇所があるので、その扱        いをどうするか…●   Clojure 1.3化    ● ...
長いの
Upcoming SlideShare
Loading in...5
×

長いの

1,552

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,552
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "長いの"

  1. 1. 長いの @emasaka
  2. 2. 自己紹介● @emasaka● 本名:高橋正和● 40代 フリーター● ブログ 「本を読む」http://emasaka.blog65.fc2.com/● ja.wikipedia.orgで「Locator/Identifier Separation Protocol」のページを立てた人● 代表作:Bash on Rails
  3. 3. twitterでオヤジギャグを流す人 ※それはシュレーディンガーです
  4. 4. Twitter
  5. 5. togetterとか● t.coだらけになっちゃう● t.coを展開するとbit.lyだったり
  6. 6. 汎用展開のWeb API
  7. 7. Untiny● 多段展開してくれるけどURLは1つのみ
  8. 8. Long URL Please.com● 複数のURLを1リクエストで展開してくれるけ ど1段のみ
  9. 9. なければ作る
  10. 10. nagaino● 複数URLを多段展開するWeb APIサービス
  11. 11. 使い方% curl http://nagaino.herokuapp.com/api/v0/expand?format=json_simple&q=http%3A%2F%2Ft.co%2F2XTGcnPZ&q=http%3A%2F%2Ft.co%2FS5NCrzZD{"status_code":200,"data":{"expand":{"http://t.co/S5NCrzZD":"http://shibuya.lisp­users.org/2011/10/18/sltt7­lter/","http://t.co/2XTGcnPZ":"http://atnd.org/events/20328"}}}
  12. 12. 特性・要件● 参照透過性 ● 同じ入力からは常に同じ出力● 並行性 ● 複数のURLを同時に展開● PaaSで動作 ● マルチコア(たぶん)のサーバーを無料で、自分で 管理せずに
  13. 13. Clojure
  14. 14. Heroku便利● Clojure対応してるPaaS
  15. 15. Herokuを使うのに用意するもの● Leiningen ● Leiningenは、Rails 3でいうと、railsコマンドと bundlerとrakeとrvmを足したようなもの● git● Herokuのアカウントとツール
  16. 16. あとは● ringアプリを作る ● ringは、RackとかWSGIとかPlackとかClackとか みたいな層 ● ringじゃなくてもいいかもしれないけど未調査 ● ちなみに、ringの作者のMark McGranaghan (mmcgrana)はHerokuの人
  17. 17. Herokuの使い方
  18. 18. プロジェクトを作る% lein new nagaino% cd nagaino
  19. 19. gitのローカルリポジトリを作る% git init% git add .% git commit ­m initial commit
  20. 20. アプリを書く(defroutes main­routes  (GET "/" [] "<h1>Hello World Wide Web!</h1>")  (route/resources "/")  (route/not­found "Page not found"))
  21. 21. Procfileを1行書く% > Procfile <<<web: lein run% git add Procfile% git commit ­m Procfile
  22. 22. Heroku上にアプリを新規作成する% heroku create ­­stack cedar nagaino
  23. 23. git pushでデプロイ% git push heroku master
  24. 24. これだけでWebアプリが 動く
  25. 25. ちなみに、“lein”が“ライン”で“lain”が“レイン”なのは、なんとなく納得いかない気がするけど(ローマ字的に)、まあどうでもいいですね
  26. 26. 実装
  27. 27. やることのイメージ("http://t.co/AAA" "http://t.co/BBB" "http://t.co/CCC" )     ↓("http://bit.ly/XXX" "http://tinyurl.com/YYY" "http://goo.gl/ZZZ" )     ↓("http://example.com/000" "http://example.jp/111" "http://example.org/222" ) ※URLはイメージです。実際の展開結果 には対応しません
  28. 28. 全体の流れ ※figures by blockdiag
  29. 29. (defn api­expand [params]  (­>> params       query­>longurl       (transform­result (params "format"))       (res (:format params)) ))(defroutes route  (GET "/api/v0/expand" [:as params]       (api­expand (:query­params params)) )  (POST "/api/v0/expandText" {params :params}        (api­expand­text params) )  (route/files "/" {:root "./resources/public"}) )
  30. 30. 処理本体
  31. 31. (defn expand­urls [sq]  (­>> sq       distinct       (map #(­> %                 string­>nagaino­url                 update­done ))       (expand­nagaino­urls {})       update­cache       (map nagaino­url­>map) ))
  32. 32. 展開本体
  33. 33. 展開本体
  34. 34. (defn expand­nagaino­urls­1 [table n­urls]  (let [n­urls­2 (expand­from­cache n­urls) table2 (update­table table n­urls­2) ]    [table2     (map #(­>> %                (expand­from­table table2)                update­status )          n­urls­2 )] ))(defn expand­nagaino­urls [table n­urls]  (let [[table2 r] (expand­nagaino­urls­1 table n­urls)]    (if (every? :done? r) r (recur table2 r)) ))
  35. 35. HTTPリクエストして変換テーブルを作る
  36. 36. (defn update­table [table sq]  (­>> sq       (filter #(­> % :done? not))       (map #(­> % :long_url_path first))       distinct       (group­by #(if (re­find bitlyurl­regex %)                      :bitlyurls :urls ))       (#(map deref              (concat               (urls­>expm­seq (:urls %))               (bitly­urls­>expm­seq (:bitlyurls %)) )))       flatten       (reduce (fn [r v] (conj r {(:short_url v) v}))               table )))
  37. 37. キャッシュ● 問い合わせは、fetchの:$inで、1フェーズ1クエリで ● SQLのSELECTのIN相当● 保存は、mass-insert!で、1リクエスト1クエリで ● SQLのbulk insert相当● 多段URL展開のサブセットも保存 ● A→B→Cなら、A→B→CとB→Cを保存
  38. 38. TODO● APIのドキュメントを書く● コードをGitHubに上げる ● ブログ記事のコードスニペットをコピペして改造している箇所があるので、その扱 いをどうするか…● Clojure 1.3化 ● clojure.contribが1.3に対応してないので…● HTTPクライアントライブラリを変更 ● 作者がもうやめるとかなんとかReadmeに… ● 非同期リクエストとか使ったほうがいいのかな…● 異常系に地味に対応 ● URLが100個とか来たときどうしようか…
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×