人間の暇な時間の潰し方

人間は、どのように時間を潰すか。例えば、次の電車まで1時間余の時間があったとする(日本の田舎、鹿児島では、このようなことが当たり前に起こる)。
彼はスマホで連絡先の一覧を見る。チャットアプリの友達一覧には数百の親しい人や、連絡先を交換したその時だけ知人だった人たちが並んでいる。彼はその中から適当な人を探す。今から彼がかける電話を受け付けてくれそうな人間だ。そのような人たちに片っ端から電話をかけていこうというわけだ。
彼の電話は現状の報告から始まる。今、駅にいます。次の電車は何時です。家に帰り着くのは何時です。といった具合だ。どのような人に対しても、その部分は不変で、必要不可欠のようだ。そこで共感を得られるかどうかが彼にとっての一番の心配事なのである。驚くべきことに、その報告と軽い挨拶だけで電話が終わることもある。
ある時、電話の相手は気の合う友達だ。会話は、この前に遊んだときのエピソードについて思い出しながら話すことから始まり、次に遊ぶことを約束して終わる。またある時は学校の先輩だ。彼は世間一般の多くの人と同じように、上下関係なく人と親しくなれる一方で接する上では上下関係を重んじる。会話の中程から終わりまで、話の主役は常に先輩側である。なるほど、これが人間の上下関係というものだ。
私は彼の電話する様子を観察して文章を書くことで時間を潰している。どちらのほうが有意義で、どちらのほうがそうでないという関係はない。また、どちらか一方が優れているということもない。私の文章は彼の行動に依存しているが、それと同時に、彼の行動の永続性も私の文章に依存しているのである。彼の電話の相手のほとんどは電話が切れたあと、すぐに彼との電話のことを頭の隅に押しやって別のことを考え、何日か立つと忘れてしまうからだ。
以上が、ある2人の人間の時間の潰し方である。

クジラータとモチラータ

クジラータは反生殖主義者である。
両親にその旨は伝えたときは少し悲しそうな顔をしていた。
あれから「孫の顔をいつか見たい」と言うことはなくなった。

 

クジラータはパイプカットの施術を受けた。
将来の自分の意志に自信が持てなかったからだ。
22歳の誕生日のことだった。

 

クジラータは頭が痛い。
最近、寝ても覚めても頭が痛い。
こんなに頭痛薬を飲んでいるのに。

 

クジラータは腹が痛い。
下腹部はモチのように腫れ(かすかに赤い)、触ると鈍痛がする。
始めの頃は無視していたが、どんどん大きくなってゆく。

 

クジラータは病院に行った。
主治医の先生に紹介してもらった大きな病院だ。
検査が終わり、病室の椅子に座らされた。先生が検査結果を見ている。
「どうやら妊娠しているようです」

 

クジラータは自殺した。

 

 

 

モチラータは今年で27歳になる。

Yayakaプロトコルで実装する真の分散SNS (ja)

English version

Yayakaプロトコルは分散SNSのためのプロトコルです。 この記事では、これがなぜ作られて、なぜ良いのかを説明します。

目的

Yayakaプロトコルは大まかに以下の目的があります。

  • 脱中央集権
  • 民主化
  • 小さなサーバーでのネットワークへの参加
  • 階層化されたプロトコルによる高い拡張性

脱中央集権は自由を得るための最初のステップです。 独占プラットフォームはあなたの自由を奪うことがあります。

民主化は自由を得るための第2ステップです。 Yayakaプロトコルは独占プラットフォームを複数の独裁プラットフォームには分割しません。

小さなサーバーでのネットワークへの参加はそれぞれのサーバーが分散SNSのすべての機能を実装する必要がないことを意味します。 それぞれのサーバーは最低限の機能だけを実装します。

階層化されたプロトコルによる高い拡張性は同じ目標をもつサーバー同士で協力しながら独自に拡張することが可能ということを意味します。

特徴

