Jay Taylor's notes

back to listing index

losvedir/ephemeral2

[web search]
Original source (github.com)
Tags: elixir phoenix ephemeral github.com
Clipped on: 2016-06-11

Skip to content
Ephemeral P2P over websockets, Phoenix/Elixir.
CSS JavaScript Elixir
Latest commit 5a82327 on May 18, 2015 Image (Asset 2/2) alt= Add MIT license
config [GJD] Upgrade phoenix to 0.11 - works except for terminate a year ago
lib trap exits for 'all' channel a year ago
priv/static Fix javascript ES6 issue (missing this.) a year ago
test Initial commit. Works, but ugly a year ago
web Fix javascript ES6 issue (missing this.) a year ago
.gitignore Initial commit. Works, but ugly a year ago
LICENSE Add MIT license a year ago
Procfile Revert "Try other production Procfile" a year ago
README.md Update README with installation instructions a year ago
brunch-config.js Initial commit. Works, but ugly a year ago
elixir_buildpack.config Cache when pushing to heroku now a year ago
mix.exs Upgrade phoenix to 0.13 a year ago
mix.lock Upgrade phoenix to 0.13 a year ago
package.json Initial commit. Works, but ugly a year ago
ttb_last_config Initial commit. Works, but ugly a year ago

README.md

Ephemeral P2P

See example implementation running here. Discussion on Hacker News here.

This app hosts "P2P" pages that are "ephemeral". We say "P2P" because the clients host the page; new visitors retrieve the page contents from other visitors on the same page. It's "ephemeral" in that the server does not store the contents of any page, so once the last visitor leaves a particular page, it is gone.

How it works

Ephemeral P2P is an Elixir/Phoenix app, taking advantage of Phoenix's excellent Channel functionality. All of the logic lies in two channels, the  HaveChannel  for clients who have a particular bit of content, and the  WantChannel  for visitors who want it. The content is addressed by its SHA256 (let us say  abc123 ), and the two topics associated with that content are  have:abc123  and  want:abc123 .

A new page is created from the homepage. A visitor fills in the textarea with whatever content they desire, and presses the "Submit" button (which is not a form submission). The client hashes the content (let's call the hash  abc123 ) and uses the HTML5 history api to change the URL to  /abc123  for easy copy/paste-ability. The client then joins the "have:abc123" topic and begins listening for  "content_request"  messages, ready to respond with a  "content"  message that includes the page content which it has in memory.

A subsequent visitor who loads  /abc123  joins the  want:abc123  topic and tries to obtain the content. First it listens for a  "content"  message that another visitor may have provoked. If the visitor does not receive it in 2 seconds, it will send a  "content_request"  message itself. The server will re-broadcast this message to all  have:abc123  subscribers, except that a  handle_out  will allow the message with probability  1/subscriber_count  and drop it otherwise. Any  have:abc123  subscribers who receive the message will respond with the content and the server will  broadcast  it to all  want:abc123  subscribers. The new visitor will send a  "content_request"  message every 2 seconds until it gets the content (for the case where the  handle_out  drops the message to everyone, or a  have  subscriber fails to respond for some reason.)

When a  want:abc123  subscriber gets the content, it leaves the  want:abc123  topic and joins the  have:abc123  topic, ready to pass it along to newer visitors.

Lastly, whenever a subscriber joins or leaves  have:abc123 , the new visitor count is broadcast, so all clients know the "health" of the page and how close it is to going away.

Run it yourself

First you'll need to install Elixir. Once you have elixir set up, it should be as easy as:

normal$ git clone git@github.com:losvedir/ephemeral2.git
$ cd ephemeral2
$ mix deps.get
$ mix phoenix.server
normal

That should serve a copy of the app locally at  localhost:4000 . If you would like to modify the CSS or Javascript, you'll need to install npm and then brunch with:

normal$ npm install -g brunch
normal