!SLIDE
!SLIDE
import spark.streaming.StreamingContext._ | |
import spark.streaming.{Seconds, StreamingContext} | |
import spark.SparkContext._ | |
import spark.storage.StorageLevel | |
import spark.streaming.examples.twitter.TwitterInputDStream | |
import com.twitter.algebird.HyperLogLog._ | |
import com.twitter.algebird._ | |
/** | |
* Example of using HyperLogLog monoid from Twitter's Algebird together with Spark Streaming's |
import spark.streaming.{Seconds, StreamingContext} | |
import spark.storage.StorageLevel | |
import spark.streaming.examples.twitter.TwitterInputDStream | |
import com.twitter.algebird._ | |
import spark.streaming.StreamingContext._ | |
import spark.SparkContext._ | |
/** | |
* Example of using CountMinSketch monoid from Twitter's Algebird together with Spark Streaming's | |
* TwitterInputDStream |
import scala.language.postfixOps | |
import java.io._ | |
import scalaj.http._ | |
import scalaz._, Scalaz._ | |
import scalaz.effect._, Effect._, IO._ | |
import scalaz.concurrent.Promise |
!SLIDE
!SLIDE
JavaScript(記事ではnode.js)におけるコールバックを命令型、Promisesを関数型と捕らえ、node.jsの多くのAPI、モジュールがコールバックを利用している点が欠点となっている解説をしつつ、関数型のアプローチについて、Promisesを使ったアプローチの利点を紹介。
上記の記事に対して、node.jsのエコシステムの今を支えているのがコールバックではないかという反論。関数型アプローチに比べて命令型、コールバックをつかった場合は未来に発生するべき振る舞いをそれらしく表現できる点が多くのプログラマにとって理解しやすいという利点を紹介している。
trait Magma[A] { | |
def append(x: A, y: A): A | |
} | |
object Magma { | |
implicit def Monoid[A](implicit m: Monoid[A]) = new Magma[A] { | |
def append(x: A, y: A) = m.append(x, y) | |
} | |
} |
現行訳: save関数はUserModuleにもMessageModuleにもあるので衝突してしまう。ここでは引数の型が違うのでコンパイラエラーになるけど、オーバーロードの場合は C++ の悪夢の日々よ再び。 | |
訳案: save関数はUserModuleにもMessageModuleにもある。受け取る型が違うので、コンパイラはこれを区別することができるけど、それはオーバーロードだ。オーバーロードはキモいし、酷いし、C++ 時代の遺物なので、できれば回避したい。 | |
現行訳: 巨大なシステムでモックを使いたいときは、Spring 等の依存性注入フレームワークを使うだろう | |
訳案: Spring 等の依存性注入フレームワークを使って大規模なシステムでモックを使ったことがある人は、それがいかに大変かを知っているだろう。 | |
現行訳: 問題は、複数のモジュールに起動ルーチンと停止ルーチンがある場合だ。モジュールから他のモジュールへ委譲するのは、非常に複雑になるのでやりたくない。 | |
訳案: 問題は、起動・停止ルーチンがあるモジュールが複数ある場合だ。ルーチン内から各モジュールが自分以外のモジュールに次々と委譲していくのは、非常に複雑になるのでやりたくない。 | |
現行訳: 少し注意が必要なのは、これらのライフサイクル関数の正確な実行順序は、自分で順番を取り扱うべきだということだ。 |
[[syntax trees at end of jvm]] // Param.scala | |
package <empty> { | |
final class Param extends Object { | |
<paramaccessor> private[this] val i: Int = _; | |
<stable> <accessor> <paramaccessor> def i(): Int = Param.this.i; | |
override <synthetic> def hashCode(): Int = Param.hashCode$extension(Param.this.i()); | |
override <synthetic> def equals(x$1: Object): Boolean = Param.equals$extension(Param.this.i(), x$1); | |
def <init>(i: Int): Param = { | |
Param.this.i = i; | |
Param.super.<init>(); |
Slightly disorganized but reasonably complete notes on the algorithms, strategies and optimizations of the Akka Cluster implementation. Could use a lot more links and context etc., but was just written for my own understanding. Might be expanded later.
Links to papers and talks that have inspired the implementation can be found on the 10 last pages of this presentation.
This is the Gossip state representation: