Scala STM Commit Barrier

A `CommitBarrier` allows multiple transactions on separate threads to perform a single atomic commit.  All of the actions performed by all of the atomic blocks executed by members of the barrier will appear to occur as a single atomic action, even though they are spread across multiple threads.

Commit barriers can be used to implement transactors, where actions taken by multiple actors should be atomic as a single unit.

Because there is no ordering possible between the atomic blocks that make up a commit barrier, if those transactions conflict then the only way to avoid deadlock is to roll back all of the barrier’s members.

If you observe a cancel cause of `CommitBarrier.MemberCycle` then this has happened to you, and you need to run more of the logic on a single thread inside a single transaction.

This abstraction is based on Multiverse’s `CountDownCommitBarrier`, by Peter Veentjer.

Scala STM コードリーディングメモ

Ref を作る

object Ref の factory は、impl.STMImpl.instance

impl.STMImpl.instance は、scala.concurrent.stm.ccstm.CCSTM を impl.STMImpl にキャストしたもの

Ref.apply で 1:Int とか渡すと newPrimitiveRef > factory.newRef が呼ばれる

factory は、impl.RefFactory だけど CCSTMRefs.Factory が実体。CCSTM が CCSTMRefs.Factory を extends している

最終的に new IntRef(1) の結果が返る

atomic の呼び出し

atomic > scala.concurrent.stm.TxnExecutor.defaultAtomic > impl.STMImpl.instance > scala.concurrent.stm.ccstm.CCSTM という所までは、Ref と同じ

CCSTM は、CCSTMExecutor を extends している。これの def apply[Z](block: InTxn => Z)(implicit mt: MaybeTxn): Z が呼ばれる

InTxnImpl.apply の中で implicit で渡した mt が InTxnImpl だったら mt をそのまま、そーではなければ、get

一番外側の atomic なら get を、内側なら mt をそのまま返す

get は、ちょっと追えなかったので後で。

scala + amqp の I/F 悩み中

結果を全て Either で返すと仮定すると下記となる

(connect(host = "localhost", username = "guest", password = "guest") { conn =>
  conn.channel { ch =>
    for {
      ex <- ch.declareExchange(name = "test.exchange", type = "direct").right
      q  <- ch.declareQueue(name = "test.queue").right
      br <- q.bind(exchange = ex, routingKey = "test").right
      pr <- ex.publish(routingKey = "test", payload = "Hello world!".getBytes).right
    } yield pr
  }
}) match {
  case Left(e) => println(e.getMessage)
  case _       =>
}

失敗は全て Exception で返すと仮定すると下記となる

try {
  connect(host = "localhost", username = "guest", password = "guest") { conn =>
    conn.channel { ch =>
      val ex = ch.declareExchange(name = "test.exchange", type = "direct")
      val q  = ch.declareQueue(name = "test.queue")
      q.bind(exchange = ex, routingKey = "test")
      ex.publish(routingKey = "test", payload = "Hello world!".getBytes)
    }
  }
} catch {
  case e: Exception => println(e.getMessage)
  case _ =>
}

見た目も使い勝手も変わらない気がする。Scala は、どちらの記述もサポートしているので、どちらを採用するのが良いのか、さっぱり解らない。

scala + amqp

以下、Java 版 RabbitMQ Client の接続例
ConnectionFactory factory = new ConnectionFactory()
factory.setUsername(userName);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setHost(hostName);
factory.setPort(portNumber);
Connection conn = factory.newConnection();

これを Scala を使ってラップしたい。

・案1:コールバック内で設定する(implicit 使ってみたい病
val conn = connect {implicit prop =>
    username(userName)
    password(password) // ..snip..
}

・案2:DSL で Factory を作る
考えたけど挫折

・案3:素直に名前付き引数
val conn = connect(
    username -> userName,
    password -> password
)

・案4:Map を使う
val conn = connect(Map(
    username -> userName,
    password -> password
))

Scala が得意な方は、こーいう時は、どうするんだろ?

2010年秋見たいアニメ

10/1(金) 22:00 アニマックス
http://www.animax.co.jp/marvelanime/

10/2(土) 24:10(以降 23:50) テレビ東京
http://www.tegamibachi.com/

10/3(日) 23:25 NHK BS2
http://www9.nhk.or.jp/anime/yakumo/

10/3(日) 25:00 テレ埼
http://www.geneonuniversal.jp/rondorobe/anime/hakuoki/

10/3(日) 25:35 テレビ東京
http://www.starchild.co.jp/special/arakawa_ub/

10/8(金) 25:55 TBS
http://www.togainu.tv/

10/9(土) 25:30 テレ玉
http://www.project-index.net/

贈与税のメモ

親族以外の第三者から1000万を贈与された場合。
(贈与額-基礎控除額110万円)×税率-控除額=贈与税額
(1000 - 110) x 0.4 - 125 = 231

以下、参考値
(1110 - 110) x 0.4 - 125 = 275
(710 - 110) x 0.3 - 65 = 115
(510 - 110) x 0.2 - 25 = 55
(410 - 110) x 0.15 - 10 = 35
(310 - 110) x 0.1 - 0 = 20

MacPort から入れた Scala 2.7 API Document の PATH

sbaz install scala-devel-docs すると下記に入る。
/opt/local/share/scala-2.7/doc/scala-devel-docs/api
形式が HTML なので、どうやってコマンドラインから参照できるようにしようか悩み中。
vim からリファレンス見たいなぁ・・・。

Scala 2.7 を MacPort から入れた場合の scala-tool-support の場所

/opt/local/var/macports/software/scala27/2.7.7_0/opt/local/share/scala-2.7/misc/scala-tool-support/

vim とかディレクトリがあるので、.vim 配下へごっそりコピー。