前述した目的を達成するためにYayakaプロトコルは以下の特徴を持ちます。

  • サーバー間を自由に移住できる。
  • それぞれのサーバーは分散SNSの一部分を実装する。
  • サーバー間の通信の方法はソケット通信やHTTPSなど任意のものが使える。
  • 追加のプロフィール属性やユーザーによるイベントの種類、コンテンツの種類は上層のプロトコルで定義される。

コンセプト

Yayakaサービス

YayakaサービスはIdentityサービス、Repositoryサービス、Social Graphサービス、Presentationサービスの4つあります。 それぞれのユーザーはIdentityサービスで登録を行い、他のサービスを認可します。 Repositoryサービスはユーザーによる投稿やお気に入り、リポストなどのイベントを保存します。 Social Graphサービスはユーザー同士の関係を保持し、イベントを配信します。 PresentationサービスはウェブフロントエンドやAPIを提供します。 それぞれのユーザーは複数のRepositoryサービスで投稿し、複数のSocial Graphサービスにイベントを配信し、用途に合わせて複数のPresentationサービスを利用することができます。 もしRepositoryサービスが不当な検閲を行ったり、PresentationサービスがUIやAPIの改悪を行ったらすぐに離れることができます。

Yayaka Meta/Messaging Protocol

Yayaka Meta/Messaging Protocol (YMP) は分散ウェブアプリケーションのためのメッセージングプロトコルです。 それぞれのサーバーはYMPの上層プロトコルとして複数のConnectionプロトコルやMessageプロトコルを実装します。 Connectionプロトコルはどのようにしてサーバー間で通信を行うかを定義し、Messageプロトコルはアプリケーションがメッセージの交換によりどのように動作するかを定義します。 YayakaプロトコルはYMPのMessageプロトコルの一つです。

Yayakaプロトコルの動作

登録

  1. ユーザーがどのサーバーで登録するかを決める。
  2. ユーザーはそのサーバーに信頼されたPresentationサービスの一つにユーザー登録のための情報を入力する。
  3. Presentationサービスは登録を行うサーバーのIdentityサービスにメッセージを送信する。
  4. Identityサービスはユーザーを作成する。

フォロー

  1. ユーザーがPresentationサービス上でフォロー操作をする。
  2. Presentationサービスはそのユーザーが認可したSocial Graphサービスの一つにメッセージを送信する。
  3. Social Graphサービスはフォロー先のSocial Graphサービスにメッセージを送信する。
  4. 2つのSocial Graphサービスはフォロー関係を保存する。

イベントの作成

  1. ユーザーがPresentationサービス上でイベント作成操作をする。
  2. Presentaitionサービスはそのユーザーが認可したRepositoryサービスの一つにメッセージを送信する。
  3. Repositoryサービスはイベントを保存する。
  4. Repositoryサービスは自分を購読しているSocial Graphサービスにイベントを配信する。
  5. それぞれのSocial Graphサービスも自分を購読しているサービスにイベントを配信する。

現状

YMPの定義はほとんど完成しています。 現在はYayakaプロトコルとElixirによるリファレンス実装を同時進行で進めています。

計画

以下が今後の計画です。

Yayakaへの貢献

YayakaプロトコルスイートのためのGitHub Organizationがあります。 気軽にIssueを立ててください。

Yayaka Protocol and Highly Distributed Social Blogging

Yayaka Protocol is a yet another protocol for distributed social blogging. I explain “Why I create”, “Why we love”, and “Why you will love” in this article.

Purposes

Yayaka Protocol has following purposes roughly:

  • Decentralization
  • Democratization
  • Participation with minimum servers
  • High extensibility with layered protocols

Decentralization is the first step to get our freedom. Monopolized platform may take your freedom.

Democratization is the second step to do that. It means Yayaka Protocol doesn’t divide a monopoly service into many authoritarian services.

Participation with minimum servers means we don’t have to implement all functions of distributed social blogging for each server. Each server can have a minimum implementation.

High extensibility with layered protocols means we can extend our web services uniquely in cooperation with other services which have a common view.

Features

Here are the features of Yayaka Protocol to perform the purposes.

  • Easily migration between servers.
  • Each server only has to implement a partial set of functions of distributed social blogging.
  • Any way to connect two different hosts is allowed. (Socket, HTTPS with token, etc.)
  • Additional profile attributes, type of social blogging events, and types of contents are specified in higher-level protocols.

Concepts

Yayaka Services

There are 4 yayaka services, identity service, repository service, social graph service, presentation service. Each user registers themselves with identity services and authorizes other services to use. Repository services store events like posts, favorites, reposts, etc. Social graph services store users' relations and deliver events properly. Presentation services provide interfaces to be used by users like front-end UI, API, etc. Each user can have multiple repository services to post, social graph services to broadcast, and presentation services to use UIs which match for each purpose. If a repository service censors unjustifiably or a presentation service regress its UI or API, each user can exit right away.

Yayaka Meta/Messaging Protocol

Yayaka Meta/Messaging Protocol (YMP) is a messaging protocol for distributed Web applications. Each server can implement multiple connection protocols and message protocols as higher-level protocols of YMP. Connection protocols specify how to establish a connection between two different hosts and message protocols specify how the application works with messaging between services. Yayaka Protocol is a message protocol of YMP (Yayaka Meta/Messaging Protocol).

How Yayaka Protocol works

Registration

  1. A user chooses a server to register him/herself.
  2. The user enters registration information on one of presentation services trusted by the server.
  3. The presentation service sends a message to the identity service of the server.
  4. The identity service creates a user.

Following

  1. A user enters who to follow on a presentation service.
  2. The presentation service sends a message to one of social graph services authorized by the user.
  3. The social graph service sends a message to target social graph.
  4. Both two social graph services store the following relation.

Creating an event

  1. A user enters data to submit on a presentation service.
  2. The presentation services send a message to one of repository services authorized by the user.
  3. The repository service stores the data.
  4. The repository service broadcasts the event to social graph services which subscribe the repository service.
  5. The each social graph services broadcast the event to services which subscribe them.

Present condition

Writing the YMP specification is almost finished. Currently, I’m simultaneously writing Yayaka Protocol specification and a reference implementation with Elixir.

Plans

Here are the plans of Yayaka Protocol and YMP:

  • Create a first connection protocol
  • Create a message protocol for distributed registry to register higher-layer protocols of YMP.
  • Create a message protocol for distributed git hosting service.

How to contribute to Yayaka Protocol

There is an organization of Yayaka Protocol Suite. Please feel free to open issues.

kuyさんと話した

はじめに

以前からお会いしたいと思っていたkuyさんに会って話をすることができた。 結構色々なことを話したので備忘録的にブログに書くことにした。

技術的な話

※ 以下には私の考えや思ったことが含まれるので、実際に会話したときの結論やkuyさんと共有した考えというわけではない。

Redux

Reduxのコンセプトを破った方がうまいこといくならそうするべきか、みたいな話をした。 後からredux-thunkには「別に無理して守る必要は無い」というメッセージが含まれているのかもしれないと思ったりした。

ReduxとReact

ReduxかReactのどちらが将来的に技術的負債になりやすいかでいうと断然Reactじゃないかみたいな話。 Reduxは割りと簡単に移行できそう?

React Vue Redux redux-saga の教育コスト

ReactかVueかで迷ったときにReactの方が教育コストが小さいと思って選んだ話とその理由、 redux-sagaでのsagaの作り方よりもReduxのreducerの作り方のほうが難しく感じる人がいて驚いた話などをkuyさんに話した。 各個人が普段やっている分野によってどちらの方が教育コストが高い/低いというのが逆転する場合があるみたいな話や、習得が簡単に感じたとしてもちゃんと理解して使えているかは分からないみたいな話をした。

Reduxルーターライブラリ合戦

kuyさん作のredux-towerと私のredux-pagesの話。 redux-towerは解決すべき問題に出会う機会が少なくてなかなか進まないという話だった。 redux-pagesはもうほとんど完成形だが、使っているpathのテンプレートエンジンに多少不満があるので別のに乗り換えたいと考えている話をした。 bouzuyaさん作のbathが良さそうという話になった。

ElixirとPhoenix

ElixirやPhoenixについて聞かれたので、WebサーバーのようなErlang/OTPが向いている分野ではElixirは本当に書きやすいという話をした。 あとPhoenix Channelsが便利。

オートマトン

オートマトンの魅力や可能性などについてkuyさんに紹介してもらった。 オートマトンを使って最近ボトルネックになりつつあるマシンなどの全体に対して適用されるようなエラー対策(メモリのエラーチェック等)の必要性を無くし、コンピューターの処理速度を更に向上させることを目指す研究があるみたいな話だった(と思う)。

Ocaml

OcamlとかReasonとかの話を聞いた。 Ocaml製Webサーバーを作る厳しさについての話など。

Keras

Kerasを使って色々やろうとしていることやKerasとChainerについてよく言われる話を紹介した。 Define and runかDefine by runみたいな話。 一応Keras作者のツイートも紹介した。

GAN

GANの紹介。深層学習のヤベー奴。

Word2Vec

Word2Vecは結構応用できるみたいな話。

Docker

Dockerについてぼんやりとした知識しか持っていなかったのでkuyさんに教えてもらった。

Kubernetes

Kubernetesで実際にサーバーの再起動とかが行われる様子を見せてもらったりした。

標準ライブラリ

標準ライブラリが洗練されていない言語は辛い、みたいな話。

Yayaka.net

Yayaka.netのソースコードはElixirの学習に使えるか?みたいな話になり、一部に役立つコードもあるかもしれないが、ほとんどのコードは雑に書かれていることを説明した。

Yayakaプロトコル

話した合計時間的にはこの話題が一番長い。 Yayakaプロトコルはマイクロサービス的で、さらにマイクロフロントエンド的な面も持つみたいな話。 マイクロフロントエンドについては初めて聞いたのでkuyさんに教えてもらった。 時代は脱モノリシック。

その他の話

アニメ、音楽、ゲーム、ドラマ、映画

趣味についての話。 ものすごく雑な概要としては、私がフリフラの布教活動をした。

マストドンに対抗して分散SNSを作った

はじめに

タイトルは釣り。s/対抗/便乗

あと、「作った」という表現は厳密には正しくなくて、以前作ったYayaka19サイトを”分散化した”というほうが近い。

記事の目的

  • いろいろと忘れてしまう前に記録しておく
  • アナウンスメント
  • 連邦全体のユーザー数を5人くらい増やす
  • サーバーが1つくらい増えたらすごい

目的に記録が含まれているというのもあって結構余計なこととか書く。

経緯

Yayaka19

もともと(Share)という名前で作り始めた。最初は、増田からパーマリンクや時系列表示を無くしたようなサービスにするはずだったが、 機能を足したり引いたりしているうちに今のような形に。 Yayaka19という名前に変えることになったのは、利用者から「Shareという名前はググラビリティが悪いのでKOKOMINECOCONAみたいな感じのエントロピー高い名前にしてほしい」と言われたため。

OStatus

OStatus*1マストドンで知ったかというと違っていて、 マストドン流行以前からGNU Socialのアカウントを持っていたため、OStatusについても知っていた。 マストドン流行以前にもYayaka19にOStatusを実装して分散SNSにしようという話はしていたが、 周りは「自分ならOStatusは実装したくない」という反応で、自分も実装したくなかった。 また、独自プロトコルで実装する(Yayakaプロトコル構想)という考えもあったが、 そもそもYayaka19を分散SNS化する必要はあるのか?分散SNSの需要は本当にある?というところで確信がなかったため、 時間をかける気は起きなかった。

そんなところに、あの日本でのマストドン流行が起こった。 少なくとも私の観測範囲では流行っていることを確認できた。 GNU Socialと違っていろんな界隈でたくさんのアカウントが作られていたし、Twitterでの投稿数が減少した人も見た。 少なくとも私の観測範囲では流行っていることを確認できた、分散SNSにも一定の需要があると判断し、 独自プロトコル(Yayakaプロトコル)を用いてYayaka19を分散SNS化することを思い立った。

設計と実装

とりあえず方針としてはサーバー同士をWebSocketで接続して、なにかあるたびにメッセージを送受信する。 例えば、あるユーザーが外部サーバーのユーザーをフォローしていたら、タイムラインをロードする度に外部サーバーから投稿を取得する。 他には、新しい投稿があったときに投稿者のフォロワーに外部サーバーのユーザーがいれば、新しい投稿を外部サーバーに送る。

一応Yayakaプロトコルにする予定があるので、ある程度留意して設計した。

主なモジュール

実装

実装するには、まず、WebSocketのサーバー側とクライアント側を作る必要がある。 しかし、両方を自分で作るのは面倒だったため、Yayaka19が使っているWebフレームワークであるPhoenixフレームワークのChannelsという機能を無理やりサーバー側として使うことにして、 クライアント側だけ自作した。それはライブラリとして別に公開している(phoenixchannelclient)。 SocketRegistryにはElixirのRegistryという比較的新しいモジュールを利用した。 全体的に実装していて楽しかった。

結果と反応

分散化できた。 結構面白がってもらえている気がする。 早速、私以外が運営するサーバー(19.fubaiundo.org)が立ったので良かった。

画像集

プロセスの関係図

f:id:ryo12redstone:20170511013401p:plain

VisualixirというツールでErlang VMのプロセスの関係図を出した。 真ん中の花火みたいなやつが多分HTTPのコネクションプール、左下のはRDBのコネクションプール、右側はフレームワークのやつ、という感じなので左上が実装した部分。

タイムライン読み込みの状態

f:id:ryo12redstone:20170511013507p:plain

errorとかtimeoutとかloadingとかになる。この表からRetryもできる。

リモートフォローの様子

f:id:ryo12redstone:20170511013636p:plain

写真が暗いのはブラウザの拡張機能でページが黒くなってるから。

military or bomb

f:id:ryo12redstone:20170511013734p:plain

if式くれ。

AA

f:id:ryo12redstone:20170511013850p:plain

ウーーイヌ

今すぐダウンロー

f:id:ryo12redstone:20170511014006p:plain

収益

f:id:ryo12redstone:20170511014052p:plain

サーバー代は700$/monthミス

サーバー代は$7/month

今後のアレ

  • Remote Mystery(やばい機能)
  • テスト書く
  • Dockerイメージ
  • Yayakaプロトコル
  • 外側をOStatusに見せるためのプロキシ
  • Editor Pluginsが流石にゴミ置き場すぎる

最後に

特になし。

リンク

*1:マストドンGNU Socialが使っている分散SNSのためのプロトコル

ReduxでのRoutingはこれでやっていこうと思います。

Reduxでの理想のRoutingライブラリを求めて作ったredux-pagesの紹介記事です。

リポジトリ: ryo33/redux-pages

実用例: ryo33/Yayaka19

以前の方法での不満

redux-pagesを作るに当たって、まず、前にSPAサイトを作っていて不満に感じたことをまとめました。 その中で、特に解決したかったものが以下の4つです。

  1. Pathのパース結果はRouter(View)だけでなく、Middlewareでも必要である
  2. 現在のページがStateに格納されていてほしい
  3. Pathをリダイレクト処理などで手書きしたくない
  4. ページ遷移に関連する処理はMiddlewareに書きたい

(1)で言いたいことは、Pathのパース結果は画面描画時だけではなく、 表示されているページによってMiddlewareでの処理内容を変えたいときにも必要だということです。 redux-pagesのREADMEに書かれている

Parse once, route anywhere

は、このことを言っています。

(2)は、Pathと画面表示は常に一致しているわけではないということです。 例えば、閲覧権限の無いページのPathにアクセスして、エラーページのPathにリダイレクトされるまでの間は何を描画するべきでしょうか。 また、Webサイトの中にはページ移動後にコンテンツのダウンロードが終わるまでは前のページが表示されたままのものがあります。 このように、Pathと画面表示は常に一致するわけではありません。 しかし、Routerで描画したり、Middlewareで処理の分岐をしたりするためには、 現在のページが常に分かるようになっている必要があります。

(3)は、Pathを手書きすると、間違っていても発見しづらく、またPath形式の変更が容易でなくなってしまうためです。

(4)は個人的な好みです。

redux-pagesの基本的なアイデア

以上で述べた不満を元にした基本的な考えは以下の3つです。

  1. Stateには現在どのページを表示すべきなのかが保持される
  2. ページオブジェクトを定義して、ページ遷移Actionや、そのページへのPathはメソッドで生成する
  3. ページ遷移は単一のActionをdispatchすることで行う

不満1を解消するのは(1)(2)、不満2を解消するのは(1)、不満3を解消するのは(2)、不満4を解消するのは(3)です。

(3)で単一のActionになっているのはMiddlewareでのページ遷移処理を単純なコードで書くためです。 例えば別のページへのリダイレクトはdispatchするだけでいいですし、 ページ遷移を遅らせるときも単にnextDispatchを呼ぶのを遅らせるだけです。

基本的な動作イメージ

redux-pagesを使ってページ遷移を行うときの基本的な動きを説明します。

Actionをdispatchしてページ遷移

  1. redux-pagesのMiddlewareにActionが到達したときにPathが変更される
  2. Middlewareで様々な処理が行われる
  3. Stateが変更されViewもそれに応じて変更される

これが、基本的なページ遷移時の処理の流れです。 ユーザー認証やリダイレクトなどは(2)のMiddlewareの中で行います。

locationの変化によるページ遷移

こちらは、ブラウザの戻るボタンなどが押されたときに使われます。

  1. Pathのパース結果でActionが投げられる
  2. Middlewareで様々な処理が行われる
  3. Stateが変更されViewもそれに応じて変更される

実用

redux-pagesはYayaka19というSPAアプリケーションで実際に使用しました。 とりあえず今のところは大きな問題など無く運用できてます。

前述の不満の解消以外の利点としては複数のページに適用したい処理をまとめて書けることが挙げられます。 例えば、アクセス権限のあるページかどうか調べてリダイレクトを行う処理を各ページごとに分けて書く必要はなく、 単にallowedPageNames.includes(action.payload.name)というような条件文に応じてリダイレクトを行うだけです。

あと、使ってから気づいたのですが、nextDispatchを遅らせることによりページ遷移を遅らせる技は滅多に使わないと思います。 ロードが終了するまで前ページを表示するよりは、ページ遷移時のHookでisLoading状態にして、あのグルグルを表示したほうがSPAぽくなります。

ちなみにページ遷移時のMiddlewareの処理にはredux-middlewaresを用いています。 例えば、ログイン確認とそれによるリダイレクトにはcreateReplacerを、ページ遷移時のHookにはcreateAsyncHookを使います。 個人的に直感的にMiddlewareを書くことができるので気に入っています。 ただ、既にredux-sagaredux-logicなどを導入している場合はそちらを使ったほうがいいです。

課題

例えば/posts/:postNumberというパスがあってpostNumberを文字列型から数値型にキャストしたいといったときに、 エラー処理も含めるとMiddlewareでActionを変換する必要があります。 これをどうにかページ定義時に書くことができるようにしたいと考えています。

あとは、導入時の雛形が比較的多いのもどうにかして減らしたいです。

さいごに

割とまともに使えて、辛いポイントもそんなにないので、とりあえずしばらくはこれを使っていこうと思います。